<?php

namespace App\Http\Controllers\Api\V1\Payments;

use App\Http\Controllers\Controller;
use App\Services\Gateways\StripeGateway;
use App\Models\Invoice;
use App\Models\Subscription;
use App\Models\Transaction;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;

class CheckoutController extends Controller
{
    protected $stripeGateway;

    public function __construct(StripeGateway $stripeGateway)
    {
        $this->stripeGateway = $stripeGateway;
    }

    /**
     * Create a one-time payment checkout session.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function createOneTime(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'product_name' => 'required|string',
            'description' => 'nullable|string',
            'amount' => 'required|numeric|min:0.5',
            'currency' => 'sometimes|string|in:usd,eur,gbp',
            'success_url' => 'required|url',
            'cancel_url' => 'required|url',
        ]);

        $validated['reference_id'] = $request->user()->id;
        $validated['metadata'] = [
            'user_id' => $request->user()->id,
            'user_email' => $request->user()->email,
        ];

        try {
            $session = $this->stripeGateway->createOneTimeCheckout($validated);

            return response()->json([
                'checkout_url' => $session->url,
                'session_id' => $session->id,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'Failed to create checkout session.',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Create a subscription checkout session.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function createSubscription(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'price_id' => 'required|string',
            'success_url' => 'required|url',
            'cancel_url' => 'required|url',
        ]);

        $validated['reference_id'] = $request->user()->id;
        $validated['metadata'] = [
            'user_id' => $request->user()->id,
            'user_email' => $request->user()->email,
        ];

        try {
            $session = $this->stripeGateway->createSubscriptionCheckout($validated);

            return response()->json([
                'checkout_url' => $session->url,
                'session_id' => $session->id,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'Failed to create subscription checkout.',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get user's invoices.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getUserInvoices(Request $request): JsonResponse
    {
        $invoices = Invoice::where('user_id', $request->user()->id)
            ->with(['transactions', 'subscription'])
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        return response()->json($invoices);
    }

    /**
     * Get user's subscriptions.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getUserSubscriptions(Request $request): JsonResponse
    {
        $subscriptions = Subscription::where('user_id', $request->user()->id)
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        return response()->json($subscriptions);
    }
    
    /**
     * Get payment success details by session ID.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $sessionId
     * @return \Illuminate\Http\JsonResponse
     */
    public function getPaymentSuccess(Request $request, string $sessionId): JsonResponse
    {
        $user = $request->user();
        
        Log::info('Payment success endpoint called', [
            'session_id' => $sessionId,
            'user_id' => $user->id
        ]);
        
        // Check if this is an ImmigoPro installment payment
        $immigoProSubscription = \App\Models\ImmigoProSubscription::where('stripe_checkout_session_id', $sessionId)
            ->where('user_id', $user->id)
            ->first();
            
        if ($immigoProSubscription) {
            Log::info('Found ImmigoPro subscription', [
                'subscription_id' => $immigoProSubscription->id,
                'status' => $immigoProSubscription->status
            ]);
            
            return response()->json([
                'success' => true,
                'payment' => [
                    'subscription_id' => $immigoProSubscription->id,
                    'package_name' => $immigoProSubscription->package_name,
                    'amount' => $immigoProSubscription->upfront_amount,
                    'status' => $immigoProSubscription->status,
                    'activated_at' => $immigoProSubscription->created_at,
                    'expires_at' => null,
                    'session_id' => $sessionId,
                    'payment_plan' => $immigoProSubscription->payment_plan,
                    'monthly_amount' => $immigoProSubscription->monthly_amount,
                    'installments' => $immigoProSubscription->installments,
                    'paid_installments' => $immigoProSubscription->paid_installments,
                    'next_charge_date' => $immigoProSubscription->next_charge_date,
                    'invoice' => null,
                ]
            ]);
        }
        
        // Find regular subscription by session ID and user
        $subscription = Subscription::where('stripe_session_id', $sessionId)
            ->where('user_id', $user->id)
            ->with('invoices.transactions')
            ->first();
            
        if (!$subscription) {
            Log::warning('Subscription not found for payment success', [
                'session_id' => $sessionId,
                'user_id' => $user->id
            ]);
            return response()->json([
                'success' => false,
                'message' => 'Payment not found'
            ], 404);
        }
        
        // Activate subscription if still pending
        if ($subscription->status === 'pending') {
            Log::info('Activating pending subscription', [
                'subscription_id' => $subscription->id
            ]);
            
            try {
                // Retrieve Stripe session to verify payment
                $stripeGateway = app(\App\Services\Gateways\StripeGateway::class);
                $session = $stripeGateway->retrieveCheckoutSession($sessionId);
                
                if ($session && $session->payment_status === 'paid') {
                    // Calculate subscription period
                    $currentPeriodStart = now();
                    $interval = $subscription->interval ?? 'month';
                    $currentPeriodEnd = match($interval) {
                        'month' => now()->addMonth(),
                        'year' => now()->addYear(),
                        'week' => now()->addWeek(),
                        default => now()->addMonth(),
                    };
                    
                    // Update subscription
                    $subscription->update([
                        'status' => 'active',
                        'activated_at' => now(),
                        'current_period_start' => $currentPeriodStart,
                        'current_period_end' => $currentPeriodEnd,
                        'expires_at' => $currentPeriodEnd,
                        'stripe_customer_id' => $session->customer,
                        'stripe_subscription_id' => $session->subscription,
                        'gateway_subscription_id' => $session->subscription,
                    ]);
                    
                    Log::info('Subscription activated', [
                        'subscription_id' => $subscription->id,
                        'status' => 'active'
                    ]);
                    
                    // Create invoice if not exists
                    $invoice = $subscription->invoices()->latest()->first();
                    if (!$invoice) {
                        Log::info('Creating invoice for subscription');
                        $invoice = Invoice::create([
                            'user_id' => $subscription->user_id,
                            'subscription_id' => $subscription->id,
                            'invoice_number' => 'INV-' . strtoupper(uniqid()),
                            'amount' => $subscription->amount,
                            'currency' => 'CAD',
                            'status' => 'paid',
                            'paid_at' => now(),
                        ]);
                        
                        // Create transaction
                        Transaction::create([
                            'invoice_id' => $invoice->id,
                            'subscription_id' => $subscription->id,
                            'user_id' => $subscription->user_id,
                            'gateway_provider' => 'stripe',
                            'gateway_transaction_id' => $session->payment_intent ?? $session->id,
                            'amount' => $subscription->amount,
                            'currency' => 'CAD',
                            'status' => 'completed',
                            'processed_at' => now(),
                        ]);
                        
                        Log::info('Invoice and transaction created', [
                            'invoice_id' => $invoice->id
                        ]);
                    }
                } else {
                    Log::warning('Payment not completed', [
                        'session_id' => $sessionId,
                        'payment_status' => $session->payment_status ?? 'unknown'
                    ]);
                }
            } catch (\Exception $e) {
                Log::error('Error activating subscription', [
                    'error' => $e->getMessage(),
                    'subscription_id' => $subscription->id
                ]);
            }
            
            // Reload subscription with invoice
            $subscription = $subscription->fresh(['invoices.transactions']);
        }
        
        // Get the invoice for this subscription
        $invoice = $subscription->invoices()->latest()->first();
        
        return response()->json([
            'success' => true,
            'payment' => [
                'subscription_id' => $subscription->id,
                'package_name' => $subscription->package_name,
                'amount' => $subscription->amount,
                'status' => $subscription->status,
                'activated_at' => $subscription->activated_at,
                'expires_at' => $subscription->expires_at,
                'session_id' => $subscription->stripe_session_id,
                'invoice' => $invoice ? [
                    'invoice_number' => $invoice->invoice_number,
                    'amount' => $invoice->amount,
                    'currency' => $invoice->currency,
                    'paid_at' => $invoice->paid_at,
                    'transaction_id' => $invoice->transactions->first()?->gateway_transaction_id,
                ] : null,
            ],
        ]);
    }

