<?php

namespace App\Http\Controllers;

use App\Models\Client;
use App\Models\ClientLocation;
use App\Models\ClientContract;
use App\Models\ClientContact;
use App\Models\Country;
use App\Models\CustomerMember;
use App\Models\Status;
use App\Models\Locker;
use App\Models\LockerGroup;
use App\Models\LockerRegistration;
use App\Models\LockerRegistrationItem;
use App\Models\MembershipPlan;
use App\Models\ReferredClient;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;

class ClientController extends Controller
{
    // public function index(Request $request)
    // {
    //     $query = Client::with(['status', 'customerMembers', 'accountType', 'lockerRegistrations'])
    //         ->byTenant();

    //     if ($request->filled('search')) {
    //         $search = $request->search;
    //         $query->where('name', 'like', "%{$search}%");
    //     }

    //     if ($request->filled('status')) {
    //         $query->whereHas('status', function ($q) use ($request) {
    //             $q->where('name', $request->status);
    //         });
    //     }

    //     $clients = $query->orderBy('id', 'desc')->paginate(20);

    //     return view('clients.index', compact('clients'));
    // }

    public function index(Request $request)
    {
        $query = Client::with([
            'status',
            'customerMembers',
            'accountType',

            // LOAD ONLY ACTIVE REGISTRATION
            'lockerRegistrations' => function ($q) {
                $q->where('status', 'Active')
                    ->latest(); // latest renewal
            }
        ])->byTenant();

        if ($request->filled('search')) {
            $query->where('name', 'like', "%{$request->search}%");
        }

        if ($request->filled('status')) {
            $query->whereHas('status', function ($q) use ($request) {
                $q->where('name', $request->status);
            });
        }

        $clients = $query->orderBy('id', 'desc')->paginate(20);

        return view('clients.index', compact('clients'));
    }

