<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Models\Plan;
use Illuminate\Console\Command;
use Stripe\Price;
use Stripe\Product;
use Stripe\Stripe;

class SyncStripePrices extends Command
{
    protected $signature = 'stripe:sync-prices {--force : Force recreate all prices}';

    protected $description = 'Sync plans with Stripe prices';

    public function handle(): int
    {
        Stripe::setApiKey(config('cashier.secret'));

        $plans = Plan::where('status', 'active')->with('prices')->get();

        $this->info("Syncing {$plans->count()} plans with Stripe...");

        $progressBar = $this->output->createProgressBar($plans->count());
        $progressBar->start();

        foreach ($plans as $plan) {
            try {
                $product = $plan->stripe_product_id && ! $this->option('force')
                    ? Product::retrieve($plan->stripe_product_id)
                    : Product::create([
                        'name' => $plan->name,
                        'description' => "EZSCALE {$plan->service_type} - {$plan->name}",
                        'metadata' => ['plan_id' => $plan->id, 'plan_slug' => $plan->slug],
                    ]);

                $plan->update(['stripe_product_id' => $product->id]);

                foreach ($plan->prices as $planPrice) {
                    if ($planPrice->stripe_price_id && ! $this->option('force')) {
                        continue;
                    }

                    $interval = match ($planPrice->billing_cycle) {
                        'monthly' => 'month',
                        'quarterly' => 'month',
                        'semi_annual' => 'month',
                        'annual' => 'year',
                        default => 'month',
                    };

                    $intervalCount = match ($planPrice->billing_cycle) {
                        'monthly' => 1,
                        'quarterly' => 3,
                        'semi_annual' => 6,
                        'annual' => 1,
                        default => 1,
                    };

                    $price = Price::create([
                        'product' => $product->id,
                        'currency' => 'usd',
                        'unit_amount' => (int) round($planPrice->price * 100),
                        'recurring' => [
                            'interval' => $interval,
                            'interval_count' => $intervalCount,
                        ],
                        'metadata' => [
                            'plan_id' => $plan->id,
                            'plan_slug' => $plan->slug,
                            'billing_cycle' => $planPrice->billing_cycle,
                        ],
                    ]);

                    $planPrice->update(['stripe_price_id' => $price->id]);
                }

                $monthlyPrice = $plan->priceForCycle('monthly');
                if ($monthlyPrice?->stripe_price_id) {
                    $plan->update(['stripe_price_id' => $monthlyPrice->stripe_price_id]);
                }

                $progressBar->advance();
            } catch (\Exception $e) {
                $this->newLine();
                $this->error("Failed to sync {$plan->name}: {$e->getMessage()}");
                $progressBar->advance();
            }
        }

        $progressBar->finish();
        $this->newLine(2);
        $this->info('Stripe prices synced successfully!');

        return self::SUCCESS;
    }
}
