<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Feature;
use App\Models\Subscription;
use App\Models\SubscriptionFeature;
use Illuminate\Support\Facades\Validator;
use Stripe\Stripe;
use Stripe\Checkout\Session;
use Stripe\Exception\SignatureVerificationException;
use Stripe\Webhook;
use Exception;

class SubscriptionController extends Controller
{
    /**
     * Display All Subscription
     */
    public function index()
    {
        try {
            $subscriptions = Subscription::with('features')->latest()->get();
            if ($subscriptions->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['subscriptions' => $subscriptions];
            return response()->json([
                'data' => $data,
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Display All Subscription with Trashed.
     */
    public function withTrashed()
    {
        try {
            $subscriptions = Subscription::with('features')->withTrashed()->latest()->get();
            if ($subscriptions->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['subscriptions' => $subscriptions];
            return response()->json([
                'data' => $data,
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Display Only Trashed Subscription.
     */
    public function trash()
    {
        try {
            $subscriptions = Subscription::with('features')->onlyTrashed()->latest()->get();
            if ($subscriptions->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['subscriptions' => $subscriptions];
            return response()->json([
                'data' => $data,
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Display Restore Trashed Feature.
     */
    public function restore(string $id)
    {
        try {
            $subscription = Subscription::with('features')->onlyTrashed()->find($id);
            if (!$subscription) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $subscription->restore();
            $data = ['subscription' => $subscription];
            return response()->json([
                'data' => $data,
                'response_message' => ['success' => ['Subscription Restored Successfully!']],
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Create Subscription with Features
     */
    public function store(Request $request)
    {
        // dd($request->all());
        try {
            $validation = Validator::make($request->all(), [
                'title' => 'required|string|max:255',
                'type' => 'required|string',
                'price' => 'required|numeric',
                'duration' => 'required|in:monthly,annual',
                'headline' => 'nullable|string',
                'user_allowed' => 'nullable',
                'subject_allowed' => 'nullable',
                'features' => 'required|array',
                'features.*' => 'required|exists:features,id',
            ]);

            if ($validation->fails()) {
                return response()->json([
                    'validation_errors' => $validation->messages(),
                    'response_status' => 400,
                ], 200);
            }

            // Determine if `user_allowed` or `subject_allowed` should be validated based on `type`
            if ($request->type === 'student' && is_null($request->subject_allowed)) {
                return response()->json([
                    'validation_errors' => ['subject_allowed' => ['The subject allowed field is required.']],
                    'response_status' => 400,
                ], 200);
            }

            if ($request->type === 'school' && is_null($request->user_allowed)) {
                return response()->json([
                    'validation_errors' => ['user_allowed' => ['The user allowed field is required.']],
                    'response_status' => 400,
                ], 200);
            }

            // Determine interval based on type (0 for monthly, 1 for yearly)
            $interval = $request->duration === 'annual' ? 'year' : 'month';

            try {
                \Stripe\Stripe::setApiKey(config('services.stripe.secret'));
                $product = \Stripe\Product::create([
                    'name' => $request->title,
                    'type' => 'service', // Assuming this is a service type product
                ]);

                $price = \Stripe\Price::create([
                    'product' => $product->id,
                    'unit_amount' => $request->price * 100, // Convert amount to cents
                    'currency' => 'USD',
                    'recurring' => [
                        'interval' => $interval,
                    ],
                ]);
            } catch (\Exception $e) {
                return response()->json([
                    'error' => $e->getMessage(),
                    'response_status' => 500,
                ], 500);
            }

            // Create Subscription
            $subscription = Subscription::create([
                'title' => $request->title,
                'stripe_price_id' => $price->id,
                'type' => $request->type,
                'price' => $request->price,
                'duration' => $request->duration,
                'headline' => $request->headline,
                'user_allowed' => $request->type === 'school' ? $request->user_allowed : null,
                'subject_allowed' => $request->type === 'student' ? $request->subject_allowed : null,
            ]);

            $insertedData = ['subscription' => $subscription];

            // Handle features
            if (!empty($request->features) && is_array($request->features)) {
                $featuresData = [];
                foreach ($request->features as $featureId) {
                    $featureEntry = SubscriptionFeature::create([
                        'subscription_id' => $subscription->id,
                        'feature_id' => $featureId,
                    ]);
                    $featuresData[] = $featureEntry;
                }
                $insertedData['features'] = $featuresData;
            }

            return response([
                'response_status' => 200,
                'response_message' => ['success' => ['Subscription Created Successfully!']],
                'data' => $insertedData
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Display Single Subscription with Features
     */
    public function show($id)
    {
        try {
            $subscription = Subscription::with('features')->find($id);
            if (!$subscription) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['subscription' => $subscription];
            return response()->json([
                'data' => $data,
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }
    
    // Active the Marked as Featured
    // public function featureSubscription(Request $request, string $id)
    // {
    //     try {

    //         $validation = Validator::make($request->all(), [
    //             'id' => 'nullable|exists:subscriptions,id',
    //         ]);

    //         if ($validation->fails()) {
    //             return response()->json([
    //                 'validation_errors' => $validation->messages(),
    //                 'response_status' => 400,
    //             ], 200);
    //         }

    //         // Find the class by ID
    //         $subscription = Subscription::select('id','mark_featured')->find($id);
    //         if (!$subscription) {
    //             return response()->json([
    //                 // 'validation_errors' => ['not_found' => ['No Data Found!']],
    //                 'response_status' => 400
    //             ], 200);
    //         }
    //         $subscription->mark_featured = !$subscription->mark_featured;
    //         $subscription->save();

    //         $data = ['subscription' => $subscription];
    //         return response()->json([
    //             'data' => $data,
    //             'response_message' => ['success' => ['Subscription Mark as Featured Successfully!']],
    //             'response_status' => 200
    //         ], 200);
    //     } catch (Exception $e) {
    //         return response()->json([
    //             'validation_errors' => $e->getMessage(),
    //             'response_status' => 400,
    //         ], 200);
    //     }
    // }
   public function featureSubscription(Request $request, string $id)
    {
        try {
            // Validate the request
            $validation = Validator::make($request->all(), [
                'id' => 'nullable|exists:subscriptions,id',
            ]);

            if ($validation->fails()) {
                return response()->json([
                    'validation_errors' => $validation->messages(),
                    'response_status' => 400,
                ], 200);
            }

            // Find the subscription by ID
            $subscription = Subscription::find($id);
            if (!$subscription) {
                return response()->json([
                    'response_message' => ['error' => ['Subscription not found!']],
                    'response_status' => 404
                ], 200);
            }

            // Get the type and duration of the subscription
            $type = $subscription->type;
            $duration = $subscription->duration;

            // Update all subscriptions of the same type and duration to mark_featured = 0
            Subscription::where('type', $type)->where('duration', $duration)->update(['mark_featured' => 0]);

            // Update the requested subscription to mark_featured = 1
            $subscription->mark_featured = 1;
            $subscription->save();

            return response()->json([
                'data' => ['subscription' => $subscription],
                'response_message' => ['success' => ['Subscription Marked as Featured Successfully!']],
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Update Subscription with Features
     */
    // public function update(Request $request, $id)
    // {
    //     // dd($request->all());
    //     try {
    //         $validation = Validator::make($request->all(), [
    //             'title' => 'required|string|max:255',
    //             'type' => 'required|string',
    //             'price' => 'required|numeric',
    //             'duration' => 'required|in:monthly,annual',
    //             'headline' => 'nullable|string',
    //             'user_allowed' => 'nullable',
    //             'subject_allowed' => 'nullable',
    //             'features' => 'required|array',
    //             'features.*' => 'required|exists:features,id',
    //         ]);

    //         if ($validation->fails()) {
    //             return response()->json([
    //                 'validation_errors' => $validation->messages(),
    //                 'response_status' => 400,
    //             ], 200);
    //         }

    //         // Determine if `user_allowed` or `subject_allowed` should be validated based on `type`
    //         if ($request->type === 'student' && is_null($request->subject_allowed)) {
    //             return response()->json([
    //                 'validation_errors' => ['subject_allowed' => ['The subject_allowed field is required.']],
    //                 'response_status' => 400,
    //             ], 200);
    //         }

    //         if ($request->type === 'school' && is_null($request->user_allowed)) {
    //             return response()->json([
    //                 'validation_errors' => ['user_allowed' => ['The user_allowed field is required.']],
    //                 'response_status' => 400,
    //             ], 200);
    //         }

    //         // Find the subscription
    //         $subscription = Subscription::find($id);
    //         if (!$subscription) {
    //             return response()->json([
    //                 'validation_errors' => ['not_found' => ['No Data Found!']],
    //                 'response_status' => 400
    //             ], 200);
    //         }

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

    //         // Retrieve the existing price and product
    //         $existingPrice = \Stripe\Price::retrieve($subscription->stripe_price_id);
    //         $existingProductId = $existingPrice->product;

    //         try {
    //             // Update the product (if title changes)
    //             \Stripe\Product::update($existingProductId, [
    //                 'name' => $request->title,
    //             ]);

    //             // Update the price (create new if required fields cannot be updated directly)
    //             $interval = $request->duration === 'annual' ? 'year' : 'month';

    //             if ($existingPrice->recurring->interval !== $interval || $existingPrice->unit_amount !== ($request->price * 100)) {
    //                 // Deactivate the existing price
    //                 \Stripe\Price::update($subscription->stripe_price_id, ['active' => false]);

    //                 // Create a new price
    //                 $newPrice = \Stripe\Price::create([
    //                     'product' => $existingProductId,
    //                     'unit_amount' => $request->price * 100, // Convert to cents
    //                     'currency' => 'USD',
    //                     'recurring' => ['interval' => $interval],
    //                 ]);

    //                 $subscription->stripe_price_id = $newPrice->id;
    //             }
    //         } catch (\Exception $e) {
    //             return response()->json([
    //                 'error' => 'Error updating Stripe product or price: ' . $e->getMessage(),
    //                 'response_status' => 500,
    //             ], 500);
    //         }

    //         // Update the subscription details
    //         $subscription->update([
    //             'title' => $request->title,
    //             'stripe_price_id' => $subscription->stripe_price_id, // Use the existing or updated price ID
    //             'type' => $request->type,
    //             'price' => $request->price,
    //             'duration' => $request->duration,
    //             'headline' => $request->headline,
    //             'user_allowed' => $request->type === 'school' ? $request->user_allowed : null,
    //             'subject_allowed' => $request->type === 'student' ? $request->subject_allowed : null,
    //         ]);

    //         $insertedData = ['subscription' => $subscription];

    //         // Handle features
    //         if (!empty($request->features) && is_array($request->features)) {
    //             // Delete existing features
    //             SubscriptionFeature::where('subscription_id', $subscription->id)->delete();

    //             // Insert new features
    //             $featuresData = [];
    //             foreach ($request->features as $featureId) {
    //                 $featureEntry = SubscriptionFeature::create([
    //                     'subscription_id' => $subscription->id,
    //                     'feature_id' => $featureId,
    //                 ]);
    //                 $featuresData[] = $featureEntry;
    //             }
    //             $insertedData['features'] = $featuresData;
    //         }

    //         return response([
    //             'response_status' => 200,
    //             'response_message' => ['success' => ['Subscription Updated Successfully!']],
    //             'data' => $insertedData
    //         ], 200);
    //     } catch (Exception $e) {
    //         return response()->json([
    //             'validation_errors' => $e->getMessage(),
    //             'response_status' => 400,
    //         ], 200);
    //     }
    // }
    public function update(Request $request, $id)
    {
        try {
            $validation = Validator::make($request->all(), [
                'title' => 'required|string|max:255',
                'type' => 'required|string',
                'price' => 'required|numeric',
                'duration' => 'required|in:monthly,annual',
                'headline' => 'nullable|string',
                'user_allowed' => 'nullable',
                'subject_allowed' => 'nullable',
                'features' => 'required|array',
                'features.*' => 'required|exists:features,id',
            ]);

            if ($validation->fails()) {
                return response()->json([
                    'validation_errors' => $validation->messages(),
                    'response_status' => 400,
                ], 200);
            }

            if ($request->type === 'student' && is_null($request->subject_allowed)) {
                return response()->json([
                    'validation_errors' => ['subject_allowed' => ['The subject_allowed field is required.']],
                    'response_status' => 400,
                ], 200);
            }

            if ($request->type === 'school' && is_null($request->user_allowed)) {
                return response()->json([
                    'validation_errors' => ['user_allowed' => ['The user_allowed field is required.']],
                    'response_status' => 400,
                ], 200);
            }

            $subscription = Subscription::find($id);
            if (!$subscription) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400,
                ], 200);
            }

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

            // Retrieve the existing price and product
            $existingPrice = \Stripe\Price::retrieve($subscription->stripe_price_id);
            $existingProductId = $existingPrice->product;

            try {
                // Update the product (if title changes)
                \Stripe\Product::update($existingProductId, [
                    'name' => $request->title,
                ]);

                // Update the price (create new if required fields cannot be updated directly)
                $interval = $request->duration === 'annual' ? 'year' : 'month';

                if ($existingPrice->recurring->interval !== $interval || $existingPrice->unit_amount !== ($request->price * 100)) {
                    // Deactivate the existing price
                    \Stripe\Price::update($subscription->stripe_price_id, ['active' => false]);

                    // Create a new price
                    $newPrice = \Stripe\Price::create([
                        'product' => $existingProductId,
                        'unit_amount' => $request->price * 100, // Convert to cents
                        'currency' => 'USD',
                        'recurring' => ['interval' => $interval],
                    ]);

                    $subscription->stripe_price_id = $newPrice->id;
                }
            } catch (\Exception $e) {
                return response()->json([
                    'error' => 'Error updating Stripe product or price: ' . $e->getMessage(),
                    'response_status' => 500,
                ], 500);
            }

            // Update the subscription details
            $subscription->update([
                'title' => $request->title,
                'stripe_price_id' => $subscription->stripe_price_id, // Use the existing or updated price ID
                'type' => $request->type,
                'price' => $request->price,
                'duration' => $request->duration,
                'headline' => $request->headline,
                'user_allowed' => $request->type === 'school' ? $request->user_allowed : null,
                'subject_allowed' => $request->type === 'student' ? $request->subject_allowed : null,
            ]);

            $insertedData = ['subscription' => $subscription];

            if (!empty($request->features) && is_array($request->features)) {
                SubscriptionFeature::where('subscription_id', $subscription->id)->delete();

                $featuresData = [];
                foreach ($request->features as $featureId) {
                    $featureEntry = SubscriptionFeature::create([
                        'subscription_id' => $subscription->id,
                        'feature_id' => $featureId,
                    ]);
                    $featuresData[] = $featureEntry;
                }
                $insertedData['features'] = $featuresData;
            }

            return response([
                'response_status' => 200,
                'response_message' => ['success' => ['Subscription Updated Successfully!']],
                'data' => $insertedData,
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Temporary Remove Subscription.
     */
    public function delete(string $id)
    {
        try {
            $subscription = Subscription::find($id);
            if (!$subscription) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }

            $subscription->delete();

            return response()->json([
                'response_message' => ['success' => ['Subscription has been sent to Trash!']],
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Permanantly Remove Subscription.
     */
    public function destroy(string $id)
    {
        try {
            $subscription = Subscription::onlyTrashed()->find($id);
            if (!$subscription) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }

            $subscription->forceDelete();

            return response()->json([
                'response_message' => ['success' => ['Deleted From Trash Successfully!']],
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }
}