    public function referralDetails(Request $request)
    {
        $query = CustomerMember::with(['client', 'statusRelation', 'referralRegistrations'])
            ->withSum('referralRegistrations as referred_commission', 'referred_commission')
            ->withSum('referralRegistrations as commission_used', 'commission_used');

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('mobile', 'like', "%{$search}%")
                    ->orWhere('proof_type', 'like', "%{$search}%")
                    ->orWhereHas('client', function ($clientQuery) use ($search) {
                        $clientQuery->where('phone', 'like', "%{$search}%")
                            ->orWhere('name', 'like', "%{$search}%");
                    })
                    ->orWhereHas('referralRegistrations', function ($registrationQuery) use ($search) {
                        $registrationQuery->where('referred_member_by', 'like', "%{$search}%");
                    });
            });
        }

        if ($request->filled('status')) {
            if ($request->status === 'active') {
                $query->where('is_active', true);
            } elseif ($request->status === 'inactive') {
                $query->where('is_active', false);
            } elseif ($request->status === 'blocked') {
                $query->whereHas('statusRelation', function ($statusQuery) {
                    $statusQuery->where('name', 'blocked');
                });
            }
        }

        $summaryQuery = clone $query;
        $summary = [
            'total_members' => $summaryQuery->count(),
            'total_referral_amount' => (clone $summaryQuery)->get()->sum('referred_commission'),
            'total_commission_used' => (clone $summaryQuery)->get()->sum('commission_used'),
            // 'total_amount' =>
            'total_balance' => (clone $summaryQuery)->get()->sum('referred_commission') - (clone $summaryQuery)->get()->sum('commission_used'),
        ];

        $records = $query->orderBy('name')->paginate(20)->withQueryString();

        $status = $request->status;
        $search = $request->search;

        return view('clients.referral-details', compact('records', 'summary', 'status', 'search'));
    }

    public function create()
    {
        $statuses = \App\Models\Status::all();
        $lockers = \App\Models\Locker::all();
        $account_type = \App\Models\AccountType::where('status', 1)->get();
        $membership_plan = MembershipPlan::select('id', 'name', 'duration_days', 'duration_months', 'price')->where('status', 1)->get();
        $locker_groups = LockerGroup::select('id', 'name')->get();
        $countries = Country::select('id', 'name')->where('status', 1)->get();

        return view('clients.create-edit', compact('statuses', 'lockers', 'account_type', 'membership_plan', 'locker_groups', 'countries'));
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'account_type' => 'required|integer|exists:account_types,id',
            'auth_count' => 'required|numeric',
            'name' => 'required|string|max:255',
            'phone' => 'required|digits_between:10,11',
            'email' => 'required|email',
            'landline' => 'nullable|string|max:20',
            'address' => 'required|string|max:500',
            'country' => 'required|string|max:100',
            'state' => 'required|string|max:100',
            'city' => 'required|string|max:100',
            'postal_code' => 'required|string|max:10',
            'registration_number' => 'nullable|string|max:30',
            'tax_type' => 'required|string|max:50',
            'tax_amount' => 'nullable|numeric|min:0',
            'stamping_fee' => 'required|numeric',
            'key_deposit' => 'required|numeric',
            'insurance_charges' => 'required|numeric',
            'discount_amount' => 'required|numeric',
            'final_amount' => 'nullable|numeric|min:0',
            'payment_mode' => 'required|string|max:50',
            'safebox_count' => 'required|numeric',
            'selected_lockers_data' => 'required|string|json',
            'payment_terms' => 'required|string|max:50',
            'contract_start_date' => 'required|date|after_or_equal:today',
            'contract_end_date' => 'required|date|after_or_equal:contract_start_date',
            'referred_member_by' => 'nullable|string|max:50',
            'referred_commission' => 'nullable|numeric',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            DB::beginTransaction();

            // Decode locker data
            $lockersData = json_decode($request->selected_lockers_data, true);

            if (!$lockersData || !is_array($lockersData)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Invalid locker data format'
                ], 422);
            }

            // Validate each locker
            foreach ($lockersData as $locker) {
                if (!isset($locker['id'], $locker['number'], $locker['size'], $locker['type'])) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Invalid locker structure'
                    ], 422);
                }

                $lockerRecord = \App\Models\Locker::find($locker['id']);

                if (!$lockerRecord || $lockerRecord->status !== 'Available') {
                    return response()->json([
                        'success' => false,
                        'message' => "Locker {$locker['number']} is not available"
                    ], 422);
                }
            }

            // Create Client
            $client = \App\Models\Client::create([
                'name' => $request->name,
                'phone' => $request->phone,
                'email' => $request->email,
                'landline' => $request->landline,
                'address' => $request->address,
                'country' => $request->country,
                'state' => $request->state,
                'city' => $request->city,
                'postal_code' => $request->postal_code,
                'account_type_id' => $request->account_type,
                'tax_type' => $request->tax_type,
                'registration_number' => $request->registration_number,
                'auth_count' => $request->auth_count,
                'is_appointment' => '1',
                'status_id' => '1',
                'tenant_id' => config('app.default_tenant_id', 1),
            ]);

            // Create ONE Registration
            $registration = \App\Models\LockerRegistration::create([
                'client_id' => $client->id,
                'auth_count' => $request->auth_count,
                'locker_password' => '123456',
                'registration_date' => now()->toDateString(),
                'safebox_count' => $request->safebox_count,
                'contract_start_date' => $request->contract_start_date,
                'contract_end_date' => $request->contract_end_date,
                'payment_terms' => $request->payment_terms,
                'stamping_fee' => $request->stamping_fee,
                'key_deposit' => $request->key_deposit,
                'insurance_charges' => $request->insurance_charges,
                'discount_amount' => $request->discount_amount,
                'tax_amount' => $request->tax_amount,
                'referred_member_by' => $request->referred_member_by,
                'referred_commission' => $request->referred_commission,
                'status' => 'Active',
            ]);

            // Insert Locker Items
            $totalAmount = 0;

            foreach ($lockersData as $locker) {

                \App\Models\LockerRegistrationItem::create([
                    'registration_id' => $registration->id,
                    'locker_id' => $locker['id'],

                    'locker_number' => $locker['number'],
                    'size' => $locker['size'],
                    'type' => $locker['type'],
                    'locker_group' => $locker['locker_group'] ?? null,
                    'locker_position' => $locker['locker_position'] ?? null,

                    'start_date' => $request->contract_start_date,
                    'end_date' => $request->contract_end_date,

                    'amount' => $locker['amount'] ?? 0,

                    'status' => 'active',
                    'added_at' => now(),
                ]);

                // Update locker status
                \App\Models\Locker::where('id', $locker['id'])
                    ->update(['status' => 'Occupied']);

                // Calculate total
                $totalAmount += $locker['amount'] ?? 0;
            }

            $taxAmount = (float) ($request->tax_amount ?? 0);
            $finalAmount = (float) ($request->final_amount ?? 0);
            $paymentTotal = $finalAmount > 0 ? $finalAmount : ($totalAmount + $taxAmount);

            // Create Invoice
            \App\Models\Invoice::create([
                'client_id' => $client->id,
                'registration_id' => $registration->id,
                'invoice_number' => \App\Models\Invoice::generateInvoiceNumber(),
                'invoice_date' => now(),
                'due_date' => now()->addDays(30),
                'tax_amount' => $taxAmount,
                'stamping_fee' => $request->stamping_fee,
                'key_deposit' => $request->key_deposit,
                'insurance_charges' => $request->insurance_charges,
                'discount_amount' => $request->discount_amount,
                'total_amount' => $paymentTotal,
                'paid_amount' => 0,
                'balance_amount' => $paymentTotal,
                'payment_mode' => $request->payment_mode ?? 'cash',
                'status' => 'pending',
                'payment_type' => $request->payment_type ?? 'create',
                'client_name' => $client->name,
                'client_phone' => $client->phone,
                'client_address' => $client->address,
                'membership_plan' => $registration->membershipPlan->name ?? '',
                'contract_start_date' => $request->contract_start_date,
                'contract_end_date' => $request->contract_end_date,
                'notes' => 'create',
                // New database columns
                'account_type_id' => $request->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' => $registration->registration_date ?? now(),
                'locker_id' => $firstLocker['id'] ?? 0,
                'locker_number' => collect($lockersData)->pluck('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,
            ]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Locker registered successfully',
                'redirect' => route('customers.members', ['client' => $client->id])
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => 'Error: ' . $e->getMessage()
            ], 500);
        }
    }

    // public function show($id)
    // {
    //     $client = Client::with([
    //         'lockerRegistrations' => function ($query) {
    //             $query->where('status', 'Active');
    //         },
    //         'lockerRegistrations.locker',
    //         'lockerRegistrations.membershipPlan',
    //         'lockerRegistrations.items',
    //         'lockerRegistrations.payments',
    //         'customerMembers',
    //     ])
    //         ->findOrFail($id);

    //     return view('clients.show', compact('client'));
    // }

    public function show($id)
    {
        $client = Client::with([
            'lockerRegistrations' => function ($query) {
                $query->where('status', 'Active');
            },
            'lockerRegistrations.locker',
            'lockerRegistrations.membershipPlan',
            'lockerRegistrations.items',
            'lockerRegistrations.payments',
            'customerMembers',
        ])
            ->findOrFail($id);

        return view('clients.show', compact('client'));
    }

    public function renewal($clientId, $registrationId)
    {
        $client = Client::findOrFail($clientId);

        $registration = LockerRegistration::with(['locker', 'membershipPlan', 'items' => function ($query) {
            $query->where('status', 'active');
        }, 'items.locker'])
            ->where('id', $registrationId)
            ->where('status', 'Active')
            ->where('client_id', $clientId)
            ->firstOrFail();

        $membership_plan = MembershipPlan::select('id', 'name', 'duration_days', 'duration_months', 'price')
            ->where('status', 1)
            ->orderBy('sort_order')
            ->get();

        return view('clients.renewal', compact('client', 'registration', 'membership_plan'));
    }

    public function createLocker($id)
    {
        $client = Client::byTenant()->findOrFail($id);
        $membership_plan = MembershipPlan::select('id', 'name', 'duration_days', 'duration_months', 'price')
            ->where('status', 1)
            ->get();
        $locker_groups = LockerGroup::select('id', 'name')->get();

        return view('clients.add-locker', compact('client', 'membership_plan', 'locker_groups'));
    }

    public function changeLocker($id, Request $request)
    {
        $client = Client::byTenant()->with([
            'lockerRegistrations' => function ($query) {
                $query->where('status', 'Active')->latest();
            },
            'lockerRegistrations.items' => function ($query) {
                $query->where('status', 'active');
            },
            'lockerRegistrations.items.locker',
            'lockerRegistrations.payments' => function ($query) {
                $query->latest();
            }
        ])->findOrFail($id);
        $membership_plan = MembershipPlan::select('id', 'name', 'duration_days', 'duration_months', 'price')
            ->where('status', 1)
            ->get();
        $locker_groups = LockerGroup::select('id', 'name')->get();

        $taxAmount = (float) ($request->tax_amount ?? 0);
        $finalAmount = (float) ($request->final_amount ?? 0);
        $totalAmount = 0; // Initialize total amount
        $paymentTotal = $finalAmount > 0 ? $finalAmount : ($totalAmount + $taxAmount);

        // Extract locker data from client's existing registrations
        $lockersData = [];
        $firstLocker = null;
        $registration = null;
        if ($client->lockerRegistrations->isNotEmpty()) {
            $registration = $client->lockerRegistrations->first();
            foreach ($registration->items as $item) {
                if ($item->locker) {
                    $lockerData = [
                        'id' => $item->locker->id,
                        'number' => $item->locker_number,
                        'size' => $item->size,
                        'type' => $item->type,
                        'locker_group' => $item->locker_group,
                        'locker_position' => $item->locker_position,
                    ];
                    $lockersData[] = $lockerData;
                    if ($firstLocker === null) {
                        $firstLocker = $lockerData;
                    }
                }
            }
        }

        $invoicePreview = [

            'client_id' => $client->id,

            'registration_id' => $registration->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' => $request->payment_type ?? 'change',

            'client_name' => $client->name,

            'client_phone' => $client->phone,

            'client_address' => $client->address,

            'membership_plan' => $registration->membershipPlan->name ?? '',

            'contract_start_date' => $request->contract_start_date ?? now(),

            'contract_end_date' => $request->contract_end_date ?? now()->addYear(),

            'notes' => 'change',

            // New database columns

            'account_type_id' => $request->account_type_id ?? 1,

            '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' => $registration->registration_date ?? now(),

            'locker_id' => $firstLocker['id'] ?? 0,

            'locker_number' => collect($lockersData)->pluck('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,

        ];

        // Get the latest payment for payment mode
        $payments = null;
        if ($client->lockerRegistrations->isNotEmpty()) {
            $latestRegistration = $client->lockerRegistrations->first();
            if ($latestRegistration->payments->isNotEmpty()) {
                $payments = $latestRegistration->payments->first();
            }
        }
        return view('clients.change-locker', compact('client', 'membership_plan', 'locker_groups', 'payments', 'invoicePreview'));
    }

    public function storeLocker(Request $request, $id)
    {
        $client = Client::byTenant()->findOrFail($id);

        $validator = Validator::make($request->all(), [
            'safebox_count' => 'required|numeric|min:1',
            'selected_lockers_data' => 'required|string|json',
            'payment_terms' => 'required|string|max:50',
            'contract_start_date' => 'required|date|after_or_equal:today',
            'contract_end_date' => 'nullable|date|after_or_equal:contract_start_date',
            'stamping_fee' => 'required|numeric',
            'key_deposit' => 'required|numeric',
            'insurance_charges' => 'required|numeric',
            'discount_amount' => 'required|numeric',
            'tax_amount' => 'required|numeric',
            'payment_mode' => 'required|string|max:50',
            'referred_member_by' => 'nullable|string|max:50',
            'referred_commission' => 'nullable|numeric',
        ]);

        if ($validator->fails()) {
            return redirect()->back()->withErrors($validator)->withInput();
        }

        try {
            DB::beginTransaction();

            $lockersData = json_decode($request->selected_lockers_data, true);

            if (!$lockersData || !is_array($lockersData)) {
                return redirect()->back()->with('error', 'Invalid locker selection format.');
            }

            foreach ($lockersData as $locker) {
                if (!isset($locker['id'], $locker['number'], $locker['size'], $locker['type'])) {
                    return redirect()->back()->with('error', 'Invalid locker data.');
                }

                $lockerRecord = \App\Models\Locker::find($locker['id']);
                if (!$lockerRecord || $lockerRecord->status !== 'Available') {
                    return redirect()->back()->with('error', "Locker {$locker['number']} is not available.");
                }
            }

            $registration = \App\Models\LockerRegistration::create([
                'client_id' => $client->id,
                'auth_count' => $client->auth_count ?? 0,
                'locker_password' => '123456',
                'registration_date' => now()->toDateString(),
                'safebox_count' => $request->safebox_count,
                'contract_start_date' => $request->contract_start_date,
                'contract_end_date' => $request->contract_end_date,
                'payment_terms' => $request->payment_terms,
                'stamping_fee' => $request->stamping_fee,
                'key_deposit' => $request->key_deposit,
                'insurance_charges' => $request->insurance_charges,
                'discount_amount' => $request->discount_amount,
                'tax_amount' => $request->tax_amount,
                'referred_member_by' => $request->referred_member_by,
                'referred_commission' => $request->referred_commission,
                'status' => 'Active',
            ]);

            $totalAmount = 0;
            foreach ($lockersData as $locker) {
                \App\Models\LockerRegistrationItem::create([
                    'registration_id' => $registration->id,
                    'locker_id' => $locker['id'],
                    'locker_number' => $locker['number'],
                    'size' => $locker['size'],
                    'type' => $locker['type'],
                    'locker_group' => $locker['locker_group'] ?? null,
                    'locker_position' => $locker['locker_position'] ?? null,
                    'start_date' => $request->contract_start_date,
                    'end_date' => $request->contract_end_date,
                    'amount' => $locker['amount'] ?? 0,
                    'status' => 'active',
                    'added_at' => now(),
                ]);

                \App\Models\Locker::where('id', $locker['id'])->update(['status' => 'Occupied']);
                $totalAmount += (float) ($locker['amount'] ?? 0);
            }

            $paymentTotal = (float) ($request->final_amount ?? 0);
            if ($paymentTotal <= 0) {
                $paymentTotal = $totalAmount + (float) ($request->tax_amount ?? 0);
            }

            \App\Models\Payment::create([
                'registration_id' => $registration->id,
                'payment_mode' => $request->payment_mode,
                'total_amount' => $paymentTotal,
                'paid_amount' => $paymentTotal,
                'balance_amount' => 0,
                'payment_date' => now(),
                'status' => 'paid',
                'notes' => 'add',
            ]);

            DB::commit();

            return redirect()->route('customers.show', $client->id)->with('success', 'Locker added successfully.');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error adding locker for client ' . $id . ': ' . $e->getMessage());

            return redirect()->back()->with('error', 'Unable to add locker. Please try again.');
        }
    }

    public function updateLocker(Request $request, $id)
    {
        $client = Client::byTenant()->findOrFail($id);

        $validator = Validator::make($request->all(), [
            'existing_locker_item_id' => 'required|integer|exists:locker_registration_items,id',
            'selected_lockers_data' => 'required|string|json',
            'tax_type' => 'required|string|max:50',
            'stamping_fee' => 'required|numeric|min:0',
            'insurance_charges' => 'required|numeric|min:0',
            'discount_amount' => 'required|numeric|min:0',
            'key_deposit' => 'nullable|numeric|min:0',
            'payment_mode' => 'required|string|max:50',
            'contract_start_date' => 'nullable|date',
            'contract_end_date' => 'nullable|date|after_or_equal:contract_start_date',
            'reason' => 'nullable|string|max:1000',
        ]);

        if ($validator->fails()) {
            return redirect()->back()->withErrors($validator)->withInput();
        }

        try {

            DB::beginTransaction();

            // Existing locker item
            $existingItem = LockerRegistrationItem::with(['registration', 'locker'])
                ->findOrFail($request->existing_locker_item_id);

            // Verify ownership
            if ($existingItem->registration->client_id != $client->id) {
                return redirect()->back()->with('error', 'Invalid locker item.');
            }

            $registration = $existingItem->registration;

            // OLD locker details backup
            $oldLockerDetails = [
                'locker_id' => $existingItem->locker_id,
                'locker_number' => $existingItem->locker_number,
                'amount' => $existingItem->amount,
                'size' => $existingItem->size,
                'type' => $existingItem->type,
                'locker_group' => $existingItem->locker_group,
                'locker_position' => $existingItem->locker_position,
            ];

            // OLD registration data backup
            $oldRegistrationData = [
                'stamping_fee' => $registration->stamping_fee,
                'insurance_charges' => $registration->insurance_charges,
                'discount_amount' => $registration->discount_amount,
                'key_deposit' => $registration->key_deposit,
                'payment_terms' => $registration->payment_terms,
                'contract_start_date' => $registration->contract_start_date,
                'contract_end_date' => $registration->contract_end_date,
            ];

            // OLD tax type backup
            $oldTaxType = $client->tax_type;

            // Selected lockers decode
            $selectedLockersData = json_decode($request->selected_lockers_data, true);

            if (
                !$selectedLockersData ||
                !is_array($selectedLockersData) ||
                empty($selectedLockersData)
            ) {
                return redirect()->back()->with('error', 'Invalid locker selection data.');
            }

            // First locker
            $firstSelectedLocker = $selectedLockersData[0];

            $newLocker = Locker::findOrFail($firstSelectedLocker['id']);

            if ($newLocker->status !== 'Available') {
                return redirect()->back()->with(
                    'error',
                    "Locker {$newLocker->locker_number} is not available."
                );
            }

            // Free old locker
            Locker::where('id', $existingItem->locker_id)
                ->update([
                    'status' => 'Available'
                ]);

            // Mark old item changed
            $existingItem->update([
                'status' => 'changed'
            ]);

            // Dates
            $startDate = $request->contract_start_date
                ? \Carbon\Carbon::parse($request->contract_start_date)
                : (
                    $existingItem->start_date
                    ?? (
                        $registration->contract_start_date
                        ? \Carbon\Carbon::parse($registration->contract_start_date)
                        : now()
                    )
                );

            $endDate = $request->contract_end_date
                ? \Carbon\Carbon::parse($request->contract_end_date)
                : (
                    $existingItem->end_date
                    ?? (
                        $registration->contract_end_date
                        ? \Carbon\Carbon::parse($registration->contract_end_date)
                        : now()->addYear()
                    )
                );

            // Create NEW locker item
            $newItem = LockerRegistrationItem::create([
                'registration_id' => $registration->id,
                'locker_id' => $newLocker->id,
                'locker_number' => $newLocker->locker_number,
                'size' => $newLocker->locker_size,
                'type' => $newLocker->locker_type,
                'locker_group' => $newLocker->locker_group_id,
                'locker_position' => $newLocker->locker_row_column,
                'amount' => $newLocker->locker_amount,
                'status' => 'active',
                'start_date' => $startDate,
                'end_date' => $endDate,
                'added_at' => now(),
            ]);

            // Occupy new locker
            Locker::where('id', $newLocker->id)
                ->update([
                    'status' => 'Occupied'
                ]);

            // Update client tax type
            $client->update([
                'tax_type' => $request->tax_type,
            ]);

            // Update registration
            $registration->update([
                'stamping_fee' => $request->stamping_fee,
                'insurance_charges' => $request->insurance_charges,
                'discount_amount' => $request->discount_amount,
                'key_deposit' => $request->key_deposit ?? 0,
                'contract_start_date' => $request->contract_start_date
                    ?? $registration->contract_start_date,
                'contract_end_date' => $request->contract_end_date
                    ?? $registration->contract_end_date,
            ]);

            // Total active lockers amount
            $totalLockerAmount = $registration->items()
                ->where('status', 'active')
                ->sum('amount');

            // Tax
            $taxAmount = (
                strtoupper($request->tax_type) === 'GST'
                || strtoupper($request->tax_type) === 'SST'
            )
                ? (
                    ($totalLockerAmount - ($request->discount_amount ?? 0)) * 0.08
                )
                : 0;

            // Final amount
            $finalAmount =
                $totalLockerAmount
                + $taxAmount
                + ($request->stamping_fee ?? 0)
                + ($request->insurance_charges ?? 0)
                + ($request->key_deposit ?? 0)
                - ($request->discount_amount ?? 0);

            if ($finalAmount < 0.01) {
                $finalAmount = 0.01;
            }


            $invoice = $registration->invoices()->latest()->first();

            if ($invoice) {

                $invoice->update([

                    // 'client_id' => $client->id,
                    // 'registration_id' => $registration->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' => $finalAmount,
                    'paid_amount' => 0,
                    'balance_amount' => $finalAmount,

                    'payment_mode' => $request->payment_mode,

                    'status' => 'pending',
                    'payment_type' => 'change',

                    'client_name' => $client->name,
                    'client_phone' => $client->phone,
                    'client_address' => $client->address,

                    'membership_plan' => $registration->membershipPlan->name ?? '',

                    'contract_start_date' => $startDate,
                    'contract_end_date' => $endDate,

                    'notes' => 'change',

                    'account_type_id' => $registration->account_type_id ?? 1,

                    'email' => $client->email ?? '',
                    'safebox' => $registration->safebox_count ?? '',

                    'postal_code' => $client->postal_code ?? '',
                    'city' => $client->city ?? '',
                    'state' => $client->state ?? '',
                    'country' => $client->country ?? '',

                    'registration_number' => $registration->registration_number ?? '',

                    'tax_type' => $request->tax_type ?? '',

                    'safebox_count' => $registration->safebox_count ?? 1,
                    'payment_terms' => $registration->payment_terms ?? 1,

                    'referred_member_by' => $registration->referred_member_by,
                    'referred_commission' => $registration->referred_commission ?? 0,
                    'commission_used' => $registration->commission_used ?? 0,

                    'registration_date' => $registration->registration_date ?? now(),

                    'locker_id' => $newLocker->id,
                    'locker_number' => $newLocker->locker_number,

                    'size' => $newLocker->locker_size,
                    'type' => $newLocker->locker_type,
                    'locker_group' => $newLocker->locker_group_id,
                    'locker_position' => $newLocker->locker_row_column,

                    'start_date' => $startDate,
                    'end_date' => $endDate,

                    'amount' => $newLocker->locker_amount,
                ]);
            }

            // Update latest payment
            $payment = $registration->payments()->latest()->first();

            if ($payment) {

                $payment->update([
                    'total_amount' => $finalAmount,
                    'paid_amount' => $finalAmount,
                    'balance_amount' => 0,
                    'payment_mode' => $request->payment_mode,
                    'payment_date' => now(),
                    'notes' => 'change',
                ]);
            }

            // Locker change history
            \App\Models\LockerChange::create([

                'client_id' => $client->id,

                'old_locker_id' => $oldLockerDetails['locker_id'],
                'old_locker_number' => $oldLockerDetails['locker_number'],

                'new_locker_id' => $newLocker->id,
                'new_locker_number' => $newLocker->locker_number,

                'changed_by_user_id' => auth()->id(),

                'reason' => $request->reason
                    ?? 'Locker change requested by user',

                'old_amount' => $oldLockerDetails['amount'],
                'new_amount' => $newLocker->locker_amount,

                'effective_date' => now(),

                'status' => 'completed',

                // OLD
                'old_safebox_count' => $registration->safebox_count ?? 1,
                'old_size' => $oldLockerDetails['size'],
                'old_type' => $oldLockerDetails['type'],
                'old_locker_group' => $oldLockerDetails['locker_group'],
                'old_tax_type' => $oldTaxType,

                'old_selected_locker_data' => json_encode([
                    [
                        'id' => $oldLockerDetails['locker_id'],
                        'number' => $oldLockerDetails['locker_number'],
                        'size' => $oldLockerDetails['size'],
                        'type' => $oldLockerDetails['type'],
                        'locker_group' => $oldLockerDetails['locker_group'],
                        'locker_position' => $oldLockerDetails['locker_position'],
                        'amount' => $oldLockerDetails['amount'],
                    ]
                ]),

                'old_stamping_fee' => $oldRegistrationData['stamping_fee'],
                'old_insurance_charges' => $oldRegistrationData['insurance_charges'],
                'old_discount_amount' => $oldRegistrationData['discount_amount'],
                'old_key_deposit' => $oldRegistrationData['key_deposit'],
                'old_payment_mode' => $payment ? $payment->payment_mode : null,
                'old_tax_amount' => (
                    (
                        $oldRegistrationData['stamping_fee']
                        + $oldRegistrationData['insurance_charges']
                        + $oldLockerDetails['amount']
                        - $oldRegistrationData['discount_amount']
                    ) * 0.08
                ),
                'old_final_amount' => $payment ? $payment->total_amount : 0,
                'old_payment_terms' => $oldRegistrationData['payment_terms'],
                'old_contract_start_date' => $oldRegistrationData['contract_start_date'],
                'old_contract_end_date' => $oldRegistrationData['contract_end_date'],

                // NEW
                'new_safebox_count' => $registration->safebox_count ?? 1,
                'new_size' => $newLocker->locker_size,
                'new_type' => $newLocker->locker_type,
                'new_locker_group' => $newLocker->locker_group_id,
                'new_tax_type' => $request->tax_type,

                'new_selected_locker_data' => json_encode([
                    [
                        'id' => $newLocker->id,
                        'number' => $newLocker->locker_number,
                        'size' => $newLocker->locker_size,
                        'type' => $newLocker->locker_type,
                        'locker_group' => $newLocker->locker_group_id,
                        'locker_position' => $newLocker->locker_row_column,
                        'amount' => $newLocker->locker_amount,
                    ]
                ]),

                'new_stamping_fee' => $request->stamping_fee,
                'new_insurance_charges' => $request->insurance_charges,
                'new_discount_amount' => $request->discount_amount,
                // 'new_key_deposit' => $request->key_deposit ?? 0,
                'new_payment_mode' => $request->payment_mode,
                'new_tax_amount' => $taxAmount,
                'new_final_amount' => $finalAmount,
                'new_payment_terms' => $registration->payment_terms,
                'new_contract_start_date' => $registration->contract_start_date,
                'new_contract_end_date' => $registration->contract_end_date,
            ]);

            DB::commit();

            return redirect()
                ->route('customers.show', $client->id)
                ->with('success', 'Locker changed successfully.');
        } catch (\Exception $e) {

            DB::rollBack();

            Log::error('Error changing locker for client ' . $id . ': ' . $e->getMessage());

            Log::error($e->getTraceAsString());

            return redirect()
                ->back()
                ->with('error', 'Unable to change locker: ' . $e->getMessage())
                ->withInput();
        }
    }

    public function edit($id)
    {
        $client = Client::byTenant()->findOrFail($id);
        $statuses = \App\Models\Status::where('type', 'client')->get();
        $lockers = \App\Models\Locker::all();
        $account_type = \App\Models\AccountType::select('id', 'type_name')->where('status', 1)->get();
        $membership_plan = MembershipPlan::select('id', 'name', 'price')->where('status', 1)->get();
        $locker_groups = LockerGroup::select('id', 'name')->get();
        $countries = Country::select('id', 'name')->where('status', 1)->get();
        return view('clients.edit', compact('client', 'statuses', 'lockers', 'account_type', 'membership_plan', 'locker_groups', 'countries'));
    }

    public function update(Request $request, $id)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'contact_person' => 'required|string|max:255',
            'email' => 'required|email',
            'phone' => 'required|digits_between:10,11',
            'alternate_phone' => 'nullable|string|max:20',
            'address' => 'required|string|max:500',
            'city' => 'required|string|max:100',
            'state' => 'required|string|max:100',
            'country' => 'required|string|max:100',
            'postal_code' => 'required|string|max:20',
            'website' => 'nullable|url|max:255',
            'account_type' => 'required|integer|exists:account_types,id',
            'auth_count' => 'required|numeric',
            'gst_number' => 'nullable|string|max:50',
            'pan_number' => 'nullable|string|max:20',
            'payment_terms' => 'required|string|max:50',
            'contract_start_date' => 'nullable|date',
            'contract_end_date' => 'nullable|date|after_or_equal:contract_start_date',
            'status_id' => 'required|exists:statuses,id',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        try {
            DB::beginTransaction();

            $client = Client::byTenant()->findOrFail($id);

            $client->update([
                'name' => $request->name,
                'contact_person' => $request->contact_person,
                'email' => $request->email,
                'phone' => $request->phone,
                'alternate_phone' => $request->alternate_phone,
                'address' => $request->address,
                'city' => $request->city,
                'state' => $request->state,
                'country' => $request->country,
                'postal_code' => $request->postal_code,
                'website' => $request->website,
                'account_type_id' => $request->account_type,
                'auth_count' => $request->auth_count,
                'gst_number' => $request->gst_number,
                'pan_number' => $request->pan_number,
                'payment_terms' => $request->payment_terms,
                'contract_start_date' => $request->contract_start_date,
                'contract_end_date' => $request->contract_end_date,
                'status_id' => $request->status_id,
            ]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Client updated successfully',
                'redirect' => route('customers.members')
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => 'Error updating client: ' . $e->getMessage(),
                'errors' => []
            ], 500);
        }
    }

    public function destroy($id)
    {
        try {
            $client = Client::byTenant()->findOrFail($id);

            // Check if client has active contracts
            if ($client->contracts()->where('status_id', Status::getActiveId())->count() > 0) {
                return response()->json(['success' => false, 'message' => 'Cannot delete client with active contracts'], 400);
            }

            $client->delete();

            return response()->json(['success' => true, 'message' => 'Client deleted successfully']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Error deleting client: ' . $e->getMessage()], 500);
        }
    }

    public function locations()
    {
        $locations = ClientLocation::with('client')
            ->byTenant()
            ->paginate(20);

        // Get filter options
        $clients = \App\Models\Client::byTenant()->active()->pluck('name', 'id');

        return view('clients.locations', compact('locations', 'clients'));
    }

    public function contracts()
    {
        $contracts = ClientContract::with(['client', 'status'])
            ->byTenant()
            ->paginate(20);

        // Get filter options
        $clients = \App\Models\Client::byTenant()->active()->pluck('name', 'id');
        $statuses = \App\Models\Status::where('type', 'contract')->pluck('name', 'id');

        return view('clients.contracts', compact('contracts', 'clients', 'statuses'));
    }

    public function contacts($clientId)
    {
        $client = Client::with(['contacts'])->byTenant()->findOrFail($clientId);
        return view('clients.contacts', compact('client'));
    }

    public function storeContact(Request $request, $clientId)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'email' => 'required|email',
            'phone' => 'required|string|max:20',
            'position' => 'nullable|string|max:255',
            'department' => 'nullable|string|max:255',
            'notes' => 'nullable|string|max:1000',
            'is_primary' => 'boolean',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        try {
            DB::beginTransaction();

            $client = Client::byTenant()->findOrFail($clientId);

            $contact = $client->addContact([
                'name' => $request->name,
                'email' => $request->email,
                'phone' => $request->phone,
                'position' => $request->position,
                'department' => $request->department,
                'notes' => $request->notes,
                'is_primary' => $request->boolean('is_primary', false),
            ]);

            DB::commit();

            return response()->json(['success' => true, 'contact' => $contact]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => 'Error creating contact: ' . $e->getMessage()], 500);
        }
    }

    public function showContact($contactId)
    {
        $contact = ClientContact::with(['client'])->byTenant()->findOrFail($contactId);
        return response()->json($contact);
    }

    public function updateContact(Request $request, $contactId)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'email' => 'required|email',
            'phone' => 'required|string|max:20',
            'position' => 'nullable|string|max:255',
            'department' => 'nullable|string|max:255',
            'notes' => 'nullable|string|max:1000',
            'is_primary' => 'boolean',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        try {
            DB::beginTransaction();

            $contact = ClientContact::byTenant()->findOrFail($contactId);

            $contact->update([
                'name' => $request->name,
                'email' => $request->email,
                'phone' => $request->phone,
                'position' => $request->position,
                'department' => $request->department,
                'notes' => $request->notes,
            ]);

            if ($request->boolean('is_primary', false)) {
                $contact->makePrimary();
            }

            DB::commit();

            return response()->json(['success' => true, 'contact' => $contact]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => 'Error updating contact: ' . $e->getMessage()], 500);
        }
    }

    public function destroyContact($contactId)
    {
        try {
            $contact = ClientContact::byTenant()->findOrFail($contactId);

            if ($contact->is_primary) {
                return response()->json(['success' => false, 'message' => 'Cannot delete primary contact'], 400);
            }

            $contact->delete();

            return response()->json(['success' => true, 'message' => 'Contact deleted successfully']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Error deleting contact: ' . $e->getMessage()], 500);
        }
    }

    // // Customer Members Management
    // public function members($customerId)
    // {
    //     $client = Client::byTenant()
    //         ->with(['lockerRegistrations' => function ($query) {
    //             $query->with(['items', 'membershipPlan'])->where('status', 'Active');
    //         }])
    //         ->findOrFail($customerId);

    //     $members = $client->customerMembers()
    //         ->with('statusRelation')
    //         ->where('is_active', 1)
    //         ->get();

    //     return view('clients.members', compact('client', 'members'));
    // }

    public function members($customerId)
    {
        $client = Client::byTenant()
            ->with(['lockerRegistrations' => function ($query) {
                $query->with(['items', 'membershipPlan'])
                    ->where('status', 'Active');
            }])
            ->findOrFail($customerId);

        $members = $client->customerMembers()
            ->with('statusRelation')
            ->where('is_active', 1)
            ->get();

        // Calculate dynamically
        $authCount = $members->count();

        return view('clients.members', compact('client', 'members', 'authCount'));
    }


    public function storeMember(Request $request, $customerId)
    {
        $request->merge([
            'status' => 2
        ]);

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|min:2|max:255',
            'gender' => 'required|string|in:male,female',
            'email' => 'nullable|email|unique:customer_members,email,NULL,id,client_id,' . $customerId,
            'mobile' => 'required|digits_between:10,11',
            'proof_type' => 'required|string|in:passport,ic_number',
            'proof_number' => 'required|string|min:5|max:100',
            'proof_file' => 'nullable|file|mimes:pdf,jpg,jpeg,png,gif|max:5120',
            'address' => 'nullable|string|max:500',
            'finger_auth' => 'boolean',
            'face_auth' => 'required|boolean',
            'required_auth' => 'boolean',
            // 'status' => 2,
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        try {
            $client = Client::byTenant()->findOrFail($customerId);

            $authRequiredCount = $client->authorized_count; // authorized_count
            $currentRequiredCount = CustomerMember::where('client_id', $customerId)
                ->where('required_auth', 1)
                ->where('is_active', 1)
                ->count();

            if ($request->boolean('required_auth')) {
                if ($authRequiredCount <= $currentRequiredCount) {
                    return response()->json([
                        'success' => false,
                        'message' => "Cannot add more required members. Maximum limit reached: {$currentRequiredCount}/{$authRequiredCount}"
                    ], 422);
                }
            }

            // Check if adding member exceeds auth_count limit
            $currentMembersCount = $client->customerMembers()
                ->where('is_active', 1)
                ->count();

            // Calculate max auth count from locker registrations
            $maxAuthCount = $client->lockerRegistrations->sum('auth_count') ?: $client->auth_count;

            if ($currentMembersCount >= $maxAuthCount) {
                return response()->json([
                    'success' => false,
                    'message' => "Cannot add more members. Maximum limit reached: {$currentMembersCount}/{$maxAuthCount}"
                ], 422);
            }

            $proofFilePath = null;
            if ($request->hasFile('proof_file')) {
                $file = $request->file('proof_file');
                $filename = time() . '_' . preg_replace('/\s+/', '_', $file->getClientOriginalName());
                $uploadDir = public_path('uploads/member-proofs');
                if (!file_exists($uploadDir)) {
                    mkdir($uploadDir, 0755, true);
                }
                $file->move($uploadDir, $filename);
                $proofFilePath = 'uploads/member-proofs/' . $filename;
            }

            $member = $client->customerMembers()->create([
                'name' => $request->name,
                'gender' => $request->gender,
                'email' => $request->email,
                'mobile' => $request->mobile,
                'proof_type' => $request->proof_type,
                'proof_number' => $request->proof_number,
                'proof_file' => $proofFilePath,
                'address' => $request->address,
                'finger_auth' => $request->boolean('finger_auth'),
                'face_auth' => $request->boolean('face_auth'),
                'required_auth' => $request->boolean('required_auth'),
                'status' => $request->status ?? 1, // Default to active if not provided
                'is_active' => true,
                // 'tenant_id' => $client->tenant_id,
            ]);

            // Return a clean array to avoid JSON serialization issues
            $response = [
                'success' => true,
                'member' => [
                    'id' => $member->id,
                    'name' => $member->name,
                    'gender' => $member->gender,
                    'email' => $member->email,
                    'mobile' => $member->mobile,
                    'address' => $member->address,
                    'finger_auth' => $member->finger_auth,
                    'face_auth' => $member->face_auth,
                    'required_auth' => $member->required_auth,
                    'is_finger_verified' => $member->is_finger_verified,
                    'status' => $member->status,
                    'is_active' => $member->is_active,
                    'created_at' => $member->created_at,
                    'updated_at' => $member->updated_at,
                ]
            ];

            // Clean any output buffers and return JSON
            if (ob_get_level()) {
                ob_clean();
            }

            return response()->json($response);
        } catch (\Exception $e) {
            // Clean any output buffers and return JSON
            if (ob_get_level()) {
                ob_clean();
            }
            return response()->json(['success' => false, 'message' => 'Error adding member: ' . $e->getMessage()], 500);
        }
    }

    public function showMember($memberId)
    {
        try {
            $member = CustomerMember::findOrFail($memberId);

            return response()->json([
                'success' => true,
                'member' => [
                    'id' => $member->id,
                    'name' => $member->name,
                    'gender' => $member->gender,
                    'email' => $member->email,
                    'mobile' => $member->mobile,
                    'proof_type' => $member->proof_type,
                    'proof_number' => $member->proof_number,
                    'proof_file' => $member->proof_file,
                    'address' => $member->address,
                    'finger_auth' => $member->finger_auth,
                    'face_auth' => $member->face_auth,
                    'required_auth' => $member->required_auth,
                    'is_finger_verified' => $member->is_finger_verified,
                    'status' => $member->status,
                    'is_active' => $member->is_active,
                    'created_at' => $member->created_at,
                    'updated_at' => $member->updated_at,
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error loading member',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function updateMember(Request $request, $memberId)
    {
        $member = CustomerMember::findOrFail($memberId);

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|min:2|max:255',
            'gender' => 'required|string|in:male,female',
            'email' => 'nullable|email|unique:customer_members,email,' . $memberId . ',id,client_id,' . $member->client_id,
            'mobile' => 'required|string|max:20',
            'proof_type' => 'required|string|max:50',
            'proof_number' => 'required|string|min:5|max:100',
            'proof_file' => 'nullable|file|mimes:pdf,jpg,jpeg,png,gif|max:5120',
            'address' => 'nullable|string|max:500',
            'face_auth' => 'required|boolean',
            'finger_auth' => 'boolean',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        try {

            $customerId = $member->client_id;

            $client = Client::byTenant()->findOrFail($customerId);

            $authRequiredCount = $client->authorized_count; // authorized_count

            // $currentRequiredCount = CustomerMember::where('client_id', $customerId)
            //     ->where('required_auth', 1)
            //     ->count();
            $currentRequiredCount = CustomerMember::where('client_id', $customerId)
                ->where('required_auth', 1)
                ->where('id', '!=', $memberId) // IMPORTANT
                ->count();

            if ($request->boolean('required_auth')) {
                if ($authRequiredCount <= $currentRequiredCount) {
                    return response()->json([
                        'success' => false,
                        'message' => "Cannot add more required members. Maximum limit reached: {$currentRequiredCount}/{$authRequiredCount}"
                    ], 422);
                }
            }
            $updateData = [
                'name' => $request->name,
                'gender' => $request->gender,
                'email' => $request->email,
                'mobile' => $request->mobile,
                'proof_type' => $request->proof_type,
                'proof_number' => $request->proof_number,
                'required_auth' => $request->boolean('required_auth'),
                'address' => $request->address,
                'finger_auth' => $request->boolean('finger_auth'),
                'face_auth' => $request->boolean('face_auth'),
            ];

            // Handle proof file upload
            if ($request->hasFile('proof_file')) {
                // Delete old file if it exists
                if ($member->proof_file && file_exists(public_path($member->proof_file))) {
                    unlink(public_path($member->proof_file));
                }
                $file = $request->file('proof_file');
                $filename = time() . '_' . preg_replace('/\s+/', '_', $file->getClientOriginalName());
                $uploadDir = public_path('uploads/member-proofs');
                if (!file_exists($uploadDir)) {
                    mkdir($uploadDir, 0755, true);
                }
                $file->move($uploadDir, $filename);
                $updateData['proof_file'] = 'uploads/member-proofs/' . $filename;
            }

            $member->update($updateData);

            // Clean any output buffers at start
            if (ob_get_level()) {
                ob_clean();
            }

            return response()->json([
                'success' => true,
                'member' => [
                    'id' => $member->id,
                    'name' => $member->name,
                    'email' => $member->email,
                    'mobile' => $member->mobile,
                    'address' => $member->address,
                    'finger_auth' => $member->finger_auth,
                    'is_finger_verified' => $member->is_finger_verified,
                    'created_at' => $member->created_at,
                    'updated_at' => $member->updated_at,
                ]
            ]);
        } catch (\Exception $e) {
            // Clean any output buffers and return JSON
            if (ob_get_level()) {
                ob_clean();
            }
            return response()->json(['success' => false, 'message' => 'Error updating member: ' . $e->getMessage()], 500);
        }
    }

    public function verifyFinger(Request $request, $memberId)
    {
        try {
            // Clean any output buffers at the very start
            while (ob_get_level()) {
                ob_end_clean();
            }

            $member = CustomerMember::findOrFail($memberId);

            // Check if fingerprint authentication is enabled for this member
            if (!$member->finger_auth) {
                return response()->json([
                    'success' => false,
                    'message' => 'Fingerprint authentication is not enabled for this member.'
                ], 400);
            }

            // In a real implementation, this would integrate with fingerprint hardware
            // For now, we'll simulate verification by marking as verified
            $member->update([
                'status' => 1,
                'is_finger_verified' => true,
                'finger_verified_at' => now(),
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Fingerprint verified successfully.',
                'member' => $member->only([
                    'id',
                    'name',
                    'email',
                    'mobile',
                    'address',
                    'finger_auth',
                    'is_finger_verified',
                    'status',
                    'is_active',
                    'created_at',
                    'updated_at'
                ])
            ]);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Member not found.'
            ], 404);
        } catch (\Exception $e) {
            Log::error('Error verifying fingerprint: ' . $e->getMessage(), [
                'member_id' => $memberId,
                'exception' => $e
            ]);

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while verifying fingerprint.'
            ], 500);
        }
    }

    public function storeFace(Request $request, $memberId)
    {
        try {
            // Clean any output buffers at the very start
            while (ob_get_level()) {
                ob_end_clean();
            }

            $member = CustomerMember::findOrFail($memberId);

            // Check if face authentication is enabled for this member
            if (!$member->face_auth) {
                return response()->json([
                    'success' => false,
                    'message' => 'Face authentication is not enabled for this member.'
                ], 400);
            }

            // Validate request data
            $validator = Validator::make($request->all(), [
                'face_descriptor' => 'required|string',
                'landmarks' => 'nullable|string'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Invalid face data provided.',
                    'errors' => $validator->errors()
                ], 422);
            }

            // Store face descriptor in database
            $member->update([
                'face_descriptor' => $request->face_descriptor,
                'is_face_verified' => 1,
                'status' => 1
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Face data stored successfully.',
                'member' => $member->only([
                    'id',
                    'name',
                    'email',
                    'mobile',
                    'face_auth',
                    'face_descriptor',
                    'is_face_verified',
                    'status',
                    'updated_at'
                ])
            ]);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Member not found.'
            ], 404);
        } catch (\Exception $e) {
            Log::error('Error storing face data: ' . $e->getMessage(), [
                'member_id' => $memberId,
                'exception' => $e
            ]);

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while storing face data.'
            ], 500);
        }
    }

    public function verifyFace(Request $request, $memberId)
    {
        try {
            // Clean any output buffers at the very start
            while (ob_get_level()) {
                ob_end_clean();
            }

            $member = CustomerMember::findOrFail($memberId);

            // Check if face authentication is enabled for this member
            if (!$member->face_auth) {
                return response()->json([
                    'success' => false,
                    'message' => 'Face authentication is not enabled for this member.'
                ], 400);
            }

            // Validate request data
            $validator = Validator::make($request->all(), [
                'face_descriptor' => 'required|string'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Invalid face data provided.',
                    'errors' => $validator->errors()
                ], 422);
            }

            // Check if member has stored face descriptor
            if (!$member->face_descriptor) {
                return response()->json([
                    'success' => false,
                    'message' => 'No face data found for this member. Please capture face data first.'
                ], 400);
            }

            // Compare face descriptors
            $storedDescriptor = json_decode($member->face_descriptor, true);
            $currentDescriptor = json_decode($request->face_descriptor, true);

            if (!$storedDescriptor || !$currentDescriptor) {
                return response()->json([
                    'success' => false,
                    'message' => 'Invalid face descriptor format.'
                ], 400);
            }

            // Calculate similarity (cosine similarity)
            $similarity = $this->calculateFaceSimilarity($storedDescriptor, $currentDescriptor);

            // Threshold for verification (adjust as needed)
            $threshold = 0.6;

            if ($similarity >= $threshold) {
                // Update member verification status
                $member->update([
                    'is_face_verified' => true
                ]);

                return response()->json([
                    'success' => true,
                    'message' => 'Face verified successfully.',
                    'similarity' => round($similarity, 3),
                    'member' => $member->only([
                        'id',
                        'name',
                        'email',
                        'mobile',
                        'face_auth',
                        'is_face_verified'
                    ])
                ]);
            } else {
                return response()->json([
                    'success' => false,
                    'message' => 'Face verification failed. Similarity too low.',
                    'similarity' => round($similarity, 3),
                    'threshold' => $threshold
                ], 400);
            }
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Member not found.'
            ], 404);
        } catch (\Exception $e) {
            Log::error('Error verifying face: ' . $e->getMessage(), [
                'member_id' => $memberId,
                'exception' => $e
            ]);

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while verifying face.'
            ], 500);
        }
    }

    private function calculateFaceSimilarity($descriptor1, $descriptor2)
    {
        // Calculate cosine similarity between two face descriptors
        $dotProduct = 0;
        $norm1 = 0;
        $norm2 = 0;

        for ($i = 0; $i < min(count($descriptor1), count($descriptor2)); $i++) {
            $dotProduct += $descriptor1[$i] * $descriptor2[$i];
            $norm1 += $descriptor1[$i] * $descriptor1[$i];
            $norm2 += $descriptor2[$i] * $descriptor2[$i];
        }

        $norm1 = sqrt($norm1);
        $norm2 = sqrt($norm2);

        if ($norm1 == 0 || $norm2 == 0) {
            return 0;
        }

        return $dotProduct / ($norm1 * $norm2);
    }

    public function destroyMember($memberId)
    {
        try {
            // Clean any output buffers at very start
            while (ob_get_level()) {
                ob_end_clean();
            }

            $member = CustomerMember::findOrFail($memberId);

            // Set status to 3 (Inactive) instead of deleting
            $member->update([
                'status' => 3,
                'is_active' => false,
                'updated_at' => now(),
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Member deactivated successfully.',
                'member' => $member->only([
                    'id',
                    'name',
                    'email',
                    'mobile',
                    'address',
                    'finger_auth',
                    'is_finger_verified',
                    'status',
                    'is_active',
                    'created_at',
                    'updated_at'
                ])
            ]);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Member not found.'
            ], 404);
        } catch (\Exception $e) {
            Log::error('Error deactivating member: ' . $e->getMessage(), [
                'member_id' => $memberId,
                'exception' => $e
            ]);

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while deactivating the member.'
            ], 500);
        }
    }

    /**
     * Search members for dropdown
     */
    public function searchMembers(Request $request)
    {
        try {
            $query = CustomerMember::with('client:id,name')
                ->select('id', 'name', 'mobile', 'client_id');

            if ($request->filled('search')) {
                $search = $request->search;
                $query->where(function ($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                        ->orWhere('mobile', 'like', "%{$search}%");
                });
            }

            $members = $query->orderBy('name')->limit(20)->get();

            $formattedMembers = $members->map(function ($member) {
                return [
                    'id' => $member->id,
                    'name' => $member->name,
                    'phone' => $member->mobile,
                    'client_name' => $member->client ? $member->client->name : 'N/A',
                    'display_name' => $member->name . ' (' . ($member->client ? $member->client->name : 'N/A') . ')'
                ];
            });

            return response()->json($formattedMembers->values());
        } catch (\Throwable $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error searching members',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get available lockers for selection
     */
    public function getAvailableLockers(Request $request)
    {
        try {
            $query = Locker::query();

            // Filter by size if specified
            if ($request->filled('size')) {
                $query->where('locker_size', $request->size);
            }

            // Filter by row if specified
            if ($request->filled('row')) {
                $query->where('locker_row_column', 'like', $request->row . 'C%');
            }

            // Filter by type if specified
            if ($request->filled('type')) {
                $query->where('locker_type', $request->type);
            }

            // Filter by group if specified
            if ($request->filled('group')) {
                $query->where('locker_group_id', $request->group);
            }

            // Filter by status if specified
            if ($request->filled('status')) {
                $query->where('status', ucfirst($request->status));
            }

            // If no status filter is specified, get all lockers for dashboard
            // If status is explicitly empty or not provided, get all lockers
            if (!$request->has('status') || $request->status === '') {
                $query->where('status', 'Available');
                $query->leftJoin('locker_groups', 'lockers.locker_group_id', '=', 'locker_groups.id')
                    ->select('lockers.*', 'locker_groups.name as name');

                $lockers = $query->orderBy('lockers.locker_number')->get();
            } else {
                // If status is specified (even if empty), filter by that status
                if ($request->status === '') {
                    // For client selection, default to available only
                    $query->where('status', 'Available');
                }
                $query->leftJoin('locker_groups', 'lockers.locker_group_id', '=', 'locker_groups.id')
                    ->select('lockers.*', 'locker_groups.name as name');

                $lockers = $query->orderBy('lockers.locker_number')->get();
            }

            return response()->json([
                'success' => true,
                'lockers' => $lockers
            ]);
        } catch (\Exception $e) {
            Log::error('Error fetching available lockers: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'Error fetching lockers'
            ], 500);
        }
    }

    /**
     * Update authorized count for a client
     */
    // public function updateAuthCount(Request $request, $customerId)
    // {
    //     try {
    //         // Find the client explicitly
    //         $client = Client::findOrFail($customerId);

    //         // Validate the request
    //         $validator = Validator::make($request->all(), [
    //             'auth_count' => 'required|integer|min:1|max:999'
    //         ], [
    //             'auth_count.required' => 'Authorized count is required',
    //             'auth_count.integer' => 'Authorized count must be a number',
    //             'auth_count.min' => 'Authorized count must be at least 1',
    //             'auth_count.max' => 'Authorized count cannot exceed 999'
    //         ]);

    //         if ($validator->fails()) {
    //             return response()->json([
    //                 'success' => false,
    //                 'message' => $validator->errors()->first()
    //             ], 422);
    //         }

    //         $newAuthCount = $request->input('auth_count');
    //         $currentMembersCount = $client->customerMembers()->count();

    //         // For authorized_count (minimum allowed), we don't need to check against current members
    //         // as this represents the minimum baseline, not the maximum limit

    //         // But we should ensure minimum doesn't exceed maximum limit
    //         $maxAuthCount = $client->lockerRegistrations->sum('auth_count') ?: $client->auth_count;
    //         if ($newAuthCount > $maxAuthCount) {
    //             return response()->json([
    //                 'success' => false,
    //                 'message' => "Minimum allowed ({$newAuthCount}) cannot be more than maximum limit ({$maxAuthCount})"
    //             ], 422);
    //         }

    //         // Check limit required member count
    //         $currentRequiredCount = CustomerMember::where('client_id', $customerId)->where('required_auth', 1)->count();

    //         if ($newAuthCount < $currentRequiredCount) {
    //             return response()->json([
    //                 'success' => false,
    //                 'message' => "Cannot set minimum to {$newAuthCount}. You already have {$currentRequiredCount} required members. Minimum must be at least {$currentRequiredCount}."
    //             ], 422);
    //         }

    //         // Update the client's authorized count (minimum allowed members)
    //         $client->authorized_count = $newAuthCount;
    //         $client->save();

    //         Log::info("Updated authorized count (minimum allowed) for client {$client->id} ({$client->name}) from {$client->getOriginal('authorized_count')} to {$newAuthCount}");

    //         return response()->json([
    //             'success' => true,
    //             'message' => "Authorized count updated successfully to {$newAuthCount}",
    //             'auth_count' => $newAuthCount
    //         ]);
    //     } catch (\Exception $e) {
    //         Log::error('Error updating authorized count: ' . $e->getMessage());

    //         return response()->json([
    //             'success' => false,
    //             'message' => 'Failed to update authorized count. Please try again.'
    //         ], 500);
    //     }
    // }

    public function updateAuthCount(Request $request, $customerId)
    {
        try {
            $client = Client::findOrFail($customerId);

            $validator = Validator::make($request->all(), [
                'auth_count' => 'required|integer|min:1|max:999'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->errors()->first()
                ], 422);
            }

            $newAuthCount = $request->input('auth_count');

            // FIX 1: Get ACTIVE registration only
            $activeRegistration = $client->lockerRegistrations()
                ->where('status', 'Active')
                ->latest()
                ->first();

            $maxAuthCount = $activeRegistration ? $activeRegistration->auth_count : 0;

            // Prevent exceeding contract limit
            if ($newAuthCount > $maxAuthCount) {
                return response()->json([
                    'success' => false,
                    'message' => "Cannot exceed contract limit ({$maxAuthCount})"
                ], 422);
            }

            // FIX 2: Get current members count (ACTIVE ONLY and REQUIRED)
            $currentMembersCount = $client->customerMembers()
                ->where('required_auth', 1)
                ->where('is_active', 1)
                ->count();

            // Prevent reducing below current members
            if ($newAuthCount < $currentMembersCount) {
                return response()->json([
                    'success' => false,
                    'message' => "You already have {$currentMembersCount} members. Cannot set less than that."
                ], 422);
            }

            // Required members check (your logic)
            $currentRequiredCount = CustomerMember::where('client_id', $customerId)
                ->where('required_auth', 1)
                ->count();

            if ($newAuthCount < $currentRequiredCount) {
                return response()->json([
                    'success' => false,
                    'message' => "Minimum must be at least {$currentRequiredCount}"
                ], 422);
            }

            // SAVE
            $client->authorized_count = $newAuthCount;
            $client->save();

            return response()->json([
                'success' => true,
                'message' => "Authorized count updated to {$newAuthCount}"
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error updating authorized count'
            ], 500);
        }
    }

    /**
     * Generate random password for locker
     */
    private function generateLockerPassword(): string
    {
        // Generate 6-character alphanumeric password
        $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $password = '';

        for ($i = 0; $i < 6; $i++) {
            $password .= $characters[rand(0, strlen($characters) - 1)];
        }

        return $password;
    }

    public function getLockerItemDetails($itemId)
    {
        try {
            $lockerItem = LockerRegistrationItem::with([
                'registration',
                'registration.client',
                'registration.payments',
                'locker'
            ])->findOrFail($itemId);

            // Verify this item belongs to an active registration
            if ($lockerItem->registration->status !== 'Active' || $lockerItem->status !== 'active') {
                return response()->json([
                    'success' => false,
                    'message' => 'Locker item is not active'
                ], 404);
            }
            return response()->json([
                'success' => true,
                'locker_item' => [
                    'id' => $lockerItem->id,
                    'locker_number' => $lockerItem->locker_number,
                    'size' => $lockerItem->size,
                    'type' => $lockerItem->type,
                    'locker_group' => $lockerItem->locker_group,
                    'locker_position' => $lockerItem->locker_position,
                    'amount' => $lockerItem->amount,
                    'start_date' => $lockerItem->start_date,
                    'end_date' => $lockerItem->end_date,
                    'client' => [
                        'tax_type' => $lockerItem->registration->client->tax_type,
                    ],
                    'registration' => [
                        'safebox_count' => $lockerItem->registration->safebox_count,
                        'stamping_fee' => $lockerItem->registration->stamping_fee,
                        'key_deposit' => $lockerItem->registration->key_deposit,
                        'insurance_charges' => $lockerItem->registration->insurance_charges,
                        'discount_amount' => $lockerItem->registration->discount_amount,
                        'payment_terms' => $lockerItem->registration->payment_terms,
                        'contract_start_date' => $lockerItem->registration->contract_start_date,
                        'contract_end_date' => $lockerItem->registration->contract_end_date,
                        'payment_mode' => $lockerItem->registration->payments && $lockerItem->registration->payments->isNotEmpty()
                            ? $lockerItem->registration->payments->first()->payment_mode : null,
                    ]
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error fetching locker details: ' . $e->getMessage()
            ], 500);
        }
    }

    // public function import(Request $request)
    // {
    //     //     echo "<pre>";

    //     // $file = $request->file('file');

    //     // $handle = fopen($file->getRealPath(), 'r');

    //     // // Header
    //     // $header = fgetcsv($handle);

    //     // print_r($header);

    //     // echo "\n\n====================\n\n";

    //     // while (($row = fgetcsv($handle, 1000, ",")) !== false) {

    //     //     print_r($row);

    //     //     echo "\n----------------------\n";
    //     // }

    //     // fclose($handle);

    //     // exit;


    //     $request->validate([
    //         'file' => 'required|mimes:csv,txt'
    //     ]);

    //     if (!$request->hasFile('file')) {
    //         return back()->with('error', 'No file uploaded');
    //     }

    //     /*
    //     |--------------------------------------------------------------------------
    //     | CREATE IMPORT FOLDER
    //     |--------------------------------------------------------------------------
    //     */

    //     $path = public_path('client/import');

    //     if (!file_exists($path)) {
    //         mkdir($path, 0777, true);
    //     }

    //     /*
    //     |--------------------------------------------------------------------------
    //     | SAVE FILE
    //     |--------------------------------------------------------------------------
    //     */

    //     $fileName = time() . '_' . $request->file('file')->getClientOriginalName();

    //     $request->file('file')->move($path, $fileName);

    //     $filePath = $path . '/' . $fileName;

    //     /*
    //     |--------------------------------------------------------------------------
    //     | OPEN CSV
    //     |--------------------------------------------------------------------------
    //     */

    //     $file = fopen($filePath, 'r');

    //     if (!$file) {
    //         return back()->with('error', 'Unable to open CSV file');
    //     }

    //     $results = [];

    //     // Skip Header
    //     fgetcsv($file);

    //     /*
    //     |--------------------------------------------------------------------------
    //     | LOOP CSV ROWS
    //     |--------------------------------------------------------------------------
    //     */

    //     while (($row = fgetcsv($file, 1000, ",")) !== false) {

    //         DB::beginTransaction();

    //         try {

    //             /*
    //             |--------------------------------------------------------------------------
    //             | ACCOUNT TYPE
    //             |--------------------------------------------------------------------------
    //             */

    //             $accountTypeId = $row[1] ?? 1;

    //             /*
    //             |--------------------------------------------------------------------------
    //             | LOCKER FETCH
    //             |--------------------------------------------------------------------------
    //             */

    //             $lockerNumber = trim($row[24] ?? '');

    //             $lockerNumber = str_pad($lockerNumber, 4, '0', STR_PAD_LEFT);

    //             $locker = \App\Models\Locker::where('locker_number', $lockerNumber)->first();

    //             if (!$locker) {

    //                 $results[] = [
    //                     'name' => $row[3] ?? '',
    //                     'phone' => $row[4] ?? '',
    //                     'locker' => $lockerNumber,
    //                     'status' => 'failed',
    //                     'message' => 'Locker Not Found'
    //                 ];

    //                 DB::rollBack();

    //                 continue;
    //             }

    //             /*
    //             |--------------------------------------------------------------------------
    //             | CHECK LOCKER STATUS
    //             |--------------------------------------------------------------------------
    //             */

    //             if ($locker->status != 'Available') {

    //                 $results[] = [
    //                     'name' => $row[3] ?? '',
    //                     'phone' => $row[4] ?? '',
    //                     'locker' => $lockerNumber,
    //                     'status' => 'failed',
    //                     'message' => 'Locker Already Occupied'
    //                 ];

    //                 DB::rollBack();

    //                 continue;
    //             }

    //             /*
    //             |--------------------------------------------------------------------------
    //             | TAX
    //             |--------------------------------------------------------------------------
    //             */

    //             $taxType = strtoupper(trim($row[13] ?? 'GST'));

    //             $stampingFee = (float) ($row[14] ?? 0);
    //             $keyDeposit = (float) ($row[15] ?? 0);
    //             $insuranceCharges = (float) ($row[16] ?? 0);
    //             $discountAmount = (float) ($row[17] ?? 0);

    //             $lockerAmount = $locker->locker_amount ?? 0;

    //             $subtotal = $lockerAmount - $discountAmount;

    //             $taxAmount = 0;

    //             if ($taxType == 'GST' || $taxType == 'SST') {
    //                 $taxAmount = ($subtotal * 8) / 100;
    //             }

    //             $finalAmount =
    //                 $subtotal +
    //                 $taxAmount +
    //                 $stampingFee +
    //                 $keyDeposit +
    //                 $insuranceCharges;

    //             /*
    //             |--------------------------------------------------------------------------
    //             | DATES
    //             |--------------------------------------------------------------------------
    //             */

    //             $contractStartDate = !empty($row[28])
    //                 ? date('Y-m-d', strtotime($row[28]))
    //                 : null;

    //             $contractEndDate = !empty($row[29])
    //                 ? date('Y-m-d', strtotime($row[29]))
    //                 : null;

    //             // echo $contractEndDate; exit;

    //             $paymentTerms = $row[19] ?? 1;
    //             /*
    //             |--------------------------------------------------------------------------
    //             | CLIENT CREATE
    //             |--------------------------------------------------------------------------
    //             */

    //             $client = \App\Models\Client::create([

    //                 'status_id' => $row[0] ?? 1,
    //                 'account_type_id' => $accountTypeId,
    //                 'auth_count' => $row[2] ?? 1,

    //                 'name' => $row[3] ?? '',
    //                 'phone' => $row[4] ?? '',
    //                 'email' => $row[5] ?? null,

    //                 'landline' => $row[6] ?? '',

    //                 'address' => $row[7] ?? '',

    //                 'country_id' => $row[8] ?? null,
    //                 'state_id' => $row[9] ?? null,
    //                 'city_id' => $row[10] ?? null,

    //                 // 'postal_code' => $row[11] ?? null,

    //                 'postal_code' => (
    //                     isset($row[11]) &&
    //                     trim($row[11]) !== '' &&
    //                     strtoupper(trim($row[11])) !== 'NULL'
    //                 )
    //                     ? trim($row[11])
    //                     : null,

    //                 'registration_number' => $row[12] ?? '',

    //                 'tax_type' => $taxType,
    //                 'tax_amount' => $taxAmount,

    //                 'stamping_fee' => $stampingFee,
    //                 'key_deposit' => $keyDeposit,
    //                 'insurance_charges' => $insuranceCharges,
    //                 'discount_amount' => $discountAmount,

    //                 'final_amount' => $finalAmount,

    //                 'payment_mode' => $row[18] ?? 'cash',
    //                 'payment_terms' => $paymentTerms,

    //                 'contract_start_date' => $contractStartDate,
    //                 'contract_end_date' => $contractEndDate,

    //                 'referred_member_by' =>
    //                 !empty($row[22]) && $row[22] != 'NULL'
    //                     ? $row[22]
    //                     : null,

    //                 'referred_commission' => $row[23] ?? 0,

    //                 'selected_lockers_data' => json_encode([
    //                     [
    //                         'id' => $locker->id,
    //                         'number' => $locker->locker_number,
    //                         'size' => $locker->locker_size ?? '',
    //                         'type' => $locker->locker_type ?? '',
    //                         'locker_group' => $locker->locker_group ?? '',
    //                         'locker_position' => $locker->locker_row_column ?? '',
    //                         'amount' => $lockerAmount,
    //                     ]
    //                 ]),

    //                 'is_appointment' => 1,
    //                 'tenant_id' => config('app.default_tenant_id', 1),

    //                 'account_number' => $row[25] ?? 0,
    //                 'i@port' => $row[26] ?? 0,
    //                 'nric' => $row[27] ?? 0,
    //                 'import_contract_start_date' => $row[20] ?? 0,
    //                 'import_contract_end_date' => $row[21] ?? 0,

    //             ]);

    //             /*
    //             |--------------------------------------------------------------------------
    //             | REGISTRATION
    //             |--------------------------------------------------------------------------
    //             */

    //             $registration = \App\Models\LockerRegistration::create([

    //                 'client_id' => $client->id,
    //                 'auth_count' => $client->auth_count,

    //                 'locker_password' => '123456',

    //                 'registration_date' => now()->toDateString(),

    //                 'safebox_count' => 1,

    //                 'contract_start_date' => $contractStartDate,
    //                 'contract_end_date' => $contractEndDate,

    //                 'payment_terms' => $paymentTerms,

    //                 'stamping_fee' => $stampingFee,
    //                 'key_deposit' => $keyDeposit,
    //                 'insurance_charges' => $insuranceCharges,
    //                 'discount_amount' => $discountAmount,
    //                 'tax_amount' => $taxAmount,

    //                 'referred_member_by' => $client->referred_member_by,
    //                 'referred_commission' => $client->referred_commission,

    //                 'status' => 'Active',
    //             ]);

    //             /*
    //             |--------------------------------------------------------------------------
    //             | REGISTRATION ITEM
    //             |--------------------------------------------------------------------------
    //             */

    //             \App\Models\LockerRegistrationItem::create([

    //                 'registration_id' => $registration->id,

    //                 'locker_id' => $locker->id,
    //                 'locker_number' => $locker->locker_number,

    //                 'size' => $locker->locker_size ?? '',
    //                 'type' => $locker->locker_type ?? '',

    //                 'locker_group' => $locker->locker_group ?? '',
    //                 'locker_position' => $locker->locker_row_column ?? '',

    //                 'start_date' => $contractStartDate,
    //                 'end_date' => $contractEndDate,

    //                 'amount' => $lockerAmount,

    //                 'status' => 'active',

    //                 'added_at' => now(),
    //             ]);

    //             /*
    //             |--------------------------------------------------------------------------
    //             | UPDATE LOCKER
    //             |--------------------------------------------------------------------------
    //             */

    //             $locker->update([
    //                 'status' => 'Occupied'
    //             ]);

    //             /*
    //             |--------------------------------------------------------------------------
    //             | INVOICE
    //             |--------------------------------------------------------------------------
    //             */

    //             \App\Models\Invoice::create([

    //                 'client_id' => $client->id,
    //                 'registration_id' => $registration->id,

    //                 'invoice_number' => \App\Models\Invoice::generateInvoiceNumber(),

    //                 'invoice_date' => now(),
    //                 'due_date' => now()->addDays(30),

    //                 'tax_amount' => $taxAmount,

    //                 'stamping_fee' => $stampingFee,
    //                 'key_deposit' => $keyDeposit,
    //                 'insurance_charges' => $insuranceCharges,
    //                 'discount_amount' => $discountAmount,

    //                 'total_amount' => $finalAmount,

    //                 'paid_amount' => 0,
    //                 'balance_amount' => $finalAmount,

    //                 'payment_mode' => $client->payment_mode ?? 'cash',

    //                 'status' => 'pending',
    //                 'payment_type' => 'create',

    //                 'client_name' => $client->name,
    //                 'client_phone' => $client->phone,
    //                 'client_address' => $client->address,

    //                 'account_type_id' => $client->account_type_id,

    //                 'email' => $client->email,

    //                 'postal_code' => $client->postal_code ?? 0,

    //                 'city' => $client->city_id ?? 0,
    //                 'state' => $client->state_id ?? 0,
    //                 'country' => $client->country_id ?? 0,

    //                 'registration_number' => $client->registration_number,

    //                 'tax_type' => $client->tax_type,

    //                 'safebox_count' => 1,

    //                 'payment_terms' => $paymentTerms,

    //                 'referred_member_by' => $client->referred_member_by,
    //                 'referred_commission' => $client->referred_commission,

    //                 'commission_used' => 0,

    //                 'registration_date' => now(),

    //                 'locker_id' => $locker->id,
    //                 'locker_number' => $locker->locker_number,

    //                 'size' => $locker->locker_size ?? '',
    //                 'type' => $locker->locker_type ?? '',

    //                 'locker_group' => $locker->locker_group ?? '',
    //                 'locker_position' => $locker->locker_row_column ?? '',

    //                 'start_date' => $contractStartDate,
    //                 'end_date' => $contractEndDate,

    //                 'amount' => $lockerAmount,
    //             ]);

    //             DB::commit();

    //             $results[] = [
    //                 'name' => $client->name,
    //                 'phone' => $client->phone,
    //                 'locker' => $locker->locker_number,
    //                 'status' => 'success',
    //                 'message' => 'Inserted Successfully'
    //             ];
    //         } catch (\Exception $e) {

    //             DB::rollBack();

    //             $results[] = [
    //                 'name' => $row[3] ?? '',
    //                 'phone' => $row[4] ?? '',
    //                 'locker' => $lockerNumber ?? '',
    //                 'status' => 'failed',
    //                 'message' => $e->getMessage()
    //             ];
    //         }
    //     }

    //     fclose($file);

    //     return back()->with([
    //         'success' => 'Clients Imported Successfully',
    //         'import_results' => $results
    //     ]);
    // }
    
    public function import(Request $request)
    {
    //     echo "<pre>";

    // $file = $request->file('file');

    // $handle = fopen($file->getRealPath(), 'r');

    // // Header
    // $header = fgetcsv($handle);

    // print_r($header);

    // echo "\n\n====================\n\n";

    // while (($row = fgetcsv($handle, 1000, ",")) !== false) {

    //     print_r($row);

    //     echo "\n----------------------\n";
    // }

    // fclose($handle);

    // exit;


        $request->validate([
            'file' => 'required|mimes:csv,txt'
        ]);

        if (!$request->hasFile('file')) {
            return back()->with('error', 'No file uploaded');
        }

        /*
        |--------------------------------------------------------------------------
        | CREATE IMPORT FOLDER
        |--------------------------------------------------------------------------
        */

        $path = public_path('client/import');

        if (!file_exists($path)) {
            mkdir($path, 0777, true);
        }

        /*
        |--------------------------------------------------------------------------
        | SAVE FILE
        |--------------------------------------------------------------------------
        */

        $fileName = time() . '_' . $request->file('file')->getClientOriginalName();

        $request->file('file')->move($path, $fileName);

        $filePath = $path . '/' . $fileName;

        /*
        |--------------------------------------------------------------------------
        | OPEN CSV
        |--------------------------------------------------------------------------
        */

        $file = fopen($filePath, 'r');

        if (!$file) {
            return back()->with('error', 'Unable to open CSV file');
        }

        $results = [];

        // Skip Header
        fgetcsv($file);

        /*
        |--------------------------------------------------------------------------
        | LOOP CSV ROWS
        |--------------------------------------------------------------------------
        */

        while (($row = fgetcsv($file, 1000, ",")) !== false) {

            DB::beginTransaction();

            try {

                /*
                |--------------------------------------------------------------------------
                | ACCOUNT TYPE
                |--------------------------------------------------------------------------
                */
                $accountTypeId = $row[1] ?? 1;
                /*
                |--------------------------------------------------------------------------
                | LOCKER FETCH
                |--------------------------------------------------------------------------
                */
                $lockerNumber = trim($row[24] ?? '');
                $lockerNumber = str_pad($lockerNumber, 4, '0', STR_PAD_LEFT);
                $locker = \App\Models\Locker::where('locker_number', $lockerNumber)->first();
                if (!$locker) {
                    $results[] = [
                        'name' => $row[3] ?? '',
                        'phone' => $row[4] ?? '',
                        'locker' => $lockerNumber,
                        'status' => 'failed',
                        'message' => 'Locker Not Found'
                    ];

                    DB::rollBack();

                    continue;
                }

                /*
                |--------------------------------------------------------------------------
                | CHECK LOCKER STATUS
                |--------------------------------------------------------------------------
                */

                if ($locker->status != 'Available') {

                    $results[] = [
                        'name' => $row[3] ?? '',
                        'phone' => $row[4] ?? '',
                        'locker' => $lockerNumber,
                        'status' => 'failed',
                        'message' => 'Locker Already Occupied'
                    ];

                    DB::rollBack();

                    continue;
                }

                $lockerGroupName = optional($locker->lockerGroup)->name ?? '';
                if ($lockerGroupName === '' && !empty($locker->locker_group_id)) {
                    $lockerGroupName = (string) LockerGroup::whereKey($locker->locker_group_id)->value('name');
                }

                if ($lockerGroupName === '') {
                    Log::warning('Import: locker group name missing', [
                        'locker_id' => $locker->id,
                        'locker_number' => $locker->locker_number,
                        'locker_group_id' => $locker->locker_group_id,
                    ]);
                }

                /*
                |--------------------------------------------------------------------------
                | TAX
                |--------------------------------------------------------------------------
                */

                $taxType = strtoupper(trim($row[13] ?? 'GST'));

                $stampingFee = (float) ($row[14] ?? 0);
                $keyDeposit = (float) ($row[15] ?? 0);
                $insuranceCharges = (float) ($row[16] ?? 0);
                $discountAmount = (float) ($row[17] ?? 0);

                $lockerAmount = $locker->locker_amount ?? 0;

                $subtotal = $lockerAmount - $discountAmount;

                $taxAmount = 0;

                if ($taxType == 'GST' || $taxType == 'SST') {
                    $taxAmount = ($subtotal * 8) / 100;
                }

                $finalAmount =
                    $subtotal +
                    $taxAmount +
                    $stampingFee +
                    $keyDeposit +
                    $insuranceCharges;
                /*
                |--------------------------------------------------------------------------
                | DATES
                |--------------------------------------------------------------------------
                */
                $contractStartDate = !empty($row[28])
                    ? date('Y-m-d', strtotime($row[28]))
                    : null;
                $contractEndDate = !empty($row[29])
                    ? date('Y-m-d', strtotime($row[29]))
                    : null;
                    // echo $contractEndDate; exit;
                $paymentTerms = $row[19] ?? 1;
                /*
                |--------------------------------------------------------------------------
                | CLIENT CREATE
                |--------------------------------------------------------------------------
                */
                $client = \App\Models\Client::create([
                    'status_id' => $row[0] ?? 1,
                    'account_type_id' => $accountTypeId,
                    'auth_count' => $row[2] ?? 1,
                    'name' => $row[3] ?? '',
                    'phone' => $row[4] ?? '',
                    'email' => $row[5] ?? null,
                    'landline' => $row[6] ?? '',
                    'address' => $row[7] ?? '',
                    'country_id' => $row[8] ?? null,
                    'state_id' => $row[9] ?? null,
                    'city_id' => $row[10] ?? null,
                    // 'postal_code' => $row[11] ?? null,
                    'postal_code' => (
                        isset($row[11]) &&
                        trim($row[11]) !== '' &&
                        strtoupper(trim($row[11])) !== 'NULL'
                    )
                        ? trim($row[11])
                        : null,
                    'registration_number' => $row[12] ?? '',
                    'tax_type' => $taxType,
                    'tax_amount' => $taxAmount,
                    'stamping_fee' => $stampingFee,
                    'key_deposit' => $keyDeposit,
                    'insurance_charges' => $insuranceCharges,
                    'discount_amount' => $discountAmount,
                    'final_amount' => $finalAmount,
                    'payment_mode' => $row[18] ?? 'cash',
                    'payment_terms' => $paymentTerms,
                    'contract_start_date' => $contractStartDate,
                    'contract_end_date' => $contractEndDate,
                    'referred_member_by' =>
                        !empty($row[22]) && $row[22] != 'NULL'
                        ? $row[22]
                        : null,
                    'referred_commission' => $row[23] ?? 0,
                    'selected_lockers_data' => json_encode([
                        [
                            'id' => $locker->id,
                            'number' => $locker->locker_number,
                            'size' => $locker->locker_size ?? '',
                            'type' => $locker->locker_type ?? '',
                            'locker_group' => $lockerGroupName,
                            'locker_position' => $locker->locker_row_column ?? '',
                            'amount' => $lockerAmount,
                        ]
                    ]),
                    'is_appointment' => 1,
                    'tenant_id' => config('app.default_tenant_id', 1),
                    'account_number' => $row[25] ?? 0,
                    'i@port' => $row[26] ?? 0,
                    'nric' => $row[27] ?? 0,
                    'import_contract_start_date' => $row[20] ?? 0,
                    'import_contract_end_date' => $row[21] ?? 0,
                ]);
                /*
                |--------------------------------------------------------------------------
                | REGISTRATION
                |--------------------------------------------------------------------------
                */
                $registration = \App\Models\LockerRegistration::create([
                    'client_id' => $client->id,
                    'auth_count' => $client->auth_count,
                    'locker_password' => '123456',
                    'registration_date' => now()->toDateString(),
                    'safebox_count' => 1,
                    'contract_start_date' => $contractStartDate,
                    'contract_end_date' => $contractEndDate,
                    'payment_terms' => $paymentTerms,
                    'stamping_fee' => $stampingFee,
                    'key_deposit' => $keyDeposit,
                    'insurance_charges' => $insuranceCharges,
                    'discount_amount' => $discountAmount,
                    'tax_amount' => $taxAmount,
                    'referred_member_by' => $client->referred_member_by,
                    'referred_commission' => $client->referred_commission,
                    'status' => 'Active',
                ]);
                /*
                |--------------------------------------------------------------------------
                | REGISTRATION ITEM
                |--------------------------------------------------------------------------
                */
                \App\Models\LockerRegistrationItem::create([
                    'registration_id' => $registration->id,
                    'locker_id' => $locker->id,
                    'locker_number' => $locker->locker_number,
                    'size' => $locker->locker_size ?? '',
                    'type' => $locker->locker_type ?? '',
                    'locker_group' => $lockerGroupName,
                    'locker_position' => $locker->locker_row_column ?? '',
                    'start_date' => $contractStartDate,
                    'end_date' => $contractEndDate,
                    'amount' => $lockerAmount,
                    'status' => 'active',
                    'added_at' => now(),
                ]);
                /*
                |--------------------------------------------------------------------------
                | UPDATE LOCKER
                |--------------------------------------------------------------------------
                */
                $locker->update([
                    'status' => 'Occupied'
                ]);
                /*
                |--------------------------------------------------------------------------
                | INVOICE
                |--------------------------------------------------------------------------
                */
                \App\Models\Invoice::create([
                    'client_id' => $client->id,
                    'registration_id' => $registration->id,
                    'invoice_number' => \App\Models\Invoice::generateInvoiceNumber(),
                    'invoice_date' => now(),
                    'due_date' => now()->addDays(30),
                    'tax_amount' => $taxAmount,
                    'stamping_fee' => $stampingFee,
                    'key_deposit' => $keyDeposit,
                    'insurance_charges' => $insuranceCharges,
                    'discount_amount' => $discountAmount,
                    'total_amount' => $finalAmount,
                    'paid_amount' => 0,
                    'balance_amount' => $finalAmount,
                    'payment_mode' => $client->payment_mode ?? 'cash',
                    'status' => 'pending',
                    'payment_type' => 'create',
                    'client_name' => $client->name,
                    'client_phone' => $client->phone,
                    'client_address' => $client->address,
                    'account_type_id' => $client->account_type_id,
                    'email' => $client->email,
                    'postal_code' => $client->postal_code ?? 0,
                    'city' => $client->city_id ?? 0,
                    'state' => $client->state_id ?? 0,
                    'country' => $client->country_id ?? 0,
                    'registration_number' => $client->registration_number,
                    'tax_type' => $client->tax_type,
                    'safebox_count' => 1,
                    'payment_terms' => $paymentTerms,
                    'referred_member_by' => $client->referred_member_by,
                    'referred_commission' => $client->referred_commission,
                    'commission_used' => 0,
                    'registration_date' => now(),
                    'locker_id' => $locker->id,
                    'locker_number' => $locker->locker_number,
                    'size' => $locker->locker_size ?? '',
                    'type' => $locker->locker_type ?? '',
                    'locker_group' => $locker_groupname ?? '',
                    'locker_position' => $locker->locker_row_column ?? '',
                    'start_date' => $contractStartDate,
                    'end_date' => $contractEndDate,
                    'amount' => $lockerAmount,
                ]);

                DB::commit();

                $results[] = [
                    'name' => $client->name,
                    'phone' => $client->phone,
                    'locker' => $locker->locker_number,
                    'status' => 'success',
                    'message' => 'Inserted Successfully'
                ];

            } catch (\Exception $e) {

                DB::rollBack();

                $results[] = [
                    'name' => $row[3] ?? '',
                    'phone' => $row[4] ?? '',
                    'locker' => $lockerNumber ?? '',
                    'status' => 'failed',
                    'message' => $e->getMessage()
                ];
            }
        }

        fclose($file);

        return back()->with([
            'success' => 'Clients Imported Successfully',
            'import_results' => $results
        ]);
    }
    
}
