<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Branch;
use App\Models\Customer;
use App\Models\User;
use App\Services\AuditService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\View\View;

class CustomerController extends Controller
{
    public function __construct(
        protected AuditService $auditService,
    ) {}

    public function index(Request $request): View
    {
        $query = Customer::query()->with(['branch', 'relationshipOfficer']);

        if ($search = $request->input('search')) {
            $query->where(function ($q) use ($search) {
                $q->where('customer_no', 'like', "%{$search}%")
                    ->orWhere('first_name', 'like', "%{$search}%")
                    ->orWhere('last_name', 'like', "%{$search}%")
                    ->orWhere('business_name', 'like', "%{$search}%")
                    ->orWhere('email', 'like', "%{$search}%")
                    ->orWhere('phone', 'like', "%{$search}%");
            });
        }

        if ($type = $request->input('type')) {
            $query->where('type', $type);
        }

        if ($status = $request->input('status')) {
            $query->where('status', $status);
        }

        if ($kyc = $request->input('kyc_status')) {
            $query->where('kyc_status', $kyc);
        }

        $customers = $query->latest()->paginate(20)->withQueryString();

        return view('admin.customers.index', compact('customers'));
    }

    public function create(): View
    {
        $branches = Branch::query()->where('status', 'active')->orderBy('name')->get();
        $officers = User::query()->where('status', 'active')->orderBy('name')->get();

        return view('admin.customers.create', compact('branches', 'officers'));
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'branch_id' => ['nullable', 'exists:branches,id'],
            'type' => ['required', 'in:individual,sme,corporate,contractor,government'],
            'title' => ['nullable', 'string', 'max:20'],
            'first_name' => ['nullable', 'string', 'max:100'],
            'last_name' => ['nullable', 'string', 'max:100'],
            'business_name' => ['nullable', 'string', 'max:200'],
            'email' => ['nullable', 'email', 'max:150'],
            'phone' => ['required', 'string', 'max:30'],
            'alt_phone' => ['nullable', 'string', 'max:30'],
            'gender' => ['nullable', 'in:male,female,other'],
            'date_of_birth' => ['nullable', 'date'],
            'bvn' => ['nullable', 'string', 'max:11'],
            'nin' => ['nullable', 'string', 'max:20'],
            'rc_number' => ['nullable', 'string', 'max:50'],
            'tin' => ['nullable', 'string', 'max:50'],
            'address' => ['nullable', 'string', 'max:255'],
            'city' => ['nullable', 'string', 'max:80'],
            'state' => ['nullable', 'string', 'max:80'],
            'occupation' => ['nullable', 'string', 'max:120'],
            'employer' => ['nullable', 'string', 'max:150'],
            'monthly_income' => ['nullable', 'numeric', 'min:0'],
            'risk_rating' => ['nullable', 'in:low,medium,high'],
            'kyc_status' => ['nullable', 'in:pending,in_review,verified,rejected'],
            'portal_enabled' => ['nullable', 'boolean'],
            'portal_password' => ['nullable', 'string', 'min:8'],
            'relationship_officer_id' => ['nullable', 'exists:users,id'],
            'status' => ['nullable', 'in:active,inactive,blacklisted,closed'],
            'notes' => ['nullable', 'string'],
        ]);

        $validated['customer_no'] = $this->generateCustomerNo();
        $validated['uuid'] = (string) Str::uuid();
        $validated['created_by'] = auth()->id();
        $validated['portal_enabled'] = $request->boolean('portal_enabled');

        $customer = Customer::query()->create($validated);

        $this->auditService->log('create', 'customers', 'customer', $customer->id, null, $customer->toArray());

        return redirect()
            ->route('admin.customers.show', $customer)
            ->with('success', 'Customer created successfully.');
    }

    public function show(Customer $customer): View
    {
        $customer->load([
            'branch',
            'relationshipOfficer',
            'accounts',
            'loans.loanProduct',
            'investments',
            'kycDocuments',
        ]);

        return view('admin.customers.show', compact('customer'));
    }

    public function edit(Customer $customer): View
    {
        $branches = Branch::query()->where('status', 'active')->orderBy('name')->get();
        $officers = User::query()->where('status', 'active')->orderBy('name')->get();

        return view('admin.customers.edit', compact('customer', 'branches', 'officers'));
    }

    public function update(Request $request, Customer $customer): RedirectResponse
    {
        $validated = $request->validate([
            'branch_id' => ['nullable', 'exists:branches,id'],
            'type' => ['required', 'in:individual,sme,corporate,contractor,government'],
            'title' => ['nullable', 'string', 'max:20'],
            'first_name' => ['nullable', 'string', 'max:100'],
            'last_name' => ['nullable', 'string', 'max:100'],
            'business_name' => ['nullable', 'string', 'max:200'],
            'email' => ['nullable', 'email', 'max:150'],
            'phone' => ['required', 'string', 'max:30'],
            'alt_phone' => ['nullable', 'string', 'max:30'],
            'gender' => ['nullable', 'in:male,female,other'],
            'date_of_birth' => ['nullable', 'date'],
            'bvn' => ['nullable', 'string', 'max:11'],
            'nin' => ['nullable', 'string', 'max:20'],
            'rc_number' => ['nullable', 'string', 'max:50'],
            'tin' => ['nullable', 'string', 'max:50'],
            'address' => ['nullable', 'string', 'max:255'],
            'city' => ['nullable', 'string', 'max:80'],
            'state' => ['nullable', 'string', 'max:80'],
            'occupation' => ['nullable', 'string', 'max:120'],
            'employer' => ['nullable', 'string', 'max:150'],
            'monthly_income' => ['nullable', 'numeric', 'min:0'],
            'risk_rating' => ['nullable', 'in:low,medium,high'],
            'kyc_status' => ['nullable', 'in:pending,in_review,verified,rejected'],
            'portal_enabled' => ['nullable', 'boolean'],
            'portal_password' => ['nullable', 'string', 'min:8'],
            'relationship_officer_id' => ['nullable', 'exists:users,id'],
            'status' => ['nullable', 'in:active,inactive,blacklisted,closed'],
            'notes' => ['nullable', 'string'],
        ]);

        $old = $customer->toArray();
        $validated['portal_enabled'] = $request->boolean('portal_enabled');

        if (empty($validated['portal_password'])) {
            unset($validated['portal_password']);
        }

        $customer->update($validated);

        $this->auditService->log('update', 'customers', 'customer', $customer->id, $old, $customer->fresh()->toArray());

        return redirect()
            ->route('admin.customers.show', $customer)
            ->with('success', 'Customer updated successfully.');
    }

    protected function generateCustomerNo(): string
    {
        $last = Customer::query()
            ->where('customer_no', 'like', 'FFC-C-%')
            ->orderByDesc('id')
            ->value('customer_no');

        $next = 1;

        if ($last && preg_match('/FFC-C-(\d+)$/', $last, $matches)) {
            $next = (int) $matches[1] + 1;
        }

        return 'FFC-C-'.str_pad((string) $next, 6, '0', STR_PAD_LEFT);
    }
}
