<?php

namespace App\Http\Controllers;

use App\Services\PayWayService;

use Barryvdh\DomPDF\Facade\Pdf;
use Dompdf\Dompdf;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
use Carbon\Carbon;
use Illuminate\Support\Facades\Http;
use App\Models\Admin; // Assuming the ticket data is in the Admin model
use App\Models\payment;
use Illuminate\Support\Facades\DB;

class PaymentController extends Controller
{
    protected $payWayService;

    public function __construct(PayWayService $payWayService)
    {
        $this->payWayService = $payWayService;
    }

    // Show all payments (Admin view) with transaction verification
    public function index(Request $request)
    {
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');

        $query = Payment::query();

        // Filter by date range if provided
        if ($startDate && $endDate) {
            $query->whereBetween('created_at', [$startDate, $endDate]);
        } elseif ($startDate) {
            $query->whereDate('created_at', '>=', $startDate);
        } elseif ($endDate) {
            $query->whereDate('created_at', '<=', $endDate);
        }

        // Fetch local payments
        $payments = $query->latest()->get();
        $sum_total = $payments->sum('total');

        $merchantId = 'lifefootballclub'; // Replace with your actual Merchant ID
        // $publicKey = '481d5528-9c70-420e-a055-fe838d5ffddb'; // Replace with your actual public key
        $publicKey = 'fd8b53ed-7142-4070-9bfd-b11206d1db37'; // Replace with your actual public key

        $transactions = [];
        $approvedTotal = 0;

        // Filtered payments array (only keep records with valid transactions)
        $filteredPayments = collect();
        $totalSoldTickets = 0; // Initialize total sold tickets counter

        foreach ($payments as $payment) {
            $tranId = $payment->tran_id;
            $reqTime = now()->timestamp;

            // Create hash for the request
            $hash = base64_encode(hash_hmac(
                'sha512',
                $reqTime . $merchantId . $tranId,
                $publicKey,
                true
            ));

            // API call to fetch transaction status
            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'User-Agent'   => 'LifeFootballClub/1.0 (Laravel-Payment-System)',
            ])->post('https://checkout.payway.com.kh/api/payment-gateway/v1/payments/check-transaction-2', [
                'req_time'    => $reqTime,
                'merchant_id' => $merchantId,
                'tran_id'     => $tranId,
                'hash'        => $hash,
            ]);

            $apiData = $response->json();

