<?php

namespace App\Http\Controllers;

use App\Http\Traits\ResponseTrait;
use App\Models\Subscription;
use App\Models\SubscriptionPlan;
use App\Models\BillingHistory;
use App\Models\PaymentMethod;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class SubscriptionController extends Controller
{
    use ResponseTrait;

    /**
     * Get available subscription plans
     * GET /subscriptions/plans
     */
    public function plans(Request $request)
    {
        $plans = SubscriptionPlan::active()
            ->orderBy('sort_order')
            ->orderBy('price')
            ->get()
            ->map(function ($plan) {
                return [
                    'id' => (string) $plan->id,
                    'name' => $plan->name,
                    'description' => $plan->description,
                    'price' => (float) $plan->price,
                    'currency' => $plan->currency,
                    'interval' => $plan->interval,
                    'popular' => $plan->popular,
                    'features' => $plan->features ?? [],
                    'limits' => [
                        'job_postings' => $plan->job_postings_limit,
                        'candidate_searches' => $plan->candidate_searches_limit,
                        'team_members' => $plan->team_members_limit,
                    ],
                ];
            });

        return $this->successResponse($plans, 'Subscription plans retrieved successfully');
    }

    /**
     * Get user's current subscription
     * GET /subscriptions/current
     */
    public function current(Request $request)
    {
        $user = $request->user();
        
        $subscription = Subscription::where('user_id', $user->id)
            ->where('status', 'active')
            ->where(function ($query) {
                $query->whereNull('expires_at')
                    ->orWhere('expires_at', '>', now());
            })
            ->with('plan')
            ->first();

        if (!$subscription) {
            return $this->successResponse(null, 'No active subscription found');
        }

        // Calculate usage (this would need to be implemented based on your business logic)
        $usage = $this->calculateUsage($user, $subscription->plan);

        $data = [
            'id' => $subscription->id,
            'plan' => [
                'id' => (string) $subscription->plan->id,
                'name' => $subscription->plan->name,
                'price' => (float) $subscription->plan->price,
                'currency' => $subscription->plan->currency,
                'interval' => $subscription->plan->interval,
            ],
            'status' => $subscription->status,
            'started_at' => $subscription->started_at,
            'expires_at' => $subscription->expires_at,
            'next_billing_date' => $subscription->next_billing_date,
            'canceled_at' => $subscription->canceled_at,
            'usage' => $usage,
        ];

        return $this->successResponse($data, 'Current subscription retrieved successfully');
    }

    /**
     * Subscribe to a plan
     * POST /subscriptions/subscribe
     */
    public function subscribe(Request $request)
    {
        $request->validate([
            'plan_id' => 'required|exists:subscription_plans,id',
            'payment_method_id' => 'required|exists:payment_methods,id',
            'coupon_code' => 'nullable|string',
        ]);

        $user = $request->user();
        $plan = SubscriptionPlan::findOrFail($request->plan_id);
        $paymentMethod = PaymentMethod::findOrFail($request->payment_method_id);

        // Verify payment method belongs to user
        if ($paymentMethod->user_id !== $user->id) {
            return $this->errorResponse('Invalid payment method');
        }

        // Check if user already has an active subscription
        $existingSubscription = Subscription::where('user_id', $user->id)
            ->where('status', 'active')
            ->where(function ($query) {
                $query->whereNull('expires_at')
                    ->orWhere('expires_at', '>', now());
            })
            ->first();

        if ($existingSubscription) {
            return $this->errorResponse('You already have an active subscription');
        }

        DB::beginTransaction();
        try {
            // Calculate expiration date based on interval
            $startedAt = now();
            $expiresAt = null;
            $nextBillingDate = null;

            if ($plan->interval === 'monthly') {
                $expiresAt = $startedAt->copy()->addMonth();
                $nextBillingDate = $expiresAt;
            } elseif ($plan->interval === 'yearly') {
                $expiresAt = $startedAt->copy()->addYear();
                $nextBillingDate = $expiresAt;
            }
            // lifetime plans don't expire

            // Process payment (this would integrate with payment gateway)
            // For now, we'll just create the subscription
            $subscription = Subscription::create([
                'user_id' => $user->id,
                'plan_id' => $plan->id,
                'payment_method_id' => $paymentMethod->id,
                'status' => 'active',
                'started_at' => $startedAt,
                'expires_at' => $expiresAt,
                'next_billing_date' => $nextBillingDate,
                'payment_gateway' => $paymentMethod->provider,
            ]);

            // Create billing record
            $billing = BillingHistory::create([
                'user_id' => $user->id,
                'subscription_id' => $subscription->id,
                'payment_method_id' => $paymentMethod->id,
                'billing_date' => now(),
                'amount' => $plan->price,
                'currency' => $plan->currency,
                'status' => 'paid', // In real implementation, this would be set after payment confirmation
                'plan_name' => $plan->name,
                'billing_period' => now()->format('Y-m'),
                'payment_gateway' => $paymentMethod->provider,
            ]);

            DB::commit();

            return response()->json([
                'code' => 201,
                'error' => false,
                'status' => 'success',
                'message' => 'Subscription created successfully',
                'data' => [
                    'subscription' => [
                        'id' => $subscription->id,
                        'plan_id' => $subscription->plan_id,
                        'status' => $subscription->status,
                        'started_at' => $subscription->started_at,
                        'expires_at' => $subscription->expires_at,
                    ],
                    'payment' => [
                        'id' => $billing->id,
                        'status' => $billing->status,
                        'amount' => (float) $billing->amount,
                        'currency' => $billing->currency,
                    ],
                ],
            ], 201, [], JSON_NUMERIC_CHECK);

        } catch (\Exception $e) {
            DB::rollBack();
            return $this->errorResponse('Failed to create subscription: ' . $e->getMessage());
        }
    }

    /**
     * Cancel subscription
     * POST /subscriptions/cancel
     */
    public function cancel(Request $request)
    {
        $request->validate([
            'reason' => 'nullable|string|max:500',
            'cancel_immediately' => 'boolean',
        ]);

        $user = $request->user();
        
        $subscription = Subscription::where('user_id', $user->id)
            ->where('status', 'active')
            ->where(function ($query) {
                $query->whereNull('expires_at')
                    ->orWhere('expires_at', '>', now());
            })
            ->first();

        if (!$subscription) {
            return $this->errorResponse('No active subscription found');
        }

        $cancelImmediately = $request->boolean('cancel_immediately', false);
        $canceledAt = now();

        if ($cancelImmediately) {
            $subscription->update([
                'status' => 'canceled',
                'canceled_at' => $canceledAt,
                'expires_at' => $canceledAt,
                'cancel_reason' => $request->reason,
            ]);
            $cancelsAt = $canceledAt;
        } else {
            // Cancel at end of billing period
            $cancelsAt = $subscription->expires_at ?? $subscription->next_billing_date ?? now()->addMonth();
            $subscription->update([
                'status' => 'canceled',
                'canceled_at' => $canceledAt,
                'cancel_reason' => $request->reason,
            ]);
        }

        return $this->successResponse([
            'cancels_at' => $cancelsAt,
        ], 'Subscription cancelled successfully');
    }

    /**
     * Calculate usage for subscription limits
     */
    private function calculateUsage($user, $plan): array
    {
        // This is a placeholder - implement based on your actual usage tracking
        return [
            'job_postings' => [
                'used' => 0, // Count from job_posts table
                'limit' => $plan->job_postings_limit ?: 999999,
            ],
            'candidate_searches' => [
                'used' => 0, // Count from searches table
                'limit' => $plan->candidate_searches_limit ?: 999999,
            ],
            'team_members' => [
                'used' => 0, // Count from team members
                'limit' => $plan->team_members_limit ?: 999999,
            ],
        ];
    }
}
