package com.saas.subscription.config;

import com.saas.subscription.entity.SubscriptionPlan;
import com.saas.subscription.repository.SubscriptionPlanRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@RequiredArgsConstructor
@Slf4j
public class SubscriptionSeeder implements CommandLineRunner {

    private final SubscriptionPlanRepository planRepository;
    private final com.saas.subscription.service.StripeService stripeService;

    @Override
    public void run(String... args) throws Exception {
        log.info("Checking subscription plans configuration...");
        List<SubscriptionPlan> plans = planRepository.findAll();

        if (plans.isEmpty()) {
            log.info("No plans found. Creating default FREE plan...");
            createDefaultFreePlan();
            plans = planRepository.findAll(); // Reload after creation
        }

        boolean updated = false;
        for (SubscriptionPlan plan : plans) {
            try {
                // RESET invalid/dummy IDs so they can be regenerated
                if ("price_test".equalsIgnoreCase(plan.getStripePriceId())
                        || "price_placeholder".equalsIgnoreCase(plan.getStripePriceId())
                        || "price_standard".equalsIgnoreCase(plan.getStripePriceId())) { // catch previous attempts
                    log.warn("Found invalid/dummy Stripe Price ID '{}' for plan '{}'. Resetting to generate real one.",
                            plan.getStripePriceId(), plan.getName());
                    plan.setStripePriceId(null);
                    // plan.setStripeProductId(null); // Optional: reset product too if needed, but
                    // price is the main issue
                }

                // 1. Ensure Product exists in Stripe
                if (plan.getStripeProductId() == null || plan.getStripeProductId().isEmpty()) {
                    log.info("Creating Stripe Product for plan: {}", plan.getName());
                    String productId = stripeService.createProduct(plan.getName(), plan.getDescription());
                    plan.setStripeProductId(productId);
                    updated = true;
                }

                // 2. Ensure Price exists in Stripe
                if (plan.getStripePriceId() == null || plan.getStripePriceId().isEmpty()) {
                    log.info("Creating Stripe Price for plan: {}", plan.getName());
                    // Convert BigDecimal price to cents (long)
                    long amountCents = plan.getPricePerMonth().multiply(java.math.BigDecimal.valueOf(100)).longValue();
                    // Prevent creating 0-value prices for FREE plans if Stripe complains (Stripe
                    // allows 0 for subscriptions but sometimes simpler not to)
                    // Actually, for free plans, we often don't need a Stripe Price ID for checkout,
                    // but let's see.
                    // If amount is 0, we might skip or create a 0-amount price. Stripe supports
                    // free subscriptions.

                    String priceId = stripeService.createPrice(plan.getStripeProductId(), amountCents,
                            plan.getCurrency());
                    plan.setStripePriceId(priceId);
                    updated = true;
                }

                if (updated) {
                    planRepository.save(plan);
                }

            } catch (Exception e) {
                log.error("Failed to seed Stripe data for plan '{}'. Check API Key.", plan.getName(), e);
                // Continue to next plan
            }
        }

        if (updated) {
            log.info("Subscription plans synchronized with Stripe.");
        } else {
            log.info("All subscription plans already synchronized with Stripe.");
        }
    }

    /**
     * Create default FREE plan with logical limitations
     * 
     * Plan features:
     * - $0/month
     * - 5 users max
     * - 100 included minutes (soft limit)
     * - $0.08/min overage
     * - 10 call transfers max
     * - 1 AI agent
     * - 1GB storage
     * - 30 days call history
     * - Basic support
     */
    private void createDefaultFreePlan() {
        try {
            log.info("🆓 Creating default FREE subscription plan...");

            SubscriptionPlan freePlan = SubscriptionPlan.builder()
                    .name("FREE")
                    .description("Free tier with basic features - perfect for testing and small clinics")
                    .pricePerMonth(java.math.BigDecimal.ZERO) // $0/month
                    .monthlyPrice(java.math.BigDecimal.ZERO)  // Sync field
                    .pricePerYear(java.math.BigDecimal.ZERO)  // $0/year
                    .currency("USD")
                    
                    // Communication limits
                    .includedMinutes(100)                               // 100 minutes included
                    .overagePricePerMinute(new java.math.BigDecimal("0.08"))  // $0.08/min overage
                    .maxCallTransfers(10)                               // 10 transfers max
                    
                    // Capacity limits
                    .maxUsers(5)                                        // 5 users maximum
                    .maxActiveAiAgents(1)                               // 1 AI agent
                    .maxStorageGb(1)                                    // 1GB storage
                    
                    // Data retention
                    .callHistoryRetentionDays(30)                       // 30 days retention
                    .recordingRetentionMonths(1)                        // 1 month recordings
                    .maxRecordingRetrievalsPerMonth(100)                // 100 retrievals/month
                    
                    // Features (all disabled for FREE tier)
                    .advancedAnalytics(false)
                    .featuresEmailSupport(true)                         // Basic email support
                    .featuresPrioritySupport(false)
                    .featuresApiAccess(false)
                    .featuresCustomDomain(false)
                    .featuresSso(false)
                    .featuresAuditLogs(false)
                    .supportLevel("STANDARD")
                    .active(true)
                    .build();

            // Save to database
            freePlan = planRepository.save(freePlan);
            log.info("✅ FREE plan created with ID: {}", freePlan.getId());

            // Create Stripe Product & Price
            String productId = stripeService.createProduct(freePlan.getName(), freePlan.getDescription());
            freePlan.setStripeProductId(productId);
            log.info("✅ Stripe Product created: {}", productId);

            // Create Stripe Price (0 cents - free subscription)
            String priceId = stripeService.createPrice(productId, 0L, "USD");
            freePlan.setStripePriceId(priceId);
            log.info("✅ Stripe Price created: {}", priceId);

            // Update with Stripe IDs
            planRepository.save(freePlan);
            log.info("🎉 DEFAULT FREE PLAN FULLY CONFIGURED AND SYNCED WITH STRIPE");

        } catch (Exception e) {
            log.error("❌ Failed to create default FREE plan. Manual creation required.", e);
            // Don't throw - allow app to start even if Stripe sync fails
        }
    }
}
