<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Stripe\StripeClient;

class StripeController extends Controller
{
    private StripeClient $stripe;

    public function __construct()
    {
        $this->stripe = new StripeClient(config('services.stripe.secret'));
    }

    /**
     * Create a Stripe Setup Intent for saving a payment method.
     */
    public function createSetupIntent(Request $request)
    {
        $user = $request->user();

        // Create or retrieve Stripe customer
        if (!$user->stripe_customer_id) {
            $customer = $this->stripe->customers->create([
                'email' => $user->email,
                'name' => $user->name,
                'metadata' => ['user_id' => $user->id],
            ]);
            $user->update(['stripe_customer_id' => $customer->id]);
        }

        $setupIntent = $this->stripe->setupIntents->create([
            'customer' => $user->stripe_customer_id,
            'payment_method_types' => ['card'],
        ]);

        return response()->json([
            'client_secret' => $setupIntent->client_secret,
        ]);
    }

    /**
     * List saved payment methods.
     */
    public function paymentMethods(Request $request)
    {
        $user = $request->user();

        if (!$user->stripe_customer_id) {
            return response()->json(['payment_methods' => []]);
        }

        $methods = $this->stripe->paymentMethods->all([
            'customer' => $user->stripe_customer_id,
            'type' => 'card',
        ]);

        return response()->json([
            'payment_methods' => collect($methods->data)->map(fn ($pm) => [
                'id' => $pm->id,
                'brand' => $pm->card->brand,
                'last4' => $pm->card->last4,
                'exp_month' => $pm->card->exp_month,
                'exp_year' => $pm->card->exp_year,
            ]),
        ]);
    }

    /**
     * Handle Stripe webhooks.
     */
    public function webhook(Request $request)
    {
        $payload = $request->getContent();
        $sigHeader = $request->header('Stripe-Signature');
        $endpointSecret = config('services.stripe.webhook_secret');

        try {
            $event = \Stripe\Webhook::constructEvent($payload, $sigHeader, $endpointSecret);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Invalid signature.'], 400);
        }

        switch ($event->type) {
            case 'invoice.payment_succeeded':
                $this->handlePaymentSucceeded($event->data->object);
                break;

            case 'invoice.payment_failed':
                $this->handlePaymentFailed($event->data->object);
                break;

            case 'customer.subscription.updated':
                $this->handleSubscriptionUpdated($event->data->object);
                break;

            case 'customer.subscription.deleted':
                $this->handleSubscriptionDeleted($event->data->object);
                break;
        }

        return response()->json(['received' => true]);
    }

    private function handlePaymentSucceeded($invoice): void
    {
        $subscription = \App\Models\Subscription::where('stripe_subscription_id', $invoice->subscription)->first();
        if (!$subscription) return;

        \App\Models\Payment::create([
            'user_id' => $subscription->user_id,
            'subscription_id' => $subscription->id,
            'stripe_payment_id' => $invoice->payment_intent,
            'stripe_invoice_id' => $invoice->id,
            'amount' => $invoice->amount_paid / 100,
            'currency' => $invoice->currency,
            'status' => 'succeeded',
            'paid_at' => now(),
        ]);
    }

    private function handlePaymentFailed($invoice): void
    {
        $subscription = \App\Models\Subscription::where('stripe_subscription_id', $invoice->subscription)->first();
        if (!$subscription) return;

        $subscription->update(['status' => 'past_due']);

        \App\Models\Payment::create([
            'user_id' => $subscription->user_id,
            'subscription_id' => $subscription->id,
            'stripe_payment_id' => $invoice->payment_intent,
            'stripe_invoice_id' => $invoice->id,
            'amount' => $invoice->amount_due / 100,
            'currency' => $invoice->currency,
            'status' => 'failed',
        ]);
    }

    private function handleSubscriptionUpdated($stripeSubscription): void
    {
        $subscription = \App\Models\Subscription::where('stripe_subscription_id', $stripeSubscription->id)->first();
        if (!$subscription) return;

        $subscription->update([
            'current_period_start' => \Carbon\Carbon::createFromTimestamp($stripeSubscription->current_period_start),
            'current_period_end' => \Carbon\Carbon::createFromTimestamp($stripeSubscription->current_period_end),
        ]);
    }

    private function handleSubscriptionDeleted($stripeSubscription): void
    {
        $subscription = \App\Models\Subscription::where('stripe_subscription_id', $stripeSubscription->id)->first();
        if (!$subscription) return;

        $subscription->cancel();
    }
}
