<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\CustomerMember;
use App\Models\Locker;
use App\Models\LockerRegistration;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class ClientController extends Controller
{
    /**
     * Get all clients
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'search' => 'nullable|string|max:255',
            'status' => 'nullable|string|max:100',
            'account_type' => 'nullable|integer|exists:account_types,id',
            'per_page' => 'nullable|integer|min:1|max:100',
        ]);

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

        $query = Client::with(['status', 'accountType', 'customerMembers'])
            ->byTenant();

        // Apply filters
        if ($request->search) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('phone', 'like', "%{$search}%")
                  ->orWhere('contact_person', 'like', "%{$search}%");
            });
        }

        if ($request->status) {
            $query->whereHas('status', function ($q) use ($request) {
                $q->where('name', $request->status);
            });
        }

        if ($request->account_type) {
            $query->where('account_type_id', $request->account_type);
        }

        $perPage = $request->per_page ?? 20;
        $clients = $query->orderBy('id', 'desc')->paginate($perPage);

        return response()->json([
            'success' => true,
            'message' => 'Clients retrieved successfully',
            'data' => $clients->items(),
            'pagination' => [
                'current_page' => $clients->currentPage(),
                'last_page' => $clients->lastPage(),
                'per_page' => $clients->perPage(),
                'total' => $clients->total(),
                'from' => $clients->firstItem(),
                'to' => $clients->lastItem(),
            ]
        ]);
    }

    /**
     * Get client details by ID
     *
     * @param Request $request
     * @param int $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function show(Request $request, $id)
    {
        $client = Client::with([
            'status', 
            'accountType', 
            'customerMembers' => function ($query) {
                $query->where('is_active', 1)->with('statusRelation');
            },
            'lockerRegistrations' => function ($query) {
                $query->with(['locker', 'membershipPlan'])->orderBy('created_at', 'desc');
            },
            'contacts'
        ])->byTenant()->find($id);

        if (!$client) {
            return response()->json([
                'success' => false,
                'message' => 'Client not found'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'message' => 'Client details retrieved successfully',
            'data' => [
                'id' => $client->id,
                'name' => $client->name,
                'email' => $client->email,
                'phone' => $client->phone,
                'alternate_phone' => $client->alternate_phone,
                'address' => $client->address,
                'city' => $client->city,
                'state' => $client->state,
                'country' => $client->country,
                'postal_code' => $client->postal_code,
                'website' => $client->website,
                'contact_person' => $client->contact_person,
                'account_type' => $client->accountType ? [
                    'id' => $client->accountType->id,
                    'name' => $client->accountType->type_name
                ] : null,
                'auth_count' => $client->auth_count,
                'authorized_count' => $client->authorized_count,
                'date_of_birth' => $client->date_of_birth,
                'proof_type' => $client->proof_type,
                'proof_number' => $client->proof_number,
                'safebox_count' => $client->safebox_count,
                'safebox' => $client->safebox,
                'gst_number' => $client->gst_number,
                'pan_number' => $client->pan_number,
                'payment_terms' => $client->payment_terms,
                'contract_start_date' => $client->contract_start_date,
                'contract_end_date' => $client->contract_end_date,
                'status' => $client->status ? [
                    'id' => $client->status->id,
                    'name' => $client->status->name
                ] : null,
                'is_appointment' => $client->is_appointment,
                'notes' => $client->notes,
                'members' => $client->customerMembers->map(function ($member) {
                    return [
                        '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,
                        'required_auth' => $member->required_auth,
                        'status' => $member->statusRelation->name ?? 'active',
                        'is_active' => $member->is_active
                    ];
                }),
                'locker_registrations' => $client->lockerRegistrations->map(function ($registration) {
                    return [
                        'id' => $registration->id,
                        'locker' => $registration->locker ? [
                            'id' => $registration->locker->id,
                            'locker_number' => $registration->locker->locker_number,
                            'locker_size' => $registration->locker->locker_size,
                            'locker_type' => $registration->locker->locker_type
                        ] : null,
                        'membership_plan' => $registration->membershipPlan ? [
                            'id' => $registration->membershipPlan->id,
                            'name' => $registration->membershipPlan->name
                        ] : null,
                        'start_date' => $registration->start_date,
                        'end_date' => $registration->end_date,
                        'registration_date' => $registration->registration_date,
                        'status' => $registration->status
                    ];
                }),
                'contacts' => $client->contacts->map(function ($contact) {
                    return [
                        'id' => $contact->id,
                        'name' => $contact->name,
                        'email' => $contact->email,
                        'phone' => $contact->phone,
                        'position' => $contact->position,
                        'department' => $contact->department,
                        'is_primary' => $contact->is_primary
                    ];
                }),
                'created_at' => $client->created_at,
                'updated_at' => $client->updated_at
            ]
        ]);
    }

    /**
     * Get client members
     *
     * @param Request $request
     * @param int $clientId
     * @return \Illuminate\Http\JsonResponse
     */
    public function members(Request $request, $clientId)
    {
        $client = Client::byTenant()->find($clientId);
        if (!$client) {
            return response()->json([
                'success' => false,
                'message' => 'Client not found'
            ], 404);
        }

        $members = $client->customerMembers()
            ->with('statusRelation')
            ->where('is_active', 1)
            ->get();

        return response()->json([
            'success' => true,
            'message' => 'Client members retrieved successfully',
            'data' => [
                'client' => [
                    'id' => $client->id,
                    'name' => $client->name,
                    'email' => $client->email,
                    'phone' => $client->phone
                ],
                'members' => $members->map(function ($member) {
                    return [
                        '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,
                        'required_auth' => $member->required_auth,
                        'status' => $member->statusRelation->name ?? 'active',
                        'is_active' => $member->is_active,
                        'authenticated_methods' => $member->authenticated_methods,
                        'verified_methods' => $member->verified_methods,
                        'fully_verified' => $member->fully_verified
                    ];
                })
            ]
        ]);
    }

    /**
     * Get client lockers
     *
     * @param Request $request
     * @param int $clientId
     * @return \Illuminate\Http\JsonResponse
     */
    public function lockers(Request $request, $clientId)
    {
        $client = Client::byTenant()->find($clientId);
        if (!$client) {
            return response()->json([
                'success' => false,
                'message' => 'Client not found'
            ], 404);
        }

        $registrations = $client->lockerRegistrations()
            ->with(['locker', 'membershipPlan'])
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json([
            'success' => true,
            'message' => 'Client lockers retrieved successfully',
            'data' => [
                'client' => [
                    'id' => $client->id,
                    'name' => $client->name,
                    'email' => $client->email,
                    'phone' => $client->phone
                ],
                'lockers' => $registrations->map(function ($registration) {
                    return [
                        'id' => $registration->id,
                        'locker' => $registration->locker ? [
                            'id' => $registration->locker->id,
                            'locker_number' => $registration->locker->locker_number,
                            'locker_size' => $registration->locker->locker_size,
                            'locker_type' => $registration->locker->locker_type,
                            'locker_row_column' => $registration->locker->locker_row_column,
                            'status' => $registration->locker->status,
                            'status_color' => $registration->locker->status_color,
                            'status_icon' => $registration->locker->status_icon
                        ] : null,
                        'membership_plan' => $registration->membershipPlan ? [
                            'id' => $registration->membershipPlan->id,
                            'name' => $registration->membershipPlan->name,
                            'duration_days' => $registration->membershipPlan->duration_days,
                            'duration_months' => $registration->membershipPlan->duration_months,
                            'price' => $registration->membershipPlan->price
                        ] : null,
                        'start_date' => $registration->start_date,
                        'end_date' => $registration->end_date,
                        'registration_date' => $registration->registration_date,
                        'status' => $registration->status,
                        'locker_password' => $registration->locker_password
                    ];
                })
            ]
        ]);
    }

    /**
     * Get client statistics
     *
     * @param Request $request
     * @param int $clientId
     * @return \Illuminate\Http\JsonResponse
     */
    public function statistics(Request $request, $clientId)
    {
        $client = Client::byTenant()->find($clientId);
        if (!$client) {
            return response()->json([
                'success' => false,
                'message' => 'Client not found'
            ], 404);
        }

        $totalMembers = $client->customerMembers()->count();
        $activeMembers = $client->customerMembers()->where('is_active', 1)->count();
        $verifiedMembers = $client->customerMembers()->where('is_finger_verified', 1)->count();
        $requiredMembers = $client->customerMembers()->where('required_auth', 1)->count();

        $totalLockers = $client->lockerRegistrations()->count();
        $activeLockers = $client->lockerRegistrations()->where('status', 'Active')->count();
        $expiredLockers = $client->lockerRegistrations()
            ->where('status', '!=', 'Active')
            ->where('end_date', '<', now())
            ->count();

        return response()->json([
            'success' => true,
            'message' => 'Client statistics retrieved successfully',
            'data' => [
                'client' => [
                    'id' => $client->id,
                    'name' => $client->name,
                    'email' => $client->email,
                    'phone' => $client->phone
                ],
                'members' => [
                    'total' => $totalMembers,
                    'active' => $activeMembers,
                    'verified' => $verifiedMembers,
                    'required' => $requiredMembers,
                    'verification_rate' => $totalMembers > 0 ? round(($verifiedMembers / $totalMembers) * 100, 2) : 0,
                    'active_rate' => $totalMembers > 0 ? round(($activeMembers / $totalMembers) * 100, 2) : 0
                ],
                'lockers' => [
                    'total' => $totalLockers,
                    'active' => $activeLockers,
                    'expired' => $expiredLockers,
                    'active_rate' => $totalLockers > 0 ? round(($activeLockers / $totalLockers) * 100, 2) : 0
                ],
                'limits' => [
                    'auth_count' => $client->auth_count,
                    'authorized_count' => $client->authorized_count,
                    'members_usage' => "{$totalMembers}/{$client->auth_count}",
                    'required_usage' => "{$requiredMembers}/{$client->authorized_count}"
                ]
            ]
        ]);
    }

    /**
     * Search clients
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function search(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'q' => 'required|string|min:2|max:255',
            'limit' => 'nullable|integer|min:1|max:50',
        ]);

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

        $query = $request->q;
        $limit = $request->limit ?? 20;

        $clients = Client::byTenant()
            ->where(function ($q) use ($query) {
                $q->where('name', 'like', "%{$query}%")
                  ->orWhere('email', 'like', "%{$query}%")
                  ->orWhere('phone', 'like', "%{$query}%")
                  ->orWhere('contact_person', 'like', "%{$query}%");
            })
            ->with(['status'])
            ->limit($limit)
            ->get();

        return response()->json([
            'success' => true,
            'message' => 'Search results retrieved successfully',
            'data' => $clients->map(function ($client) {
                return [
                    'id' => $client->id,
                    'name' => $client->name,
                    'email' => $client->email,
                    'phone' => $client->phone,
                    'contact_person' => $client->contact_person,
                    'status' => $client->status ? $client->status->name : 'unknown'
                ];
            })
        ]);
    }

    /**
     * Get active clients only
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function active(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'per_page' => 'nullable|integer|min:1|max:100',
        ]);

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

        $perPage = $request->per_page ?? 20;
        $clients = Client::byTenant()
            ->active()
            ->with(['status', 'accountType'])
            ->orderBy('name')
            ->paginate($perPage);

        return response()->json([
            'success' => true,
            'message' => 'Active clients retrieved successfully',
            'data' => $clients->items(),
            'pagination' => [
                'current_page' => $clients->currentPage(),
                'last_page' => $clients->lastPage(),
                'per_page' => $clients->perPage(),
                'total' => $clients->total(),
                'from' => $clients->firstItem(),
                'to' => $clients->lastItem(),
            ]
        ]);
    }
}
