<?php

namespace App\Providers;

use App\Models\SubscriptionPlan;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;

class SubscriptionPlanServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        //
    }

    public function boot(): void
    {
        if (!$this->migrationsHaveRun()) {
            return;
        }

        $this->updatePlans();
    }

    protected function migrationsHaveRun(): bool
    {
        return Schema::hasTable('cache') && Schema::hasTable('subscription_plans');
    }

    protected function updatePlans(): void
    {
        if (empty(config('saashovel.STRIPE_KEY'))) {
            return;
        }

        Cache::remember("subscription_plans_stripe", now()->addDay(), function () {
            $plans = $this->fetchPlansFromStripe();
            $this->updatePlansInDatabase($plans);
            return $plans;
        });
    }

    protected function fetchPlansFromStripe()
    {
        try {
            \Stripe\Stripe::setApiKey(config('saashovel.STRIPE_SECRET'));

            $products = \Stripe\Product::all(['active' => true]);

            $plans = collect($products->data)
                ->filter(function ($product) {
                    return in_array($product->name, [
                        config('saashovel.FIRST_TIER_SUBSCRIPTION_NAME'),
                        config('saashovel.SECOND_TIER_SUBSCRIPTION_NAME'),
                        config('saashovel.THIRD_TIER_SUBSCRIPTION_NAME')
                    ]);
                })
                ->flatMap(function ($product) {
                    $prices = \Stripe\Price::all(['product' => $product->id, 'active' => true]);

                    return collect($prices->data)->map(function ($price) use ($product) {
                        return [
                            'plan_id' => $price->id,
                            'name' => $product->name,
                            'currency' => strtoupper($price->currency) ?? config('saashovel.DEFAULT_CURRENCY'),
                            'price' => $price->unit_amount,
                            'price_formatted' => number_format($price->unit_amount / 100, 2) . ' ' . strtoupper($price->currency),
                        ];
                    });
                })
                ->sortBy('price')
                ->values();

            $tiers = ['first-tier', 'second-tier', 'third-tier'];
            return $plans->map(function ($plan, $index) use ($tiers) {
                $plan['tier'] = $tiers[$index];
                return $plan;
            });

        } catch (\Stripe\Exception\ApiErrorException $e) {
            return ['error' => $e->getMessage()];
        } catch (\Exception $e) {
            return ['error' => 'An unexpected error occurred: ' . $e->getMessage()];
        }
    }

    protected function updatePlansInDatabase($plans): void
    {
        $plans->each(function ($plan) {
            SubscriptionPlan::updateOrCreate(
                ['plan_id' => $plan['plan_id']],
                array_merge($plan, ['billing_provider' => 'stripe'])
            );
        });
    }
}
