<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Stripe\Stripe;
use Stripe\Checkout\Session;
use Stripe\Subscription;
use Stripe\Webhook;
use App\Models\Plan;
use App\Models\Subscription as SubscriptionDB;
use Illuminate\Support\Facades\Validator;

class StripeSubscriptionController extends Controller
{
    public function createCheckoutSession(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'plan_id'   => 'required|exists:plans,id'
        ]);

        // return response()->json([
        //             'success'       => false,
        //             'message'       => 'Plan not available now',
        //             'check'         => $request->ammount
        //         ],200);

        $user = $request->user();
        if (!$user) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        $checkSub   = DB::table('subscriptions')->where(['user_id'=>$user->id,'status'=>'active','is_trial'=>0])->orderBy('id','DESC')->first();
        if($checkSub!=null)
        {
            return response()->json([
                'success'       => false,
                'message'       => "You already have an active subscription. You can change it from your subscription settings.",
            ],200);
        }

        Stripe::setApiKey(config('services.stripe.secret'));

        try {
            // $session = Session::create([
            //     'payment_method_types' => ['card'],
            //     'customer_email' => $user->email,
            //     'line_items' => [
            //         [
            //             'price' => $request->priceId,
            //             'quantity' => 1,
            //         ],
            //     ],
            //     'mode' => 'subscription',
            //     'success_url' => env('CLIENT_URL') . '/success',
            //     'cancel_url' => env('CLIENT_URL') . '/cancel',
            //     'metadata' => ['user_id' => $user->id, 'priceId' => $request->priceId]
            // ]);

            $plan   = Plan::find($request->plan_id);

            if($plan==null)
            {
                return response()->json([
                    'success'       => false,
                    'message'       => 'Plan not available now',
                ],200);
            }

            // $customer = \Stripe\Customer::create([
            //     'name' => 'Ravi Kumar',
            //     'email' => "$user->email",
            //     'address' => [
            //         'line1' => '123 MG Road',
            //         'city' => 'Mumbai',
            //         'state' => 'MH',
            //         'postal_code' => '400001',
            //         'country' => 'IN',
            //     ],
            // ]);


            $amount = (integer)$request->ammount*100; //$plan->price*100;

            $session= Session::create([
                'payment_method_types' => ['card'],
                'customer_email'    => $user->email,
                // 'customer'          => $customer->id, 
                'line_items' => [
                    [
                        'price_data'=> [
                            'currency'      => $request->currency,
                            'product_data'  => [
                                'name'      => "Plan of $plan->name",
                                'images'    => [asset('/img/Logo2.png')],
                            ],
                            'unit_amount'   => $amount,
                            'recurring'     => [
                                'interval'  => "$plan->interval"
                            ],
                        ],
                        'quantity'  => 1,
                    ],
                ],
                // 'billing_address_collection' => 'required',

                // Optional: collect shipping address too
                // 'shipping_address_collection' => [
                //     'allowed_countries' => ['IN'], // or ['IN', 'US', 'CA'] etc.
                // ],
                // 'customer_update' => [
                //     'shipping' => 'auto',
                // ],
                'mode'          => 'subscription',
                'success_url'   => env('CLIENT_URL') . '/tran/success?session_id={CHECKOUT_SESSION_ID}',
                'cancel_url'    => env('CLIENT_URL') . '/tran/cancel?session_id={CHECKOUT_SESSION_ID}',
                'automatic_tax' => ['enabled' => true],
                'metadata' => ['user_id' => $user->id, 'plan_id'=>$plan->id]
            ]);

            return response()->json([
                'success'       => true,
                'message'       => 'Session Created Successfully',
                'session_id'    => $session->id
            ],200);

        } catch (\Exception $e) {
            return response()->json([
                'success'       => false,
                'message'       => $e->getMessage(),
            ],200);
            // return response()->json(['error' => $e->getMessage().''.$e->getLine()], 500);
        }
    }

    public function handleWebhook(Request $request)
    {
        
        Stripe::setApiKey(config('services.stripe.secret'));

        $payload = $request->getContent();
        // $payload = json_encode($payload);
        // $sig_header = 'whsec_KjC6LENIupTxIlouB0rtUPUT4d9w2yen'; // LIVE
        // $sig_header = 'whsec_eZSERFUSJ9EAbk1ppdaXfnOHFMbbWGlp'; // Testing  $request->header('Stripe-Signature'); 
        // $endpoint_secret = 'whsec_eZSERFUSJ9EAbk1ppdaXfnOHFMbbWGlp'; //env('STRIPE_WEBHOOK_SECRET');
        // \Log::info('Stripe Webhook Print: ' . $payload);
        // \Log::error('end: ' . $payload->id);
        die;
        try {
            // $event = Webhook::constructEvent($payload, $sig_header, $endpoint_secret);
            $event = $payload;
        
            if ($event->type === 'checkout.session.completed') {
                $session = $event->data->object;
                $user = \App\Models\User::find($session->metadata->user_id);

                if ($user) {
                    DB::table('subscriptions')->insert([
                        'user_id' => $user->id,
                        'stripe_subscription_id' => $session->subscription,
                        'plan_id' => $session->metadata->plan_id,
                        'status' => 'active',
                        'created_at' => now(),
                        'updated_at' => now(),
                    ]);
                }
            } elseif ($event->type === 'customer.subscription.updated') {
                \Log::error('Stripe Webhook Update: ' . $payload);
                $subscription = $event->data->object;
                DB::table('subscriptions')
                    ->where('stripe_subscription_id', $subscription->id)
                    ->update(['status' => $subscription->status]);
            } elseif ($event->type === 'customer.subscription.deleted') {
                $subscription = $event->data->object;
                DB::table('subscriptions')
                    ->where('stripe_subscription_id', $subscription->id)
                    ->update(['status' => 'canceled']);
            }

            return response()->json(['message' => 'Webhook processed'], 200);
        } catch (\Exception $e) {
            // Log::error('Stripe webhook error: ' . $e->getMessage().''.$e->getLine());
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    public function checkoutSuccess(Request $request)
    {
        date_default_timezone_set('Asia/Kolkata');
        $user       = $request->user();
        if (!$user) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
        
        $sessionId  = $request->sessionId;
        $ses_check  = DB::table('subscriptions')->where('session_id',$sessionId)->first();
        if($ses_check!=null)
        {
            $session=json_decode($ses_check->log);
            $time   = date('Y-m-d H:i:s', $session->created);
            $plan   = Plan::find($session->metadata->plan_id);
            $detail = array('plan_name'=>$plan->name,'plan_price'=>$plan->price,'plan_interval'=>$plan->interval,'sub_id'=>$session->subscription,'paid_amount'=>$session->amount_total/100,'email'=>$session->customer_email,'paid_on'=>$time,'currency'=>$session->currency);
            return response()->json([
                'success'       => true,
                'message'       => 'Already Retrieve',
                'detail'        => $detail
            ],200);
        }


        Stripe::setApiKey(config('services.stripe.secret'));
        try {
            $session = Session::retrieve($sessionId);
            // dd($session);
            $subscriptionId = $session->subscription;
            $chargeId = null;
            
            
            // \Log::info('Stripe Success SESSION: ' . $session);
            if($session->payment_status=="paid"){

                $stripeSubscription = \Stripe\Subscription::retrieve($subscriptionId);
                $time    = date('Y-m-d', $session->created); //H:i:s
                $end     = date('Y-m-d', $stripeSubscription->current_period_end); //H:i:s
                
                DB::table('subscriptions')->insert([
                    'user_id'       => $user->id,
                    'session_id'    => $sessionId,
                    'stripe_subscription_id' => $subscriptionId,
                    'plan_id'       => $session->metadata->plan_id,
                    'status'        => 'active',
                    'payment_status'=> 1,
                    'transaction_id'=> $chargeId,
                    'amount'        => ($session->amount_total/100),
                    'start_at'      => $time,
                    'end_at'        => $end,
                    'log'           => json_encode($session),
                    'created_at'    => now(),
                    'updated_at'    => now(),
                ]);

                $plan   = Plan::find($session->metadata->plan_id);
                $detail = array('plan_name'=>$plan->name,'plan_price'=>$plan->price,'plan_interval'=>$plan->interval,'sub_id'=>$subscriptionId,'paid_amount'=>$session->amount_total/100,'email'=>$session->customer_email,'paid_on'=>$time,'currency'=>$session->currency);
                return response()->json([
                    'success'       => true,
                    'message'       => 'Session Created Successfully',
                    'detail'        => $detail
                ],200);
            }
            elseif($session->payment_status=="unpaid")
            {
                $time    = date('Y-m-d', $session->created); //H:i:s
                DB::table('subscriptions')->insert([
                    'user_id'       => $user->id,
                    'session_id'    => $sessionId,
                    'stripe_subscription_id' => $subscriptionId,
                    'plan_id'       => $session->metadata->plan_id,
                    'status'        => 'failed',
                    'payment_status'=> 0,
                    'transaction_id'=> $chargeId,
                    'amount'        => ($session->amount_total/100),
                    'start_at'      => $time,
                    'end_at'        => $time,
                    'log'           => json_encode($session),
                    'created_at'    => now(),
                    'updated_at'    => now(),
                ]);

                $plan   = Plan::find($session->metadata->plan_id);
                $detail = array('plan_name'=>$plan->name,'plan_price'=>$plan->price,'plan_interval'=>$plan->interval,'sub_id'=>$subscriptionId,'paid_amount'=>$session->amount_total/100,'email'=>$session->customer_email,'paid_on'=>$time,'currency'=>$session->currency);
                return response()->json([
                    'success'       => true,
                    'message'       => 'Session Failed',
                    'detail'        => $detail
                ],200);
            }
            else{
                
                return response()->json([
                    'success'       => false,
                    'message'       => 'Oops something went wrong',
                ],200);
                
            }
            
        } catch (\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    public function checkoutFailed(Request $request)
    {
        $user = $request->user();
        if (!$user) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
        Stripe::setApiKey(config('services.stripe.secret'));
        $sessionId = $request->sessionId;
        try {
            $session = Session::retrieve($sessionId);
            \Log::error('Stripe Failed : ' . $session);
        } catch (\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 500);
        }

    }

    public function cancelSubscription(Request $request)
    {
        $user = $request->user();
        $subscription = DB::table('subscriptions')
            ->where('user_id', $user->id)
            ->where('status', 'active')
            ->orderBy('created_at','DESC')
            ->first();

        if ($subscription) {
            Stripe::setApiKey(config('services.stripe.secret'));
            Subscription::update($subscription->stripe_subscription_id, [
                'cancel_at_period_end' => true,
            ]);

            DB::table('subscriptions')
                ->where('id', $subscription->id)
                ->update(['status' => 'canceled']);

            return response()->json([
                'success'   => true,
                'message' => 'Subscription canceled successfully'
            ], 200); //Subscription will be canceled at the end of the billing cycle
        }

        return response()->json([
            'success'   => false,
            'message'   => 'No active subscription found'
        ], 200);
    }

    public function checkSubscription()
    {
        $user = $request->user();
        
        // Get the user's active subscription
        $subscription = DB::table('subscriptions')
            ->where('user_id', $user->id)
            ->where('status', 'active')
            ->first();

        if ($subscription) {
            return response()->json([
                'status' => 'active',
                'stripe_subscription_id' => $subscription->stripe_subscription_id,
                'plan_id' => $subscription->plan_id,
            ]);
        }

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

    public function changePlan(Request $request)
    {
        $user = $request->user();
        $newPriceId = $request->priceId; // New Stripe Price ID

        // Find the user's active subscription
        $subscription = DB::table('subscriptions')
            ->where('user_id', $user->id)
            ->where('status', 'active')
            ->first();

        if (!$subscription) {
            return response()->json(['error' => 'No active subscription found'], 404);
        }

        Stripe::setApiKey(config('services.stripe.secret'));

        try {
            // Update Stripe subscription with the new plan
            $stripeSubscription = \Stripe\Subscription::retrieve($subscription->stripe_subscription_id);
            \Stripe\Subscription::update($stripeSubscription->id, [
                'items' => [
                    [
                        'id' => $stripeSubscription->items->data[0]->id,
                        'price' => $newPriceId,
                    ],
                ],
            ]);

            // Update in the database
            DB::table('subscriptions')
                ->where('id', $subscription->id)
                ->update(['stripe_price_id' => $newPriceId]);

            return response()->json(['message' => 'Subscription updated successfully']);
        } catch (\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    public function paymentHistory(Request $request)
    {
        $user   = $request->user();

        // $list   = DB::table('subscriptions as sub')
        //             ->select('sub.stripe_subscription_id','sub.status','sub.amount','sub.start_at','p.name as plan_name','p.interval','sub.is_trial','sub.payment_status')
        //             ->leftjoin('plans as p','p.id','=','sub.plan_id')
        //             ->where('sub.user_id',$user->id)
        //             ->orderBy('sub.id','DESC')
        //             ->get();

        $list   = SubscriptionDB::with(['plan' => function ($query) {
            $query->select('_id', 'name', 'interval'); // MongoDB uses _id
        }])
        ->where('user_id', $user->id)
        ->orderByDesc('_id')
        ->get()
        ->map(function ($sub) {
            return [
                'id' => $sub->id,
                'stripe_subscription_id' => $sub->stripe_subscription_id,
                'status' => $sub->status,
                'amount' => $sub->amount,
                'start_at' => $sub->start_at,
                'plan_name' => $sub->plan->name ?? null,
                'interval' => $sub->plan->interval ?? null,
                'is_trial' => $sub->is_trial,
                'payment_status' => $sub->payment_status,
            ];
        });
        
        return response()->json([
            'success'       => true,
            'message'       => 'Payment History',
            'list'          => $list
        ],200);
    }
    
}
