<?php

namespace App\Http\Controllers\APIs\Customer_API;

use App\Helpers\onesignalhelper;
use App\Http\Controllers\Controller;
use App\Models\IamPrincipal;
use App\Models\ReferralUsers;
use App\Models\SubscriptionProducts;
use App\Models\Subscriptions;
use Illuminate\Http\Request;
use Stripe\Event;
use Stripe\Stripe;
use Carbon\Carbon;

use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use DateTime;

class StripeWebhookController extends Controller
{
    //


    public function getWebhook(Request $request)
    {
        // dd("ssssss",$request);
        Log::info('Stripe Webhook Received= in getWebhook ');
    }
    public function handleWebhook(Request $request)
    {
        Log::info("webhook At line 1");

        // Verify the webhook signature for security
        $secret = config('constants.subscription.webhook_secret'); // Your webhook secret key

        $payload = $request->getContent();
        $sigHeader = $request->header('Stripe-Signature');
        $event = null;


        try {
            $event = Event::constructFrom(
                json_decode($payload, true),
                $sigHeader,
                config('constants.subscription.webhook_secret')
            );


        } catch (\UnexpectedValueException $e) {
            // Invalid payload
            return response()->json(['error' => 'Invalid payload'], 400);
        } catch (\Stripe\Exception\SignatureVerificationException $e) {
            // Signature verification failed
            return response()->json(['error' => 'Signature verification failed'], 400);
        }
        // $stripeSecret = config('services.stripe.key');

        $stripeSecret = (config('constants.subscription.stripe_secret_key'));




        Log::info("webhook called");
        $stripe = new \Stripe\StripeClient($stripeSecret);

        if ($event->type === 'checkout.session.completed') {
            try {

                DB::beginTransaction();
                // Handle successful subscription payment
                // You can access event data like $event->data->object

                // Session::flush();
                $session = $event->data->object;

                $metadata = $session->metadata;
                if ($metadata == null || empty($metadata)) {
                    return response('Webhook Metadata received at null ', 200);
                }
                $userId = $metadata->userId;
                $userEmail = $metadata->userEmail;
                $subscriptionProductId = $metadata->subscriptionProductXid;


                $isReferralSubscription = $metadata->is_referral_subscription;
                $isCustomReferralCodeApplied = $metadata->isCustomReferralCodeApplied;

                $referralUserId = $metadata->referral_user_id;

                if ($isReferralSubscription == 1 && $isCustomReferralCodeApplied == 0) {
                    //who has refer the Subscription to Current user
                    Log::info("Referral User Subscription Updating Function Starts");

                    $referralUserSubscriptionData = Subscriptions::where('iam_principal_xid', $referralUserId)->where('subscription_status', '=', 'active')->first();

                    // $stripe->subscriptions->update(
                    //     $referralUserSubscriptionData->subscription_id,
                    //     ['proration_behavior' => 'none']
                    // );
                    if ($referralUserSubscriptionData && $referralUserSubscriptionData->is_cancelled_subscription == 0) {


                        //update subscription add 30 days trial period to this subscription
                        $nextPaymentDate = $referralUserSubscriptionData->next_payment_date;

                        // we are setting next payment date based on REFERRAL .. IF USER HAS NOT REFERRED YET.. then it will take next_payment_date
                        //Otherwise IT need to take THE LAST REFERRED DATA

                        // $userLastReferredDate = ReferralUsers::where('iam_principal_xid',$referralUserId)->last();
                        $userLastReferredDate = ReferralUsers::where('iam_principal_xid', $referralUserId)
                            ->orderBy('referred_date_time', 'desc')
                            ->first();

                        if ($userLastReferredDate) {
                            Log::info("trial date added for multiple time");
                            $date = new DateTime($referralUserSubscriptionData->next_payment_date);
                            // $date = new DateTime($nextPaymentDate);
                            $date->modify('+30 days');
                        } else {
                            $date = new DateTime($nextPaymentDate);
                        }


                        $newDate = $date->format('Y-m-d H:i:s');
                        Log::info("new Date = ");
                        Log::info($newDate);
                        $timestampForReferralUser = $date->getTimestamp();
                        Log::info($timestampForReferralUser);
                        $updateSubscription = $stripe->subscriptions->update(
                            $referralUserSubscriptionData->subscription_id,
                            ['trial_end' => $timestampForReferralUser]
                        );

                        $SubscriptionObject = $stripe->subscriptions->retrieve($referralUserSubscriptionData->subscription_id, []);

                        $upcoming_invoice = $stripe->invoices->upcoming([
                            'subscription' => $referralUserSubscriptionData->subscription_id,       // use retrieved id from subscription
                        ]);
                        Log::info("UPCOMING INVOICE");

                        Log::info($upcoming_invoice);
                        $referralUserSubscriptionData->current_period_start = date('Y-m-d H:i:s', $SubscriptionObject->current_period_start);
                        $referralUserSubscriptionData->current_period_end = date('Y-m-d H:i:s', $SubscriptionObject->current_period_end);
                        $referralUserSubscriptionData->next_payment_date = date('Y-m-d H:i:s', $upcoming_invoice->next_payment_attempt);
                        $referralUserSubscriptionData->next_invoice_amount = $upcoming_invoice->amount_due / 100;

                        $referralUserSubscriptionData->save();

                        Log::info("Referral User Subscription Updated with Referral");

                        //updated the Referral Users Subscription.

                    }
                }

                $subscriptionProductData = SubscriptionProducts::where('id', $subscriptionProductId)->first();

                //checkout store in db
                $subscriptionData = $stripe->checkout->sessions->retrieve($session->id, []);
                $SubscriptionObject = $stripe->subscriptions->retrieve($subscriptionData->subscription, []);
                //update proration behavior
                // $stripe->subscriptions->update(
                //     $subscriptionData->subscription,
                //     ['proration_behavior' => 'none']
                // );

                //update proration behavior

                $priceObject = $stripe->prices->retrieve($SubscriptionObject->plan->id, []);

                $amountSubtotalDollars = $subscriptionData->amount_total / 100;
                // Log::info('Subscription has been started ');



                $subscriptionObjectFromInvoice = $stripe->subscriptions->retrieve($subscriptionData->subscription, []);

                $upcoming_invoice = $stripe->invoices->upcoming([
                    'subscription' => $subscriptionData->subscription,                  // use retrieved id from subscription
                ]);

                $id = Subscriptions::updateOrCreate(
                    ['iam_principal_xid' => $userId, 
                    'subscription_product_xid' => $subscriptionProductId],
                    [
                        'subscription_id' => $subscriptionData->subscription,
                        'amount' => $amountSubtotalDollars,
                        'stripe_customer_id' => $subscriptionData->customer,
                        'subscription_status' => $subscriptionObjectFromInvoice->status,
                        'current_period_start' => date('Y-m-d H:i:s', $SubscriptionObject->current_period_start),
                        'current_period_end' => date('Y-m-d H:i:s', $SubscriptionObject->current_period_end),

                        'status' => 'complete',
                        'next_payment_date' => date('Y-m-d H:i:s', $upcoming_invoice->next_payment_attempt),
                        'next_invoice_amount' => $upcoming_invoice->amount_due / 100


                    ]
                );

                if ($isReferralSubscription == 1 && $isCustomReferralCodeApplied == 1) {

                    Log::info("new User Subscription Updating Function Starts");

                    //update Current User subscription to add 30 days additional to their subscription end
                    $SubscriptionObject = $stripe->subscriptions->retrieve($subscriptionData->subscription, []);
                    $newUserSubscriptionDetails = Subscriptions::where('iam_principal_xid', $userId)
                        ->where('subscription_product_xid', $subscriptionProductId)->first();

                    $nextPaymentDate = $newUserSubscriptionDetails->next_payment_date;
                    $date = new DateTime($nextPaymentDate);
                    // $date->modify('+30 days');
                    $newDate = $date->format('Y-m-d H:i:s');
                    Log::info("new Date = ");
                    Log::info($newDate);
                    $timestampForReferralUser = $date->getTimestamp();
                    Log::info(" Updating Function Starts");

                    $updateSubscription = $stripe->subscriptions->update(
                        $newUserSubscriptionDetails->subscription_id,
                        ['trial_end' => $timestampForReferralUser]
                    );
                    Log::info(" Updating Function END");


                    $SubscriptionObject = $stripe->subscriptions->retrieve($newUserSubscriptionDetails->subscription_id, []);

                    $upcoming_invoice = $stripe->invoices->upcoming([
                        'subscription' => $newUserSubscriptionDetails->subscription_id,       // use retrieved id from subscription
                    ]);
                    $newUserSubscriptionDetails->current_period_start = date('Y-m-d H:i:s', $SubscriptionObject->current_period_start);
                    $newUserSubscriptionDetails->current_period_end = date('Y-m-d H:i:s', $SubscriptionObject->current_period_end);
                    $newUserSubscriptionDetails->next_payment_date = date('Y-m-d H:i:s', $upcoming_invoice->next_payment_attempt);
                    $newUserSubscriptionDetails->next_invoice_amount = $upcoming_invoice->amount_due / 100;

                    $newUserSubscriptionDetails->save();

                    Log::info("new User Subscription Updated with Referral");


                    Log::info("Creating entry in Referral User table");
                    Log::info($referralUserId);
                    Log::info($userId);

                    Log::info($isCustomReferralCodeApplied);

              

                    ReferralUsers::create([

                        'iam_principal_xid' => $referralUserId, //Referral User Xid
                        'referred_user_xid' => $userId, // new user Id
                        'referred_date_time' => Carbon::now(),
                        'isCustomReferralCodeApplied' =>$isCustomReferralCodeApplied
                    ]);
                    Log::info("Created entry in Referral User table");

                }

                $getUserData = IamPrincipal::where('id', $userId)->first();

                $title = "Congratulations your subscription is now active";
                $message = $getUserData->first_name . " has subscribed for " . $subscriptionProductData->name;
                $content_type = "new_subscription";

                onesignalhelper::sendNotificationApi($getUserData->one_signal_player_id, $title, $message, $content_type, $image = null, $id = null);

                Log::info('Subscription Taken Successfully by ');
                DB::commit();
            } catch (\Exception $e) {
                Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage());
                // return response()->json(['error' => __('something_went_wrong')], 500);
                Log::error('Customer Subscription Checkout session function failed: ' . $e->getMessage() . $e->getLine());
                DB::rollBack();


            }
            //end
        }

