<?php

namespace App\Http\Controllers;

use App\Models\Client;
use App\Models\LockerPayment;
use App\Models\LockerRegistration;
use App\Models\LockerRegistrationItem;
use App\Models\MembershipPlan;
use App\Models\Payment;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class PaymentController extends Controller
{
     private function closedClientJsonOrRedirect(Client $client, ?Request $request = null)
    {
        if (!$client->isClosed()) {
            return null;
        }

        $message = 'Account is closed. No further operations are allowed for this client.';
        $request = $request ?? request();

        if ($request->expectsJson()) {
            return response()->json(['success' => false, 'message' => $message], 403);
        }

        return redirect()->back()->with('error', $message);
    }
    
    /**
     * Show payment page for all clients or specific client
     */
    public function index($clientId = null)
    {
        // Get all customers with their locker registrations, items, and payment status for table
        $customers = Client::with(['lockerRegistrations.locker', 'lockerRegistrations.items', 'lockerRegistrations.payments'])
            ->orderBy('name')
            ->get();

        // If specific client is selected
        if ($clientId) {
            $client = Client::with([
                'lockerRegistrations.locker',
                'lockerRegistrations.membershipPlan',
                'membershipPlan',
                'customerMembers'
            ])->findOrFail($clientId);

            // Get pending payments using Payment model
            $pendingPayments = \App\Models\Payment::whereHas('registration', function($query) use ($clientId) {
                    $query->where('client_id', $clientId);
                })
                ->where('status', 'pending')
                ->with(['registration.locker', 'registration.membershipPlan'])
                ->get();

            // Get payment history
            $paymentHistory = \App\Models\Payment::whereHas('registration', function($query) use ($clientId) {
                    $query->where('client_id', $clientId);
                })
                ->whereIn('status', ['paid'])
                ->with(['registration.locker', 'registration.membershipPlan'])
                ->orderBy('payment_date', 'desc')
                ->get();

            // Calculate totals
            $totalPending = $pendingPayments->sum('total_amount');
            $totalPaid = $paymentHistory->sum('paid_amount');

            return view('payment.index', compact(
                'customers',
                'client',
                'pendingPayments',
                'paymentHistory',
                'totalPending',
                'totalPaid'
            ));
        }

        // Show all customers view
        return view('payment.index', compact('customers'));
    }

    /**
     * Show payment creation form for client
     */
    public function create($clientId)
    {
        $client = Client::with([
            'lockerRegistrations.locker',
            'lockerRegistrations.items',
            'lockerRegistrations.membershipPlan',
            'membershipPlan',
            'customerMembers'
        ])->findOrFail($clientId);

        return view('payment.create-edit', compact('client'));
    }

    /**
     * Show payment details for client
     */
    public function show($clientId)
    {
        $client = Client::with([
            'lockerRegistrations.locker',
            'lockerRegistrations.items',
            'lockerRegistrations.membershipPlan',
            'lockerRegistrations.payments'
        ])->findOrFail($clientId);

        return view('payment.show', compact('client'));
    }

    /**
     * Initiate payment from invoice - creates pending payment entry
     */
    public function initiatePayment(Request $request, $clientId)
    {
        $validator = Validator::make($request->all(), [
            'invoice_id' => 'required|exists:invoices,id',
            'locker_registration_id' => 'required|exists:locker_registrations,id',
            'payment_type' => 'required|in:registration_fee,rent,deposit,renewal,penalty,maintenance,create,add,change',
            'amount' => 'required|numeric|min:0.01',
            'payment_date' => 'required|date',
            'notes' => 'nullable|string|max:500',
        ]);

        if ($validator->fails()) {
            return redirect()->back()->withErrors($validator)->withInput();
        }

        try {
            DB::beginTransaction();

            $lockerRegistration = LockerRegistration::findOrFail($request->locker_registration_id);

            // Find invoice first
            $invoice = \App\Models\Invoice::where('id', $request->invoice_id)->first();
            
            // Create invoice if doesn't exist
            if (!$invoice) {
                // echo 'create'; exit;
                try {
                    $invoice = \App\Models\Invoice::create([
                        'invoice_number' => \App\Models\Invoice::generateInvoiceNumber(),
                        'client_id' => $lockerRegistration->client_id,
                        'registration_id' => $lockerRegistration->id,
                        'invoice_date' => now(),
                        'subtotal' => $request->amount,
                        'tax_amount' => 0,
                        'stamping_fee' => 0,
                        'key_deposit' => 0,
                        'insurance_charges' => 0,
                        'discount_amount' => 0,
                        'total_amount' => $request->amount,
                        'paid_amount' => 0,
                        'balance_amount' => $request->amount,
                        'status' => 'pending', // Changed from 'draft' to 'pending' to avoid enum issue
                        'payment_mode' => $lockerRegistration->payment_mode,
                        'payment_type' => 'create',
                        'client_name' => $lockerRegistration->client->name,
                        'client_phone' => $lockerRegistration->client->phone,
                        'client_address' => $lockerRegistration->client->address ?? '',
                        'membership_plan' => $lockerRegistration->membershipPlan->name ?? '',
                        'contract_start_date' => $lockerRegistration->contract_start_date,
                        'contract_end_date' => $lockerRegistration->contract_end_date,
                        'notes' => 'Payment initiated',
                    ]);
                    
                    // Verify invoice was created successfully
                    if (!$invoice || !$invoice->id) {
                        throw new \Exception('Invoice creation failed - no ID returned');
                    }
                } catch (\Exception $e) {
                    // If invoice creation fails, create payment without invoice_id
                    $payment = \App\Models\Payment::create([
                        'invoice_id' => null,
                        'registration_id' => $request->locker_registration_id,
                        'total_amount' => $request->amount,
                        'paid_amount' => $request->amount,
                        'balance_amount' => 0,
                        'payment_mode' => 'cash',
                        'payment_date' => $request->payment_date,
                        'status' => 'paid',
                        'notes' => 'paid - invoice creation failed: ' . $e->getMessage(),
                    ]);
                    
                    DB::commit();
                    return redirect()->route('invoices.index')->with('success', 'Payment initiated successfully!');
                }
            } else {
                
                // Double check existing invoice actually exists in database
                $verifyInvoice = \App\Models\Invoice::find($invoice->id);
                if (!$verifyInvoice) {
                    // echo 'create else null'; exit;
                    $invoice = null; // Invoice was deleted, clear reference
                }
            }

            
            
            // // Create paid payment record with invoice_id
            $payment = \App\Models\Payment::create([
                'invoice_id' => $invoice ? $invoice->id : null,
                'registration_id' => $request->locker_registration_id,
                'total_amount' => $request->amount,
                'paid_amount' => $request->amount,
                'balance_amount' => 0,
                'payment_mode' => 'cash', // Default payment mode
                'payment_date' => $request->payment_date,
                'status' => 'paid',
                'notes' => 'paid',
            ]);

            // Update invoice status to paid
            if ($invoice) {
                // echo $invoice;
                // echo 'invoice paid'; exit;
                $invoice->update([
                    'status' => 'paid',
                    'paid_amount' => $request->amount,
                    'balance_amount' => 0,
                ]);
            }
// echo 'end'; exit;
            DB::commit();

            return redirect()->route('invoices.index')
                ->with('success', 'Payment processed successfully!');

        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()->with('error', 'Failed to initiate payment: ' . $e->getMessage());
        }
    }

    /**
     * Process payment for locker registration
     */
    public function processPayment(Request $request, $clientId)
    {
        $validator = Validator::make($request->all(), [
            'payment_method' => 'required|in:cash,card,debit_card,bank_transfer,online,cheque,fpx',
            'payment_type' => 'required|in:registration_fee,rent,deposit,renewal,penalty,maintenance,change',
            'amount' => 'required|numeric|min:0.01',
            'payment_date' => 'required|date',
            'notes' => 'nullable|string|max:500',
            'locker_registration_id' => 'required|exists:locker_registrations,id',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        try {
            DB::beginTransaction();

            $client = Client::findOrFail($clientId);
            $lockerRegistration = LockerRegistration::findOrFail($request->locker_registration_id);

            // Create payment record
            $payment = \App\Models\Payment::create([
                'registration_id' => $request->locker_registration_id,
                'total_amount' => $request->amount,
                'paid_amount' => $request->amount,
                'balance_amount' => 0,
                'payment_mode' => $request->payment_method ?? 'cash',
                'payment_date' => $request->payment_date,
                'status' => 'paid',
                'notes' => $request->notes,
            ]);

            // Update locker registration status to Active if payment is for registration
            if ($request->payment_type === 'registration_fee' || $request->payment_type === 'rent') {
                $lockerRegistration->update(['status' => 'Active']);

                // Update locker status to Active
                $lockerRegistration->locker()->update(['status' => 'Occupied']);
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Payment processed successfully',
                'payment' => $payment->load(['lockerRegistration.locker', 'membershipPlan'])
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Error processing payment: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get pending payments for a client
     */
    public function getPendingPayments($clientId)
    {
        $pendingPayments = LockerPayment::where('client_id', $clientId)
            ->where('payment_status', 'pending')
            ->with(['lockerRegistration.locker', 'membershipPlan'])
            ->get();

        return response()->json([
            'success' => true,
            'payments' => $pendingPayments
        ]);
    }

    /**
     * Create pending payment for locker registration
     */
    public function createPendingPayment(Request $request, $clientId)
    {
        $validator = Validator::make($request->all(), [
            'locker_registration_id' => 'required|exists:locker_registrations,id',
            'amount' => 'required|numeric|min:0.01',
            'payment_type' => 'required|in:registration_fee,rent,deposit,renewal,penalty,maintenance,change',
            'due_date' => 'required|date|after:today',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        try {
            $lockerRegistration = LockerRegistration::findOrFail($request->locker_registration_id);

            $payment = LockerPayment::create([
                'client_id' => $clientId,
                'locker_registration_id' => $request->locker_registration_id,
                'membership_plan_id' => $lockerRegistration->membership_plan_id,
                'amount' => $request->amount,
                'payment_type' => $request->payment_type,
                'payment_method' => 'pending',
                'payment_status' => 'pending',
                'due_date' => $request->due_date,
                'invoice_number' => 'INV' . date('Y') . str_pad($clientId, 6, '0', STR_PAD_LEFT),
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Pending payment created successfully',
                'payment' => $payment->load(['lockerRegistration.locker', 'membershipPlan'])
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error creating pending payment: ' . $e->getMessage()
            ], 500);
        }
    }



    // public function processRenewal(Request $request, $clientId, $registrationId)
    // {
    //     $validator = Validator::make($request->all(), [
    //         'locker_registration_id' => 'required|exists:locker_registrations,id',
    //         'membership_plan_id' => 'required|exists:membership_plans,id',
    //         'payment_method' => 'required|in:cash,card,bank_transfer,online,cheque',
    //         'payment_date' => 'required|date',
    //         'contract_start_date' => 'required|date',
    //         'contract_end_date' => 'required|date|after_or_equal:contract_start_date',
    //         'amount' => 'required|numeric|min:0.01',
    //         'tax_amount' => 'required|numeric|min:0',
    //         'payment_type' => 'required|in:renewal',
    //     ]);

    //     if ($validator->fails()) {
    //         return redirect()->back()->withErrors($validator)->withInput();
    //     }

    //     DB::beginTransaction();

    //     try {
    //         $client = Client::findOrFail($clientId);
    //         $oldRegistration = LockerRegistration::with(['items', 'locker'])->findOrFail($registrationId);

    //         if ((int) $oldRegistration->client_id !== (int) $clientId) {
    //             abort(404);
    //         }

    //         $oldRegistration->update(['status' => 'Expired']);
    //         foreach ($oldRegistration->items as $item) {
    //             $item->update(['status' => 'expired']);
    //         }

    //         $paymentMethod = $request->payment_method;
    //         if ($paymentMethod === 'debit_card') {
    //             $paymentMethod = 'card';
    //         } elseif ($paymentMethod === 'fpx') {
    //             $paymentMethod = 'online';
    //         }

    //         $newRegistration = LockerRegistration::create([
    //             'client_id' => $client->id,
    //             'auth_count' => $oldRegistration->auth_count,
    //             'locker_password' => $oldRegistration->locker_password,
    //             'registration_date' => now()->toDateString(),
    //             'payment_terms' => $request->membership_plan_id,
    //             'commission_used' => $oldRegistration->commission_used,
    //             'safebox_count' => $oldRegistration->safebox_count,
    //             'contract_start_date' => $request->contract_start_date,
    //             'contract_end_date' => $request->contract_end_date,
    //             'stamping_fee' => $oldRegistration->stamping_fee,
    //             'key_deposit' => $oldRegistration->key_deposit,
    //             'insurance_charges' => $oldRegistration->insurance_charges,
    //             'discount_amount' => $oldRegistration->discount_amount,
    //             'tax_amount' => $request->tax_amount,
    //             'referred_member_by' => $oldRegistration->referred_member_by,
    //             'referred_commission' => $oldRegistration->referred_commission,
    //             'status' => 'Active',
    //         ]);

    //         if ($oldRegistration->items->count() > 0) {
    //             foreach ($oldRegistration->items as $item) {
    //                 LockerRegistrationItem::create([
    //                     'registration_id' => $newRegistration->id,
    //                     'locker_id' => $item->locker_id,
    //                     'locker_number' => $item->locker_number,
    //                     'size' => $item->size,
    //                     'type' => $item->type,
    //                     'locker_group' => $item->locker_group,
    //                     'locker_position' => $item->locker_position,
    //                     'start_date' => $request->contract_start_date,
    //                     'end_date' => $request->contract_end_date,
    //                     'amount' => $item->amount,
    //                     'status' => 'active',
    //                     'added_at' => now(),
    //                 ]);
    //             }
    //         } elseif ($oldRegistration->locker) {
    //             LockerRegistrationItem::create([
    //                 'registration_id' => $newRegistration->id,
    //                 'locker_id' => $oldRegistration->locker->id,
    //                 'locker_number' => $oldRegistration->locker->locker_number,
    //                 'size' => $oldRegistration->locker->locker_size,
    //                 'type' => $oldRegistration->locker->locker_type,
    //                 'locker_group' => $oldRegistration->locker->locker_group ?? null,
    //                 'locker_position' => $oldRegistration->locker->locker_position ?? null,
    //                 'start_date' => $request->contract_start_date,
    //                 'end_date' => $request->contract_end_date,
    //                 'amount' => $oldRegistration->locker_amount ?? 0,
    //                 'status' => 'active',
    //                 'added_at' => now(),
    //             ]);
    //         }

    //         Payment::create([
    //             'registration_id' => $newRegistration->id,
    //             'payment_mode' => $paymentMethod,
    //             'total_amount' => $request->amount,
    //             'paid_amount' => $request->amount,
    //             'balance_amount' => 0,
    //             'payment_date' => $request->payment_date,
    //             'status' => 'paid',
    //             'transaction_id' => 'TXN' . time() . rand(1000, 9999),
    //             'notes' => $request->notes ?? null,
    //         ]);

    //         DB::commit();

    //         return redirect()->route('customers.show', $client->id)
    //             ->with('success', 'Renewal completed successfully and payment saved.');
    //     } catch (\Exception $e) {
    //         DB::rollBack();
    //         \Log::error('Renewal processing failed', [
    //             'client_id' => $clientId,
    //             'registration_id' => $registrationId,
    //             'request' => $request->all(),
    //             'exception' => $e,
    //         ]);
    //         $errorMessage = $e->getMessage() ?: 'An unexpected error occurred. Please try again.';
    //         return redirect()->back()->with('error', 'Unable to process renewal: ' . $errorMessage);
    //     }
    // }

    public function processRenewal(Request $request, $clientId, $registrationId)
    {
        $validator = Validator::make($request->all(), [
            'locker_registration_id' => 'required|exists:locker_registrations,id',
            'membership_plan_id' => 'required|exists:membership_plans,id',
            'payment_method' => 'required|in:cash,card,bank_transfer,online,cheque,debit_card,fpx',
            'payment_date' => 'required|date',
            'contract_start_date' => 'required|date',
            'contract_end_date' => 'required|date|after_or_equal:contract_start_date',
            'amount' => 'required|numeric|min:0.01',
            'tax_amount' => 'required|numeric|min:0',
            'payment_type' => 'required|in:renewal',
        ]);

        if ($validator->fails()) {
            return redirect()->back()->withErrors($validator)->withInput();
        }

        DB::beginTransaction();

        try {
            // 1. Fetch data
            $client = Client::findOrFail($clientId);
            $oldRegistration = LockerRegistration::with(['items', 'locker'])->findOrFail($registrationId);

            // Safety check
            if ((int)$oldRegistration->client_id !== (int)$clientId) {
                abort(404);
            }

            if ($oldRegistration->status !== 'Active') {
                throw new \Exception('Only active registrations can be renewed');
            }

            // Normalize payment method
            $paymentMethod = $request->payment_method;
            if ($paymentMethod === 'debit_card') {
                $paymentMethod = 'card';
            } elseif ($paymentMethod === 'fpx') {
                $paymentMethod = 'online';
            }

            // 2. CREATE NEW REGISTRATION
            $newRegistration = LockerRegistration::create([
                'client_id' => $client->id,
                'auth_count' => $oldRegistration->auth_count,
                'locker_password' => $oldRegistration->locker_password,
                'registration_date' => now()->toDateString(),
                'payment_terms' => $request->membership_plan_id,
                'commission_used' => $oldRegistration->commission_used,
                'safebox_count' => $oldRegistration->safebox_count,
                'contract_start_date' => $request->contract_start_date,
                'contract_end_date' => $request->contract_end_date,
                'stamping_fee' => $oldRegistration->stamping_fee,
                'key_deposit' => $oldRegistration->key_deposit,
                'insurance_charges' => $oldRegistration->insurance_charges,
                'discount_amount' => $oldRegistration->discount_amount,
                'tax_amount' => $request->tax_amount,
                'referred_member_by' => $oldRegistration->referred_member_by,
                'referred_commission' => $oldRegistration->referred_commission,
                'status' => 'Active',
            ]);

            // Load membershipPlan relationship
            $newRegistration->load('membershipPlan');

            // 3. CREATE ITEMS from request lockers
            $lockers = $request->input('lockers', []);
            if (count($lockers) > 0) {
                foreach ($lockers as $locker) {
                    LockerRegistrationItem::create([
                        'registration_id' => $newRegistration->id,
                        'locker_id' => $locker['locker_id'],
                        'locker_number' => $locker['locker_number'],
                        'size' => $locker['size'],
                        'type' => $locker['type'],
                        'locker_group' => $locker['locker_group'],
                        'locker_position' => $locker['locker_position'],
                        'start_date' => $request->contract_start_date,
                        'end_date' => $request->contract_end_date,
                        'amount' => $locker['amount'],
                        'status' => 'active',
                        'added_at' => now(),
                    ]);
                }
            } 
            // elseif ($oldRegistration->locker) {
            //     LockerRegistrationItem::create([
            //         'registration_id' => $newRegistration->id,
            //         'locker_id' => $oldRegistration->locker->id,
            //         'locker_number' => $oldRegistration->locker->locker_number,
            //         'size' => $oldRegistration->locker->locker_size,
            //         'type' => $oldRegistration->locker->locker_type,
            //         'locker_group' => $oldRegistration->locker->locker_group ?? null,
            //         'locker_position' => $oldRegistration->locker->locker_position ?? null,
            //         'start_date' => $request->contract_start_date,
            //         'end_date' => $request->contract_end_date,
            //         'amount' => $oldRegistration->locker_amount ?? 0,
            //         'status' => 'active',
            //         'added_at' => now(),
            //     ]);
            // }
            $taxAmount = (float) ($request->tax_amount ?? 0);
            
            // Calculate payment total
            $paymentTotal = (float) ($request->amount ?? 0) 
                          + (float) ($request->stamping_fee ?? 0)
                          + (float) ($request->key_deposit ?? 0)
                          + (float) ($request->insurance_charges ?? 0)
                          + $taxAmount
                          - (float) ($request->discount_amount ?? 0);
            
            $firstLocker = $lockers[0] ?? [];

            $finalAmount = (float) ($request->final_amount ?? 0);

            // If final_amount is provided, use it; otherwise use the calculated paymentTotal
            if ($finalAmount > 0) {
                $paymentTotal = $finalAmount;
            }

            // Create invoice with pending status only (no payment yet)
            $invoice = \App\Models\Invoice::create([
                'client_id' => $client->id,
                'registration_id' => $newRegistration->id,
                'invoice_number' => \App\Models\Invoice::generateInvoiceNumber(),
                'invoice_date' => now(),
                'due_date' => now()->addDays(30),
                'tax_amount' => $taxAmount,
                'stamping_fee' => $request->stamping_fee ?? 0,
                'key_deposit' => $request->key_deposit ?? 0,
                'insurance_charges' => $request->insurance_charges ?? 0,
                'discount_amount' => $request->discount_amount ?? 0,
                'total_amount' => $paymentTotal,
                'paid_amount' => 0,
                'balance_amount' => $paymentTotal,
                'payment_mode' => $request->payment_mode ?? 'cash',
                'status' => 'pending',
                'payment_type' => 'renewal',
                'client_name' => $client->name,
                'client_phone' => $client->phone,
                'client_address' => $client->address,
                'membership_plan' => $newRegistration->membershipPlan->name ?? '',
                'contract_start_date' => $request->contract_start_date,
                'contract_end_date' => $request->contract_end_date,
                'notes' => 'renewal',
                'account_type_id' => $oldRegistration->account_type_id,
                'email' => $client->email ?? '',
                'safebox' => $client->safebox ?? '',
                'postal_code' => $client->postal_code ?? 0,
                'city' => $client->city ?? '',
                'state' => $client->state ?? '',
                'country' => $client->country ?? '',
                'registration_number' => $client->registration_number ?? '',
                'tax_type' => $request->tax_type ?? 'gst',
                'safebox_count' => $request->safebox_count ?? 1,
                'payment_terms' => $request->payment_terms ?? 30,
                'referred_member_by' => $request->referred_member_by,
                'referred_commission' => $request->referred_commission ?? 0,
                'commission_used' => $request->commission_used ?? 0,
                'registration_date' => $oldRegistration->registration_date ?? now(),
                'locker_id' => $firstLocker['locker_id'] ?? 0,
                'locker_number' => collect($lockers)->pluck('locker_number')->implode(', '),
                'size' => $firstLocker['size'] ?? '',
                'type' => $firstLocker['type'] ?? '',
                'locker_group' => $firstLocker['locker_group'] ?? '',
                'locker_position' => $firstLocker['locker_position'] ?? '',
                'start_date' => $request->start_date ?? now(),
                'end_date' => $request->end_date ?? now()->addYear(),
                'amount' => $request->amount ?? 0,
            ]);

        

            // ✅ 4. UPDATE OLD REGISTRATION LAST (IMPORTANT FIX)
            $oldRegistration->update(['status' => 'Expired']);

            foreach ($oldRegistration->items as $item) {
                $item->update(['status' => 'expired']);
            }

            DB::commit();

            return redirect()->route('customers.show', $client->id)
                ->with('success', 'Renewal completed successfully. Invoice created with pending status.');
        } catch (\Exception $e) {
            DB::rollBack();

            \Log::error('Renewal processing failed', [
                'client_id' => $clientId,
                'registration_id' => $registrationId,
                'request' => $request->all(),
                'exception' => $e,
            ]);

            return redirect()->back()->with(
                'error',
                'Unable to process renewal: ' . ($e->getMessage() ?: 'Unexpected error')
            );
        }
    }
}