            if ($response->successful() && isset($apiData['data'])) {
                $transactions[$tranId] = $apiData['data'];

                // Only include records with a valid payment_status
                if (isset($apiData['data']['payment_status'])) {
                    $filteredPayments->push($payment);

                    // Add to total sold tickets
                    $totalSoldTickets += $payment->number_chair;

                    // Check if the transaction is approved
                    if ($apiData['data']['payment_status'] === 'APPROVED') {
                        $approvedTotal += $payment->total;
                    }
                }
            }
        }

        return view('admin.check_payment', [
            'payment'           => $filteredPayments,
            'total'             => $approvedTotal,
            'transactions'      => $transactions,
            'sum_total'         => $sum_total,
            'totalSoldTickets'  => $totalSoldTickets, // New data for Total Sold Tickets
        ]);
    }




    /**
     * Pushback endpoint to update payment status.
     */
    public function pushback(Request $request)
    {
        Log::info('Pushback data received', $request->all());

        $validatedData = $request->validate([
            'tran_id' => 'required|string',
            'status'  => 'required|string',
            'hash'    => 'required|string',
        ]);

        $payment = Payment::where('tran_id', $validatedData['tran_id'])->first();
        if (!$payment) {
            return response()->json(['message' => 'Transaction not found'], 404);
        }

        $expectedHash = $this->payWayService->getHash(
            $validatedData['tran_id'] . $validatedData['status']
        );

        if ($validatedData['hash'] !== $expectedHash) {
            return response()->json(['message' => 'Invalid hash'], 400);
        }

        $merchantId = 'lifefootballclub';
        // production
        $publicKey  = 'fd8b53ed-7142-4070-9bfd-b11206d1db37';
        // sandbox
        // $publicKey  = '481d5528-9c70-420e-a055-fe838d5ffddb';
        $reqTime    = time();

        $checkHash = base64_encode(hash_hmac(
            'sha512',
            $reqTime . $merchantId . $validatedData['tran_id'],
            $publicKey,
            true
        ));

        Log::info("Sending pushback verification to ABA", [
            'req_time' => $reqTime,
            'tran_id'  => $validatedData['tran_id'],
            'hash'     => $checkHash,
        ]);

        $response = Http::withHeaders([
            'Content-Type' => 'application/json',
            'User-Agent'   => 'LifeFootballClub/1.0 (Laravel-Payment-System)',
        ])->post('https://checkout.payway.com.kh/api/payment-gateway/v1/payments/check-transaction-2', [
            'req_time'    => $reqTime,
            'merchant_id' => $merchantId,
            'tran_id'     => $validatedData['tran_id'],
            'hash'        => $checkHash,
        ]);

        $apiData = $response->json();

        Log::info("ABA Response for Pushback Verification", [
            'tran_id' => $validatedData['tran_id'],
            'response' => $apiData,
        ]);

        if (!$response->successful() || !isset($apiData['data'])) {
            return response()->json(['message' => 'Failed to verify transaction via API'], 400);
        }

        $transactionStatus = $apiData['data']['status'] ?? null;
        if ($transactionStatus !== 'success') {
            return response()->json(['message' => 'Transaction status is not successful'], 400);
        }

        $payment->is_used = 1;
        $payment->save();

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

    /**
     * This method verifies any pending payments via scheduled jobs.
     */
    public function verifyPendingPayments()
    {
        $merchantId = 'lifefootballclub';
        $publicKey  = 'fd8b53ed-7142-4070-9bfd-b11206d1db37';
        // $publicKey  = '481d5528-9c70-420e-a055-fe838d5ffddb';

        $payments = Payment::where('is_used', 0)->get();

        foreach ($payments as $payment) {
            $reqTime = time();
            $checkHash = base64_encode(hash_hmac(
                'sha512',
                $reqTime . $merchantId . $payment->tran_id,
                $publicKey,
                true
            ));

            Log::info("Scheduled verification request to ABA", [
                'tran_id' => $payment->tran_id,
                'hash'    => $checkHash,
            ]);

            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'User-Agent'   => 'LifeFootballClub/1.0 (Laravel-Payment-System)',
            ])->post('https://checkout.payway.com.kh/api/payment-gateway/v1/payments/check-transaction-2', [
                'req_time'    => $reqTime,
                'merchant_id' => $merchantId,
                'tran_id'     => $payment->tran_id,
                'hash'        => $checkHash,
            ]);

            $apiData = $response->json();

            if ($response->successful() && isset($apiData['data']) && $apiData['data']['status'] === 'success') {
                $payment->is_used = 1;
                $payment->save();
            }
        }
    }

    // Show receipt page for confirmation
    // public function receipt($paymentId)
    // {
    //     $payment = Payment::findOrFail($paymentId);
    //     $ticketData = session('ticket_data', []);

    //     // Ensure 'seat_type_name' is available in the session or use the stored value
    //     if (!isset($ticketData['seat_type_name'])) {
    //         $ticketData['seat_type_name'] = $payment->seat_type_name;
    //     }

    //     if (!$ticketData) {
    //         return redirect()->route('payment.create', ['ticketId' => $payment->ticket_id])
    //             ->with('error', 'Ticket data is missing. Please start over.');
    //     }

    //     $tranId = $payment->tran_id;
    //     $req_time = time();
    //     $merchantId = 'lifefootballclub';
    //     $amount = number_format($ticketData['total'] ?? $payment->total, 2, '.', '');

    //     $payment_option = 'abapay_khqr';
    //     $return_deeplink = base64_encode(json_encode([
    //         "android_scheme" => route("payment.qrcode.byTran", ['tranId' => $payment->tran_id]),
    //         "ios_scheme" => route("payment.qrcode.byTran", ['tranId' => $payment->tran_id])
    //     ]));
    //     $continue_success_url = route('payment.qrcode.byTran', ['tranId' => $payment->tran_id]);

    //     $hash = $this->payWayService->getHash(
    //         $req_time . $merchantId . $tranId . $amount . $payment_option . $continue_success_url . $return_deeplink

    //     );

    //     return view('payments.receipt', compact(
    //         'ticketData',
    //         'payment',
    //         'tranId',
    //         'req_time',
    //         'merchantId',
    //         'amount',
    //         'payment_option',
    //         'hash',
    //         'continue_success_url',
    //         'return_deeplink'
    //     ));
    // }

    public function receipt($paymentId)
    {
        $payment = Payment::findOrFail($paymentId);
        $ticketData = session('ticket_data', []);

        if (!isset($ticketData['seat_type_name'])) {
            $ticketData['seat_type_name'] = $payment->seat_type_name;
        }

        if (!$ticketData) {
            return redirect()->route('payment.create', ['ticketId' => $payment->ticket_id])
                ->with('error', 'Ticket data is missing. Please start over.');
        }

        // ✅ Ensure `$total` value is correctly assigned
        $total = isset($ticketData['total']) ? $ticketData['total'] : $payment->total;

        $tranId = $payment->tran_id;
        $req_time = time();
        $merchantId = 'lifefootballclub';
        $amount = number_format($total, 2, '.', '');  // ✅ Corrected `$amount` formatting

        $payment_option = 'abapay_khqr';
        // $continue_success_url = urlencode(route('payment.qrcode.byTran', ['tranId' => $payment->tran_id]));
        $continue_success_url = route('payment.qrcode.byTran', ['tranId' => $payment->tran_id]);
        $return_deeplink = urlencode(base64_encode(json_encode([
            "android_scheme" => route("payment.qrcode.byTran", ['tranId' => $payment->tran_id]),
            "ios_scheme" => route("payment.qrcode.byTran", ['tranId' => $payment->tran_id])
        ])));

        $hashString = $req_time . $merchantId . $tranId . $amount . $payment_option . $continue_success_url . $return_deeplink;
        $hash = $this->payWayService->getHash($hashString);

        return view('payments.receipt', compact(
            'ticketData',
            'payment',
            'tranId',
            'req_time',
            'merchantId',
            'amount',
            'payment_option',
            'hash',
            'continue_success_url',
            'return_deeplink'
        ));
    }


    // Create a new ticket (Admin view)
    public function create($ticketId)
    {
        $ticket = Admin::with('seatTypes')->findOrFail($ticketId);
        return view('payments.create', ['ticket' => $ticket]);
    }

    // Store payment details and generate tran_id
    // public function store(Request $request)
    // {
    //     $validatedData = $request->validate([
    //         'ticket_id'    => 'required|exists:ticket,id',
    //         'name'         => 'required|string|max:255',
    //         'phone_number' => 'required|string|max:15',
    //         'seat_type_id' => 'required|string',
    //         'number_chair' => 'required|integer|min:1',
    //     ]);

    //     $ticket = Admin::with('seatTypes')->findOrFail($validatedData['ticket_id']);
    //     $seatType = $ticket->seatTypes->firstWhere('id', $validatedData['seat_type_id']);

    //     if (!$seatType) {
    //         return back()->withErrors(['seat_type_id' => 'Invalid seat type selected.']);
    //     }

    //     if ($seatType->available_tickets < $validatedData['number_chair']) {
    //         return back()->withErrors(['number_chair' => 'Not enough seats available for this seat type.']);
    //     }

    //     $total = $validatedData['number_chair'] * $seatType->price;

    //     try {
    //         $payment = DB::transaction(function () use ($validatedData, $seatType, $ticket, $total) { // ✅ Add $ticket here
    //             $payment = Payment::create([
    //                 'ticket_id'    => $validatedData['ticket_id'],
    //                 'name'         => $validatedData['name'],
    //                 'phone_number' => $validatedData['phone_number'],
    //                 'seat_type_id' => $seatType->id,
    //                 'seat_type_name' => $seatType->name,
    //                 'chair_type'   => $seatType->name,
    //                 'number_chair' => $validatedData['number_chair'],
    //                 'total'        => $total,
    //                 'is_used'      => 0,
    //             ]);

    //             $payment->tran_id = date('YmdHis') . '-' . $payment->id;
    //             $payment->save();

    //             // ✅ Decrement available tickets for the selected seat type
    //             $seatType->decrement('available_tickets', $validatedData['number_chair']);

    //             // ✅ Decrement overall inventory in Admin model
    //             $ticket->decrement('available_tickets', $validatedData['number_chair']);

    //             // Add 'seat_type_name' to session for receipt display
    //             $validatedData['seat_type_name'] = $seatType->name;
    //             $validatedData['total'] = $total;

    //             session(['ticket_data' => $validatedData]);
    //             session(['transaction_id' => $payment->tran_id]);

    //             return $payment; // ✅ Ensure the payment object is returned here
    //         });

    //         if (!$payment) {
    //             return back()->with('error', 'Failed to create payment. Please try again.');
    //         }

    //         return redirect()->route('payment.receipt', ['paymentId' => $payment->id]);
    //     } catch (\Exception $e) {
    //         // Log the error for debugging
    //         Log::error('Payment Creation Error:', ['error' => $e->getMessage()]);

    //         return back()->with('error', 'An error occurred while processing your payment. Please try again.');
    //     }
    // }

    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'ticket_id'    => 'required|exists:ticket,id',
            'name'         => 'required|string|max:255',
            'phone_number' => 'required|string|max:15',
            'seat_type_id' => 'required|string',
            'number_chair' => 'required|integer|min:1',
        ]);

        $ticket = Admin::with('seatTypes')->find($validatedData['ticket_id']);

        if (!$ticket) {
            return back()->withErrors(['ticket_id' => 'Selected ticket does not exist.']);
        }

        $seatType = $ticket->seatTypes->where('id', $validatedData['seat_type_id'])->first();

        if (!$seatType) {
            return back()->withErrors(['seat_type_id' => 'Invalid seat type selected.']);
        }

        if ($seatType->available_tickets < $validatedData['number_chair']) {
            return back()->withErrors(['number_chair' => 'Not enough seats available for this seat type.']);
        }

        // ✅ Correct `$total` Calculation
        $total = round($validatedData['number_chair'] * $seatType->price, 2);

        try {
            $payment = DB::transaction(function () use ($validatedData, $seatType, $ticket, $total) {
                $payment = Payment::create([
                    'ticket_id'       => $validatedData['ticket_id'],
                    'name'            => $validatedData['name'],
                    'phone_number'    => $validatedData['phone_number'],
                    'seat_type_id'    => $seatType->id,
                    'seat_type_name'  => $seatType->name,
                    'chair_type'      => $seatType->name,
                    'number_chair'    => $validatedData['number_chair'],
                    'total'           => $total, // ✅ Fixed `$total` being saved here
                    'is_used'         => 0,
                ]);

                $payment->tran_id = date('YmdHis') . '-' . $payment->id;
                $payment->save();

                $seatType->decrement('available_tickets', $validatedData['number_chair']);
                $ticket->decrement('available_tickets', $validatedData['number_chair']);

                // ✅ Correct Session Storage with `$total`
                session([
                    'ticket_data'     => $validatedData,
                    'transaction_id'  => $payment->tran_id,
                    'seat_type_name'  => $seatType->name,
                    'total'           => $total // ✅ Correctly storing `$total`
                ]);

                return $payment;
            });

            return redirect()->route('payment.receipt', ['paymentId' => $payment->id]);
        } catch (\Exception $e) {
            Log::error('Payment Creation Error:', ['error' => $e->getMessage()]);
            return back()->with('error', 'An error occurred while processing your payment. Please try again.');
        }
    }



    // Confirm payment and generate QR code
    public function confirm(Request $request)
    {
        // Retrieve the payment using ticket ID or transaction ID
        $ticketId = $request->input('ticketId');
        $payment = payment::where('ticket_id', $ticketId)->first();

        // Fetch the ticket data
        $ticket = Admin::findOrFail($ticketId);

        // Generate QR data
        $qrData = json_encode([
            'name'         => $payment->name,
            'phone_number' => $payment->phone_number,
            'chair_type'   => $payment->chair_type,
            'number_chair' => $payment->number_chair,
            'total'        => $payment->total,
            'ticket_id'    => $payment->ticket_id,
            'is_used'      => $payment->is_used,
        ]);

        // Optionally, generate a QR code image:
        // $qrCode = base64_encode(QrCode::format('png')->size(300)->generate($qrData));

        // Mark the ticket as used if needed
        if ($payment->is_used == 0) {
            $payment->is_used = 1;
            $payment->save();
        }

        return view('payments.qrcode', compact('payment', 'ticket'))
            ->with('success', 'Payment confirmed and QR code generated!');
    }

    // public function showQrByTranId($tranId)
    // {
    //     // Fetch the payment record by transaction ID.
    //     $payment = payment::where('tran_id', $tranId)->firstOrFail();

    //     // Fetch the ticket details using the ticket_id from the payment record.
    //     $ticket = Admin::findOrFail($payment->ticket_id);

    //     return view('payments.qrcode', compact('payment', 'ticket'));
    // }
    public function showQrByTranId($tranId)
    {
        $payment = Payment::where('tran_id', $tranId)->firstOrFail();
        $ticket = Admin::findOrFail($payment->ticket_id);

        // Generate data to embed in QR code
        $qrData = json_encode([
            'tran_id'       => $payment->tran_id,
            'name'          => $payment->name,
            'phone_number'  => $payment->phone_number,
            'chair_type'    => $payment->chair_type,
            'number_chair'  => $payment->number_chair,
            'total'         => $payment->total,
            'is_used'       => $payment->is_used,
        ]);

        return view('payments.qrcode', compact('payment', 'ticket', 'qrData'));
    }

    public function downloadTicketPDF($paymentId)
    {
        $payment = payment::findOrFail($paymentId);
        $ticket = Admin::findOrFail($payment->ticket_id);

        // Load your Blade view
        $pdf = Pdf::loadView('payments.e_ticket_pdf', compact('payment', 'ticket'))
            ->setOptions([
                // 1) Enable remote images so DomPDF can fetch them
                'isRemoteEnabled' => true,
                // 2) Embed a Khmer-compatible font
                'defaultFont'     => 'KhmerOS',
            ]);

        return $pdf->download('e-ticket.pdf');
    }

    public function validateTicket(Request $request)
    {
        $data = $request->all();
        $payment = Payment::where('tran_id', $data['tran_id'])->first();

        if (!$payment) {
            return response()->json(['message' => 'Invalid Ticket'], 404);
        }

        if ($payment->is_used) {
            return response()->json([
                'message' => 'Ticket has already been used',
                'data' => $payment
            ]);
        }

        $payment->update(['is_used' => 1]);

        return response()->json([
            'message' => 'Ticket validated successfully',
            'data' => $payment
        ]);
    }
}
