<?php

namespace App\Http\Controllers\Webhook;

use App\Http\Controllers\Controller;
use App\Models\Transaction;
use App\Models\Subscription;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Stripe\Webhook;
use Stripe\Exception\SignatureVerificationException;
use Exception;

class StripeWebhookController extends Controller
{
    /**
     * Handle Stripe webhooks
     */
    public function handleWebhook(Request $request)
    {
        $payload = $request->getContent();
        $sigHeader = $request->header('Stripe-Signature');
        $webhookSecret = config('services.stripe.webhook_secret');

        try {
            $event = Webhook::constructEvent(
                $payload,
                $sigHeader,
                $webhookSecret
            );
        } catch (SignatureVerificationException $e) {
            Log::error('Stripe webhook signature verification failed: ' . $e->getMessage());
            return response()->json(['error' => 'Invalid signature'], 400);
        } catch (Exception $e) {
            Log::error('Stripe webhook error: ' . $e->getMessage());
            return response()->json(['error' => 'Webhook error'], 400);
        }

        // Handle the event
        switch ($event->type) {
            case 'payment_intent.succeeded':
                $this->handlePaymentIntentSucceeded($event->data->object);
                break;

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

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

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

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

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

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

            default:
                Log::info('Unhandled Stripe webhook event: ' . $event->type);
        }

        return response()->json(['status' => 'success']);
    }

    /**
     * Handle successful payment intent
     */
    protected function handlePaymentIntentSucceeded($paymentIntent)
    {
        try {
            $transaction = Transaction::where('gateway_payment_id', $paymentIntent->id)->first();

            if ($transaction) {
                $transaction->update([
                    'status' => 'success',
                    'payment_status' => 'paid',
                    'paid_at' => now(),
                    'captured_at' => now(),
                    'gateway_response' => (array) $paymentIntent,
                ]);

                // If this is a plan purchase, update user's plan
                if ($transaction->entity_type === 'subscription' && $transaction->entity_id) {
                    $user = User::find($transaction->user_id);
                    if ($user) {
                        $user->update([
                            'plan_id' => $transaction->entity_id,
                            'plan_expires_at' => now()->addMonth(),
                        ]);
                    }
                }

                Log::info("Payment intent succeeded: {$paymentIntent->id}");
            }
        } catch (Exception $e) {
            Log::error("Error handling payment intent succeeded: " . $e->getMessage());
        }
    }

    /**
     * Handle failed payment intent
     */
    protected function handlePaymentIntentFailed($paymentIntent)
    {
        try {
            $transaction = Transaction::where('gateway_payment_id', $paymentIntent->id)->first();

            if ($transaction) {
                $transaction->update([
                    'status' => 'failed',
                    'payment_status' => 'failed',
                    'gateway_response' => (array) $paymentIntent,
                ]);

                Log::warning("Payment intent failed: {$paymentIntent->id}");
            }
        } catch (Exception $e) {
            Log::error("Error handling payment intent failed: " . $e->getMessage());
        }
    }

    /**
     * Handle subscription created
     */
    protected function handleSubscriptionCreated($stripeSubscription)
    {
        try {
            $subscription = Subscription::where('gateway_subscription_id', $stripeSubscription->id)->first();

            if ($subscription) {
                $subscription->update([
                    'status' => $stripeSubscription->status,
                    'payment_status' => $stripeSubscription->status === 'active' ? 'paid' : 'pending',
                    'start_date' => now(),
                ]);

                Log::info("Subscription created: {$stripeSubscription->id}");
            }
        } catch (Exception $e) {
            Log::error("Error handling subscription created: " . $e->getMessage());
        }
    }

    /**
     * Handle subscription updated
     */
    protected function handleSubscriptionUpdated($stripeSubscription)
    {
        try {
            $subscription = Subscription::where('gateway_subscription_id', $stripeSubscription->id)->first();

            if ($subscription) {
                $subscription->update([
                    'status' => $stripeSubscription->status,
                    'payment_status' => $stripeSubscription->status === 'active' ? 'paid' : 'pending',
                ]);

                // Update user's plan expiration if subscription is active
                if ($stripeSubscription->status === 'active') {
                    $user = User::find($subscription->user_id);
                    if ($user) {
                        $user->update([
                            'plan_expires_at' => now()->addMonth(),
                        ]);
                    }
                }

                Log::info("Subscription updated: {$stripeSubscription->id}");
            }
        } catch (Exception $e) {
            Log::error("Error handling subscription updated: " . $e->getMessage());
        }
    }

    /**
     * Handle subscription deleted
     */
    protected function handleSubscriptionDeleted($stripeSubscription)
    {
        try {
            $subscription = Subscription::where('gateway_subscription_id', $stripeSubscription->id)->first();

            if ($subscription) {
                $subscription->update([
                    'status' => 'cancelled',
                    'cancelled_at' => now(),
                ]);

                // Revert user to free plan
                $user = User::find($subscription->user_id);
                if ($user) {
                    $freePlan = \App\Models\UserPlan::where('slug', 'standard')->first();
                    if ($freePlan) {
                        $user->update([
                            'plan_id' => $freePlan->id,
                            'plan_expires_at' => null,
                        ]);
                    }
                }

                Log::info("Subscription deleted: {$stripeSubscription->id}");
            }
        } catch (Exception $e) {
            Log::error("Error handling subscription deleted: " . $e->getMessage());
        }
    }

    /**
     * Handle successful invoice payment
     */
    protected function handleInvoicePaymentSucceeded($invoice)
    {
        try {
            if ($invoice->subscription) {
                $subscription = Subscription::where('gateway_subscription_id', $invoice->subscription)->first();

                if ($subscription) {
                    $subscription->update([
                        'payment_status' => 'paid',
                        'next_billing_date' => now()->addMonth(),
                        'billing_cycle_count' => $subscription->billing_cycle_count + 1,
                    ]);

                    // Create transaction record for the payment
                    Transaction::create([
                        'transaction_id' => 'txn_' . uniqid(),
                        'order_id' => 'ord_' . uniqid(),
                        'gateway_payment_id' => $invoice->payment_intent,
                        'user_id' => $subscription->user_id,
                        'entity_type' => 'subscription',
                        'entity_id' => $subscription->plan_id,
                        'gateway_slug' => 'stripe',
                        'amount' => $invoice->amount_paid / 100,
                        'currency' => strtoupper($invoice->currency),
                        'status' => 'success',
                        'payment_status' => 'paid',
                        'paid_at' => now(),
                        'captured_at' => now(),
                    ]);

                    Log::info("Invoice payment succeeded: {$invoice->id}");
                }
            }
        } catch (Exception $e) {
            Log::error("Error handling invoice payment succeeded: " . $e->getMessage());
        }
    }

    /**
     * Handle failed invoice payment
     */
    protected function handleInvoicePaymentFailed($invoice)
    {
        try {
            if ($invoice->subscription) {
                $subscription = Subscription::where('gateway_subscription_id', $invoice->subscription)->first();

                if ($subscription) {
                    $subscription->update([
                        'payment_status' => 'failed',
                    ]);

                    Log::warning("Invoice payment failed: {$invoice->id}");
                }
            }
        } catch (Exception $e) {
            Log::error("Error handling invoice payment failed: " . $e->getMessage());
        }
    }
}