    /**
     * Get all subscriptions for admin dashboard.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getAllSubscriptions(Request $request): JsonResponse
    {
        $subscriptions = Subscription::with('user:id,name,email')
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json([
            'success' => true,
            'data' => $subscriptions,
        ]);
    }

    /**
     * Get dashboard statistics.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getDashboardStats(Request $request): JsonResponse
    {
        $subscriptions = Subscription::all();
        
        $stats = [
            'total_revenue' => $subscriptions
                ->whereIn('status', ['active', 'cancelled', 'expired'])
                ->sum('amount'),
            'total_transactions' => $subscriptions->count(),
            'pending_payments' => $subscriptions->where('status', 'pending')->count(),
            'successful_payments' => $subscriptions->where('status', 'active')->count(),
            'active_users' => $subscriptions->pluck('user_id')->unique()->count(),
            'active_subscriptions' => $subscriptions->where('status', 'active')->count(),
            'monthly_recurring_revenue' => $subscriptions
                ->where('status', 'active')
                ->where('interval', 'month')
                ->sum('amount'),
        ];

        return response()->json($stats);
    }

    /**
     * Get all invoices for admin.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getAllInvoices(Request $request): JsonResponse
    {
        $invoices = Invoice::with([
                'user:id,name,email',
                'subscription:id,package_name'
            ])
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json([
            'success' => true,
            'data' => $invoices,
        ]);
    }

    /**
     * Get all transactions for admin.
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getAllTransactions(Request $request): JsonResponse
    {
        $transactions = Transaction::with([
                'user:id,name,email',
                'invoice:id,invoice_number',
                'subscription:id,package_name'
            ])
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json([
            'success' => true,
            'data' => $transactions,
        ]);
    }

    /**
     * Create a checkout session for quotation payment
     */
    public function createQuotationSession(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'quotation_id' => 'required|exists:quotations,id',
            'subtotal' => 'required|numeric|min:0.50',
            'tax_amount' => 'required|numeric|min:0',
            'total_amount' => 'required|numeric|min:0.50',
            'success_url' => 'required|url',
            'cancel_url' => 'required|url',
        ]);

        try {
            // Get quotation details
            $quotation = \App\Models\Quotation::findOrFail($validated['quotation_id']);
            
            // Verify user owns this quotation
            if ($quotation->user_id !== $request->user()->id) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthorized access to quotation',
                ], 403);
            }

            // Verify quotation is accepted or pending (pending means awaiting payment)
            if (!in_array($quotation->status, ['accepted', 'pending'])) {
                return response()->json([
                    'success' => false,
                    'message' => 'Quotation must be in accepted or pending status for payment',
                ], 400);
            }

            // Create Stripe checkout session
            $session = $this->stripeGateway->createOneTimeCheckout([
                'product_name' => 'Quotation #' . $quotation->id,
                'description' => 'Payment for quotation',
                'amount' => $validated['total_amount'],
                'currency' => $quotation->currency ?? 'cad',
                'success_url' => $validated['success_url'],
                'cancel_url' => $validated['cancel_url'],
                'reference_id' => $quotation->id,
                'metadata' => [
                    'quotation_id' => $quotation->id,
                    'user_id' => $request->user()->id,
                    'user_email' => $request->user()->email,
                    'subtotal' => $validated['subtotal'],
                    'tax_amount' => $validated['tax_amount'],
                    'payment_type' => 'quotation',
                ],
            ]);

            // Store session ID in quotation for tracking
            $quotation->update([
                'stripe_session_id' => $session->id,
            ]);

            return response()->json([
                'success' => true,
                'data' => [
                    'url' => $session->url,
                    'session_id' => $session->id,
                ],
            ]);
        } catch (\Exception $e) {
            Log::error('Error creating quotation checkout session', [
                'error' => $e->getMessage(),
                'quotation_id' => $validated['quotation_id'],
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Failed to create checkout session',
                'error' => $e->getMessage(),
            ], 500);
        }
    }
}
