<?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\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);

        // Debug: Check first client and its status
        // $firstClient = $clients->first();
        // if ($firstClient) {
        //     dd([
        //         'client_id' => $firstClient->id,
        //         'status_id' => $firstClient->status_id,
        //         'status_object' => $firstClient->status,
        //         'status_name' => $firstClient->status ? $firstClient->status->name : 'NULL',
        //         'all_relationships' => $firstClient->getRelations()
        //     ]);
        // }

        // echo "<pre>";
        // print_r($clients->toArray());
        // echo "</pre>";
        // exit;

        return view('clients.index', compact('clients'));
    }

    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|string|max:20',
    //         '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',
    //         'registration_number' => 'nullable|string|max:30',
    //         'safebox_count' => 'required|numeric',
    //         'discount_amount' => 'nullable|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_by' => 'nullable|string|max:50',
    //         'referred_commission' => 'nullable|numeric',
    //     ]);

    //     if ($validator->fails()) {
    //         return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
    //     }

    //     try {
    //         DB::beginTransaction();

    //         // Custom validation for selected_lockers_data structure
    //         $lockersData = json_decode($request->selected_lockers_data, true);
    //         if ($lockersData === null) {
    //             return response()->json(['success' => false, 'message' => 'Invalid locker data format'], 422);
    //         }

    //         if (!is_array($lockersData)) {
    //             return response()->json(['success' => false, 'message' => 'Locker data must be an array'], 422);
    //         }

    //         // Extract locker numbers for safebox column
    //         $lockerNumbers = [];
    //         $commonPassword = $this->generateLockerPassword(); // Generate one password for all lockers

    //         foreach ($lockersData as $locker) {
    //             if (!isset($locker['id']) || !isset($locker['number']) || !isset($locker['size']) || !isset($locker['type']) || !isset($locker['available'])) {
    //                 return response()->json(['success' => false, 'message' => 'Each locker must have id, number, size, type, and available fields'], 422);
    //             }

    //             // Collect locker id and number with same password
    //             $lockerNumbers[] = [
    //                 'id' => $locker['id'],
    //                 'number' => $locker['number'],
    //             ];

    //             // Check if locker is available in database
    //             $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);
    //             }
    //         }

    //         $client = Client::create([
    //             // Client Table Data
    //             'name' => $request->name,
    //             'phone' => $request->phone,
    //             'landline' => $request->landline,
    //             'address' => $request->address,
    //             'city' => $request->city,
    //             'state' => $request->state,
    //             'country' => $request->country,
    //             'account_type_id' => $request->account_type,
    //             'auth_count' => $request->auth_count,
    //             'safebox_count' => $request->safebox_count,
    //             'safebox' => json_encode($lockerNumbers),
    //             'registration_number' => $request->registration_number,
    //             'contract_start_date' => $request->contract_start_date,
    //             'contract_end_date' => $request->contract_end_date,
    //             'payment_terms' => $request->payment_terms,
    //             'is_appointment' => '0',
    //             'status_id' => '1',
    //             'tenant_id' => config('app.default_tenant_id', 1),
    //         ]);

    //         // Commission
    //         $commission = $request->referred_commission;

    //         if ($commission > 0) {
    //             $referedClient = ReferredClient::create([
    //                 'client_id' => $client->id,
    //                 'referred_by_client_id' => $request->referred_by,
    //                 // 'reference_type' => $request->reference_type,
    //                 'referred_member_id' => $request->referred_by,
    //                 'referred_commission' => $request->referred_commission,
    //                 'referral_date' => now(),
    //                 'status' => 'pending',
    //             ]);
    //         }

    //         $discountAmount = $request->discount_amount / $request->safebox_count;

    //         // Insert into locker-registration table
    //         foreach ($lockersData as $index => $locker) {
    //             \App\Models\LockerRegistration::create([
    //                 'client_id' => $client->id,
    //                 'locker_id' => $locker['id'],
    //                 'membership_plan_id' => $request->payment_terms,
    //                 'locker_password' => $commonPassword,
    //                 'start_date' => $request->contract_start_date,
    //                 'end_date' => $request->contract_end_date,
    //                 'registration_date' => now(),
    //                 'locker_amount' => $locker['amount'],
    //                 'locker_discount' => $discountAmount,
    //                 'commission_amount' => 0,
    //                 'total_commission_used' => 0,
    //                 'status' => 'Pending',
    //             ]);

    //             // Update locker status to 'Occupied'
    //             \App\Models\Locker::where('id', $locker['id'])->update(['status' => 'Occupied']);
    //         }

    //         DB::commit();

    //         return response()->json([
    //             'success' => true,
    //             'message' => 'Client created successfully',
    //             'redirect' => route('customers.members', ['client' => $client->id])
    //         ]);
    //     } catch (\Exception $e) {
    //         DB::rollBack();

    //         return response()->json([
    //             'success' => false,
    //             'message' => 'Error creating client: ' . $e->getMessage(),
    //             'errors' => []
    //         ], 500);
    //     }
    // }

    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|string|max:20',
            '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',
            'stamping_fee' => 'required|numeric',
            'key_deposit' => 'required|numeric',
            'insurance_charges' => 'required|numeric',
            'discount_amount' => 'required|numeric',
            '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,
                '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,
                '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,
                '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;
            }

            // ✅ Create Payment
            \App\Models\Payment::create([
                'registration_id' => $registration->id,
                'payment_mode' => $request->payment_mode,
                'total_amount' => $totalAmount,
                'paid_amount' => $totalAmount,
                'balance_amount' => 0,
                'payment_date' => now(),
                'status' => 'paid',
            ]);

            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', 'lockerRegistrations.locker', 'lockerRegistrations.membershipPlan', 'customerMembers'])
            ->findOrFail($id);

        return view('clients.show', compact('client'));
    }

    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.create-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|string|max:20',
            '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()->findOrFail($customerId);
        $members = $client->customerMembers()
            ->with('statusRelation')
            ->where('is_active', 1)
            ->get();

        return view('clients.members', compact('client', 'members'));
    }

    public function storeMember(Request $request, $customerId)
    {
        $request->merge([
            'status' => 2
        ]);

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|min:2|max:255',
            'email' => 'nullable|email|unique:customer_members,email,NULL,id,client_id,' . $customerId,
            'mobile' => 'required|digits:10',
            'proof_type' => 'required|string|in:passport,ic_number',
            'proof_number' => 'required|string|min:5|max:100',
            '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();
            if ($currentMembersCount >= $client->auth_count) {
                return response()->json([
                    'success' => false,
                    'message' => "Cannot add more members. Maximum limit reached: {$currentMembersCount}/{$client->auth_count}"
                ], 422);
            }

            $member = $client->customerMembers()->create([
                'name' => $request->name,
                'email' => $request->email,
                'mobile' => $request->mobile,
                'proof_type' => $request->proof_type,
                'proof_number' => $request->proof_number,
                '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,
                    '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,
                    'email' => $member->email,
                    'mobile' => $member->mobile,
                    'proof_type' => $member->proof_type,
                    'proof_number' => $member->proof_number,
                    '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',
            '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',
            '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,
                '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'),
            ];

            $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
            if ($newAuthCount > $client->auth_count) {
                return response()->json([
                    'success' => false,
                    'message' => "Minimum allowed ({$newAuthCount}) cannot be more than maximum limit ({$client->auth_count})"
                ], 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);
        }
    }

    /**
     * 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;
    }
}
