<?php

// app/Http/Controllers/SubscriptionController.php

namespace App\Http\Controllers;

use App\Models\CorrectScoreGame;
use App\Models\CorrectScoreGameGroup;
use App\Models\ManualPayment;
use App\Models\Subscription;
use App\Models\Transaction;
use App\Models\User;
use App\Models\VipGameGroup;
use App\Models\VvipGameGroup;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class SubscriptionController extends Controller
{
    public function subscribe(Request $request)
    {
        $request->validate([
            'game_group_id' => 'required|integer',
            'type' => 'required|in:vip,vvip,correct_score',
            'expires_at' => 'required|date',
        ]);

        $subscriptionData = [
            'user_id' => Auth::id(),
            'expires_at' => $request->expires_at,
        ];

        switch ($request->type) {
            case 'vip':
                $subscriptionData['vip_game_group_id'] = $request->game_group_id;
                break;
            case 'vvip':
                $subscriptionData['vvip_game_group_id'] = $request->game_group_id;
                break;
            case 'correct_score':
                $subscriptionData['correct_score_game_group_id'] = $request->game_group_id;
                break;
        }

        $subscription = Subscription::create($subscriptionData);

        return response()->json($subscription, 201);
    }

    public function checkSubscription($type, $gameGroupId)
    {
        $subscription = Subscription::where('user_id', Auth::id())
            ->where(function ($query) use ($type, $gameGroupId) {
                switch ($type) {
                    case 'vip':
                        $query->where('vip_game_group_id', $gameGroupId);
                        break;
                    case 'vvip':
                        $query->where('vvip_game_group_id', $gameGroupId);
                        break;
                    case 'correct_score':
                        $query->where('correct_score_game_group_id', $gameGroupId);
                        break;
                }
            })
            ->where('expires_at', '>', now())
            ->first();

        return response()->json(['active' => (bool) $subscription], 200);
    }

    public function getSubscribedUsers()
    {
        $subscribedUsers = Subscription::join('users', 'subscriptions.user_id', '=', 'users.id')
            ->leftJoin('vip_game_groups', 'subscriptions.vip_game_group_id', '=', 'vip_game_groups.id')
            ->leftJoin('vvip_game_groups', 'subscriptions.vvip_game_group_id', '=', 'vvip_game_groups.id')
            ->leftJoin('correct_score_game_groups', 'subscriptions.correct_score_game_group_id', '=', 'correct_score_game_groups.id')
            ->where('users.role', '!=', 'admin')
            ->where(function ($query) {
                $query->where('vip_game_groups.created_at', '>=', today())
                    ->orWhere('vvip_game_groups.created_at', '>=', today())
                    ->orWhere('correct_score_game_groups.created_at', '>=', today());
            })
            ->distinct('users.id') // Ensure distinct user IDs
            ->select('users.id')
            ->get();

        $subscribedUserCount = $subscribedUsers->count();

        Log::info('Subscribed Users Count: ' . $subscribedUserCount);


        return response()->json(['subscribedUsers' => $subscribedUsers->count()], 200);
    }



    public function getAllUsers(Request $request)
    {
        $limit = $request->query('limit');

        if ($limit) {
            $users = User::where('role', 'user')->limit($limit)->get();
        } else {
            $users = User::where('role', 'user')->get();
        }

        return response()->json($users, 200);
    }
    public function getUnsubscribedUsers()
    {
        $activeSubscriptions = Subscription::join('users', 'subscriptions.user_id', '=', 'users.id')
            ->leftJoin('vip_game_groups', 'subscriptions.vip_game_group_id', '=', 'vip_game_groups.id')
            ->leftJoin('vvip_game_groups', 'subscriptions.vvip_game_group_id', '=', 'vvip_game_groups.id')
            ->leftJoin('correct_score_game_groups', 'subscriptions.correct_score_game_group_id', '=', 'correct_score_game_groups.id')
            ->where('users.role', '!=', 'admin')
            ->where(function ($query) {
                $query->where('vip_game_groups.created_at', '>=', today())
                    ->orWhere('vvip_game_groups.created_at', '>=', today())
                    ->orWhere('correct_score_game_groups.created_at', '>=', today());
            })
            ->pluck('users.id')
            ->unique();

        $unsubscribedUsers = User::where('role', 'user')
            ->whereNotIn('id', $activeSubscriptions)
            ->get();

        $unsubscribedUserCount = $unsubscribedUsers->count();
        Log::info($unsubscribedUserCount);

        return response()->json($unsubscribedUsers, 200);
    }



    public function getRecentUsers()
    {
        $users = User::where('role','user')->get()->take(15)->orderBy('');
        return response()->json($users, 200);
    }






    public function verifyPayment(Request $request)
    {
        Log::info($request->all());

        // Retrieve the event and data
        $event = $request->input('event');
        $data = $request->input('data');

        // Acknowledge the event immediately

        $reference = $request->input('reference');
        $country = $request->input('country');
        $normalizedCountry = strtolower($country);

        // Check if the reference is present
        if (!$reference) {
            return response()->json(['status' => 'failed', 'message' => 'Reference is required'], 400);
        }

        // Verify the transaction with Paystack
        //$secretKey = "sk_live_133b261c2a9a010ee6962e066ddb663c78ae9596";

        $secretKey='';
        if ($normalizedCountry == "nigeria"){
            $secretKey='sk_live_69997ecfeba45df388ed13da6baf41068e3ec3d0';
            //$secretKey='sk_test_d7a53a157e38630204d2fff2e7ad82bb4b113231';
        }else{
            $secretKey = "sk_live_c7c66e812fa33649e7eeb9248862a31e69b9811d";
            //$secretKey = "sk_test_f17e372ad74bd5d55768d51769ff817126f6c064";
        }


        $response = Http::withToken($secretKey)->get("https://api.paystack.co/transaction/verify/{$reference}");



        if ($response->successful()) {
            $transactionData = $response->json()['data'];

            if ($transactionData['status'] === 'success') {
                $email = $transactionData['customer']['email'];
                $user = User::where('email', $email)->first();

                if ($user) {
                    $amountPaid = $transactionData['amount'] / 100;
                    $expiresAt = now()->addMonth();

                    $metadata = $transactionData['metadata'] ?? [];
                    $groupId = null;
                    $groupType = null;

                    if (isset($metadata['custom_fields'])) {
                        foreach ($metadata['custom_fields'] as $field) {
                            if ($field['variable_name'] === 'group_id') {
                                $groupId = $field['value'];
                            }
                            if ($field['variable_name'] === 'group_type') {
                                $groupType = $field['value'];
                            }
                        }
                    }

                    $subscriptionData = [
                        'user_id' => $user->id,
                        'amount_paid' => $amountPaid,
                        'expires_at' => $expiresAt,
                    ];

                    if ($groupType === 'vip') {
                        $subscriptionData['vip_game_group_id'] = $groupId;
                    } elseif ($groupType === 'vvip') {
                        $subscriptionData['vvip_game_group_id'] = $groupId;
                    } elseif ($groupType === 'correct_score') {
                        $subscriptionData['correct_score_game_group_id'] = $groupId;
                    }

                    $subscription = Subscription::create($subscriptionData);

                    // Create a new transaction record to avoid duplicate processing
                    Transaction::create([
                        'reference' => $reference,
                        'user_id' => $user->id,
                        'amount' => $amountPaid,
                        'status' => 'success',
                        'gateway_response' => $transactionData['gateway_response'],
                        'channel' => $transactionData['channel'],
                        'paid_at' => Carbon::now(),
                    ]);

                    $games = [];

                    if ($groupType === 'vip') {
                        $games = VipGameGroup::with('games')->where('id', $groupId)->get();
                    } elseif ($groupType === 'vvip') {
                        $games = VvipGameGroup::with('games')->where('id', $groupId)->get();
                    } elseif ($groupType === 'correct_score') {
                        $games = CorrectScoreGameGroup::with('games')->where('id', $groupId)->get();
                    }

                    Log::info($games);

                    if ($games->isNotEmpty() && isset($games[0])) {
                        $firstGroup = $games[0];

                        // Add the booking info to all games within the first group
                        foreach ($firstGroup->games as $game) {
                            $game->sporty_booking = $firstGroup->sporty_booking;
                            $game->msport_booking = $firstGroup->msport_booking;
                            $game->betway_booking = $firstGroup->betway_booking;
                            $game->onex_booking = $firstGroup->onex_booking;
                        }
                    }

                    return response()->json(['status' => 'success', 'subscription' => $subscription, 'games' => $games], 200);

                } else {
                    return response()->json(['status' => 'failed', 'message' => 'User not found'], 404);
                }
            } else {
                return response()->json(['status' => 'failed', 'message' => $transactionData['gateway_response']], 400);
            }
        }

        return response()->json(['status' => 'failed', 'message' => $response->json()['message']], 400);


        return response()->json(['status' => 'failed', 'message' => 'Invalid event'], 400);
    }

    public function getUserSubscriptions()
    {
        $user = Auth::user();
        //Log::info('Getting subscriptions for user', ['user_id' => $user->id]);

        $subscriptions = Subscription::where('user_id', $user->id)
            ->where('expires_at', '>', now())
            ->with('vipGameGroup.games', 'vvipGameGroup.games', 'correctScoreGameGroup.games')
            ->orderBy('created_at', 'desc') // newest subscriptions first
            ->get();


//        Log::info('Found subscriptions', [
//            'user_id' => $user->id,
//            'subscription_count' => $subscriptions->count(),
//            'subscriptions' => $subscriptions->toArray()
//        ]);

        return response()->json($subscriptions, 200);
    }

    public function getUsersWithSubscriptions()
    {
        // Fetch users who are not admins and have active subscriptions based on the game creation date
        $users = User::where('role', '!=', 'admin')
            ->with(['subscriptions' => function ($query) {
                $query->where('expires_at', '>', now());
            }])
            ->get();

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

    public function initializeTransaction(Request $request)
    {

        // Validate the request inputs
        $request->validate([
            'email' => 'required|email',
            'amount' => 'required|integer|min:1',
            'group_id' => 'required|integer',
            'group_type' => 'required|string'
        ]);

        // Generate a unique reference
        $reference = 'ref-' . uniqid() . '-' . now()->timestamp;

        // Paystack secret key
        // $secretKey = "sk_live_133b261c2a9a010ee6962e066ddb663c78ae9596";
        $secretKey = "sk_test_f17e372ad74bd5d55768d51769ff817126f6c064";
        // Prepare the data to send to Paystack
        $data = [
            "email" => $request->email,
            "amount" => $request->amount * 100,
            "metadata" => [
                "custom_fields" => [
                    [
                        "variable_name" => "group_id",
                        "value" => $request->group_id
                    ],
                    [
                        "variable_name" => "group_type",
                        "value" => $request->group_type
                    ]
                ]
            ]
        ];

        try {
            // Make the request to Paystack API
            $response = Http::withToken($secretKey)->post("https://api.paystack.co/transaction/initialize", $data);

            // Log the response for debugging
            Log::info($response->json());

            // Check if the request was successful
            if ($response->successful()) {
                $responseData = $response->json();
                return response()->json([
                    'status' => 'success',
                    'authorization_url' => $responseData['data']['authorization_url'],
                    'reference' => $responseData['data']['reference'],
                ]);
            } else {
                return response()->json(['status' => 'failed', 'message' => $response->json()['message']], 400);
            }
        } catch (\Exception $e) {
            return response()->json(['status' => 'failed', 'message' => $e->getMessage()], 500);
        }
    }

    // Manual Payment Methods
    public function submitManualPayment(Request $request)
    {
        Log::info($request->all());
        try {
            $request->validate([
                'screenshot' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
                'groupId' => 'required|integer',
                'groupType' => 'required|string',
                'amount' => 'required|numeric',
                'country' => 'required|string',
                'userId' => 'required|integer'
            ]);

            Log::info("here 1");

            // Handle file upload
            $screenshot = $request->file('screenshot');
            $fileName = uniqid('payment_') . '.' . $screenshot->getClientOriginalExtension();
            $uploadPath = public_path('uploads/manual-payments');
            $screenshot->move($uploadPath, $fileName);
            $fileUrl = url('uploads/manual-payments/' . $fileName);
            $fullPath = $uploadPath . '/' . $fileName;
            Log::info("here 2");
            // Create manual payment record using Eloquent
            $manualPayment = ManualPayment::create([
                'user_id' => $request->userId,
                'group_id' => $request->groupId,
                'group_type' => $request->groupType,
                'amount' => $request->amount,
                'country' => $request->country,
                'screenshot_path' => $fileUrl,
                'status' => 'pending'
            ]);
            Log::info("here 3");
            $this->sendSms();
            return response()->json([
                'success' => true,
                'paymentId' => $manualPayment->id,
                'message' => 'Payment request submitted successfully'
            ]);

        } catch (\Exception $e) {
            return response()->json(['error' => 'Server error: ' . $e->getMessage()], 500);
        }
    }

    public function getManualPaymentStatus($paymentId)
    {
        try {
            $payment = ManualPayment::find($paymentId);

            if (!$payment) {
                return response()->json(['error' => 'Payment not found'], 404);
            }

            return response()->json([
                'id' => $payment->id,
                'status' => $payment->status,
                'admin_notes' => $payment->admin_notes,
                'created_at' => $payment->created_at,
                'updated_at' => $payment->updated_at
            ]);

        } catch (\Exception $e) {
            return response()->json(['error' => 'Server error: ' . $e->getMessage()], 500);
        }
    }

    public function getManualPaymentsForAdmin(Request $request)
    {
        Log::info("here 4");

        try {
            $status = $request->query('status', 'all');
            $page = (int)$request->query('page', 1);
            $limit = (int)$request->query('limit', 20);

            $query = ManualPayment::with('user');

            if ($status !== 'all') {
                $query->where('status', $status);
            }

            $payments = $query->orderBy('created_at', 'desc')
                ->paginate($limit, ['*'], 'page', $page);


            Log::info($payments);
            return response()->json([
                'payments' => $payments->items(),
                'pagination' => [
                    'page' => $payments->currentPage(),
                    'limit' => $payments->perPage(),
                    'total' => $payments->total(),
                    'pages' => $payments->lastPage()
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json(['error' => 'Server error: ' . $e->getMessage()], 500);
        }
    }

    public function updateManualPaymentStatus(Request $request, $paymentId)
    {
        try {
            $request->validate([
                'status' => 'required|in:approved,rejected',
                'admin_notes' => 'nullable|string'
            ]);

            $status = $request->status;
            $adminNotes = $request->admin_notes ?? '';

            // Get payment details first
            $payment = ManualPayment::find($paymentId);

            if (!$payment) {
                return response()->json(['error' => 'Payment not found'], 404);
            }

            // Update payment status
            $payment->update([
                'status' => $status,
                'admin_notes' => $adminNotes
            ]);

            // If approved, create subscription
            if ($status === 'approved') {
                Log::info('Creating subscription for approved manual payment', ['payment_id' => $payment->id]);
                $this->createSubscriptionFromManualPayment($payment);
            }

            return response()->json([
                'success' => true,
                'message' => 'Payment status updated successfully'
            ]);

        } catch (\Exception $e) {
            return response()->json(['error' => 'Server error: ' . $e->getMessage()], 500);
        }
    }

    private function createSubscriptionFromManualPayment($payment)
    {
        try {
            Log::info('Starting subscription creation', [
                'user_id' => $payment->user_id,
                'group_type' => $payment->group_type,
                'group_id' => $payment->group_id,
                'amount' => $payment->amount
            ]);

            $subscriptionData = [
                'user_id' => $payment->user_id,
                'amount_paid' => $payment->amount,
                'expires_at' => now()->addMonth()
            ];

            switch ($payment->group_type) {
                case 'vip':
                    $subscriptionData['vip_game_group_id'] = $payment->group_id;
                    break;
                case 'vvip':
                    $subscriptionData['vvip_game_group_id'] = $payment->group_id;
                    break;
                case 'correctScore':
                    $subscriptionData['correct_score_game_group_id'] = $payment->group_id;
                    break;
                default:
                    Log::error('Invalid group type for manual payment', ['group_type' => $payment->group_type]);
                    throw new \Exception('Invalid group type: ' . $payment->group_type);
            }

            // Check if subscription already exists
            $existingSubscription = Subscription::where('user_id', $payment->user_id)
                ->where(function ($query) use ($payment) {
                    switch ($payment->group_type) {
                        case 'vip':
                            $query->where('vip_game_group_id', $payment->group_id);
                            break;
                        case 'vvip':
                            $query->where('vvip_game_group_id', $payment->group_id);
                            break;
                        case 'correctScore':
                            $query->where('correct_score_game_group_id', $payment->group_id);
                            break;
                    }
                })
                ->first();

            if ($existingSubscription) {
                Log::info('Extending existing subscription', ['subscription_id' => $existingSubscription->id]);
                // Extend existing subscription by 1 month
                $existingSubscription->update([
                    'expires_at' => Carbon::parse($existingSubscription->expires_at)->addMonth(),
                    'amount_paid' => $existingSubscription->amount_paid + $payment->amount
                ]);
            } else {
                Log::info('Creating new subscription', $subscriptionData);
                $newSubscription = Subscription::create($subscriptionData);
                Log::info('Subscription created successfully', ['subscription_id' => $newSubscription->id]);
            }

        } catch (\Exception $e) {
            Log::error('Failed to create subscription from manual payment', [
                'error' => $e->getMessage(),
                'payment_id' => $payment->id,
                'user_id' => $payment->user_id
            ]);
            throw $e;
        }
    }

    public function sendSms(): array
    {
        $response = Http::withHeaders([
            'fayasms-developer' => '43069809.zNc6NqwhQaQJk77R42HTx4bem4cUMgme', // Ensure this is set in your .env file
        ])->post('https://devapi.fayasms.com/messages', [
            'sender' =>'oddsonpoint',
            'message' => 'Please note that a customer has submitted a manual payment. Kindly check and verify',
            'recipients' => ["0596238389"],
        ]);

        Log::info($response);
        if ($response->successful()) {
            return [
                'success' => true,
                'data' => $response->json(),
            ];
        }

        return [
            'success' => false,
            'error' => $response->body(),
        ];
    }

}