        if ($event->type === 'invoice.payment_succeeded') {

            try {

                DB::beginTransaction();
                $invoice = $event->data->object;

                $metadata = $invoice->metadata;

                //
                $productID = $invoice->lines->data[0]->price->product;
                $subscriptionProductData = SubscriptionProducts::where('stripe_product_id', $productID)->first();

                $customerID = $invoice->customer;

                $subscriptionId = $invoice->lines->data[0]->subscription;

                $subscriptionObject = $stripe->subscriptions->retrieve($subscriptionId, []);

                $upcoming_invoice = $stripe->invoices->upcoming([
                    'subscription' => $subscriptionId,                  // use retrieved id from subscription
                ]);


                $isCustomerStoredInSubscriptionTable = Subscriptions::where('stripe_customer_id', $customerID)->first();
                if ($isCustomerStoredInSubscriptionTable == null) {
                    return response('Webhook received at null ', 200);
                }

                $subscriptionInDatabase = Subscriptions::where('stripe_customer_id', $customerID)->where('subscription_id', $subscriptionId)->where('is_cancelled_subscription', 0)->first();

                $subscriptionInDatabase->subscription_status = $subscriptionObject->status;
                $subscriptionInDatabase->current_period_end = date('Y-m-d H:i:s', $upcoming_invoice->next_payment_attempt);
                $subscriptionInDatabase->status = 'complete';
                $subscriptionInDatabase->next_payment_date = date('Y-m-d H:i:s', $upcoming_invoice->next_payment_attempt);
                $subscriptionInDatabase->save();


                $iamPrincialData = IamPrincipal::where('id', $subscriptionInDatabase->iam_principal_xid)->first();



                $title = "Congratulations your Subscription has been Renewed";
                $message = $iamPrincialData->first_name . " has subscribed for " . $subscriptionProductData->product_name;
                $content_type = "recurring_subscription";

                onesignalhelper::sendNotificationApi($iamPrincialData->one_signal_player_id, $title, $message, $content_type, $image = null, $id = null);

                Log::info("Recurring Subscription has been Updated");
                DB::commit();

            } catch (\Exception $e) {
                Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage());
                // return response()->json(['error' => __('something_went_wrong')], 500);

                DB::rollBack();
                Log::error('Customer Subscription Invoice payment function failed:' . $e->getMessage());

            }
            // write your code here
            // after successful event this actions will be taken

            //hritik code

        }

        return response('Webhook received', 200);
    }
}