<?php

namespace App\Http\Controllers\Membership\Admin;

use App\Http\Controllers\Controller;
use App\Models\LoanApplication;
use App\Models\LoanDocument;
use App\Services\LoanService;
use Illuminate\Http\Request;

class LoanManagementController extends Controller
{
    protected LoanService $loanService;

    public function __construct(LoanService $loanService)
    {
        $this->loanService = $loanService;
    }

    /**
     * Display loan applications dashboard.
     */
    public function index(Request $request)
    {
        abort_unless(auth()->user()->can('view loan applications'), 403);

        $statistics = $this->loanService->getStatistics();

        $query = LoanApplication::with(['member.user', 'loanProduct']);

        if ($request->search) {
            $query->where(function ($q) use ($request) {
                $q->where('reference_number', 'like', "%{$request->search}%")
                    ->orWhereHas('member.user', function ($q) use ($request) {
                        $q->where('name', 'like', "%{$request->search}%")
                            ->orWhere('email', 'like', "%{$request->search}%");
                    });
            });
        }

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

        if ($request->product_id) {
            $query->where('loan_product_id', $request->product_id);
        }

        $applications = $query->latest()->paginate(15);
        $products = \App\Models\LoanProduct::all();

        return view('loans.admin.applications.index', compact('applications', 'products', 'statistics'));
    }

    /**
     * Display loan application details.
     */
    public function show(LoanApplication $loanApplication)
    {
        abort_unless(auth()->user()->can('view loan applications'), 403);

        $loanApplication->load([
            'member.user',
            'member.membershipCategories',
            'loanProduct',
            'documents',
            'repayments',
            'amortizationSchedule',
        ]);

        return view('loans.admin.applications.show', compact('loanApplication'));
    }

    /**
     * Manager review of loan application.
     */
    public function managerReview(Request $request, LoanApplication $loanApplication)
    {
        // Must have the role AND the permission
        abort_unless(
            auth()->user()->hasAnyRole(['Manager', 'Super Manager']) &&
            auth()->user()->can('approve loan applications'),
            403
        );

        $request->validate([
            'approved' => 'required|in:0,1',
            'notes' => 'nullable|string|max:1000',
        ]);

        if (!$loanApplication->canBeApprovedByManager()) {
            return redirect()->back()
                ->withErrors(['error' => 'This application cannot be reviewed at this stage.']);
        }

        // Use boolean() helper — (bool)"0" is true in PHP, so we must not cast directly
        $approved = $request->boolean('approved');

        $this->loanService->managerReview(
            $loanApplication,
            $approved,
            strip_tags($request->notes ?? ''),
            auth()->id()
        );

        return redirect()->route('admin.loan-applications.show', $loanApplication)
            ->with('success', $approved ? 'Application approved and sent for final approval.' : 'Application rejected.');
    }

    /**
     * Super Manager final approval.
     */
    public function superManagerApprove(Request $request, LoanApplication $loanApplication)
    {
        abort_unless(
            auth()->user()->hasRole('Super Manager') &&
            auth()->user()->can('approve loan applications'),
            403
        );

        $request->validate([
            'approved_amount' => 'nullable|numeric|min:0',
            'notes' => 'nullable|string|max:1000',
        ]);

        if (!$loanApplication->canBeApprovedBySuperManager()) {
            return redirect()->back()
                ->withErrors(['error' => 'This application cannot be approved at this stage.']);
        }

        $this->loanService->superManagerApprove(
            $loanApplication,
            $request->approved_amount ? (float) $request->approved_amount : null,
            strip_tags($request->notes ?? ''),
            auth()->id()
        );

        return redirect()->route('admin.loan-applications.show', $loanApplication)
            ->with('success', 'Loan application approved successfully.');
    }

    /**
     * Disburse loan.
     */
    public function disburse(Request $request, LoanApplication $loanApplication)
    {
        abort_unless(auth()->user()->can('disburse loans'), 403);

        $request->validate([
            'phone_number' => 'required|string|regex:/^[0-9]{10,15}$/',
        ], [
            'phone_number.required' => 'Phone number is required for disbursement.',
            'phone_number.regex' => 'Please enter a valid phone number.',
        ]);

        if (!$loanApplication->canBeDisbursed()) {
            return redirect()->back()
                ->withErrors(['error' => 'This loan cannot be disbursed.']);
        }

        // Normalise phone: strip leading zeros and any non-digit characters
        // PaymentService requires MSISDN format (e.g. 256771234567, no leading zero)
        $phone = preg_replace('/\D/', '', $request->phone_number);
        $phone = ltrim($phone, '0');

        $result = $this->loanService->disburseLoan(
            $loanApplication,
            $phone,
            auth()->id()
        );

        if ($result['success']) {
            return redirect()->route('admin.loan-applications.show', $loanApplication)
                ->with('success', $result['message']);
        }

        return redirect()->back()
            ->withErrors(['error' => $result['message']]);
    }

    /**
     * Verify loan document.
     */
    public function verifyDocument(LoanDocument $document)
    {
        abort_unless(auth()->user()->can('verify loan documents'), 403);

        $document->verify(auth()->id());

        return redirect()->back()
            ->with('success', 'Document verified successfully.');
    }

    /**
     * Display active loans.
     */
    public function activeLoans(Request $request)
    {
        abort_unless(auth()->user()->can('view loan applications'), 403);

        $query = LoanApplication::with(['member.user', 'loanProduct'])
            ->where('status', 'active');

        if ($request->search) {
            $query->where(function ($q) use ($request) {
                $q->where('reference_number', 'like', "%{$request->search}%")
                    ->orWhereHas('member.user', function ($q) use ($request) {
                        $q->where('name', 'like', "%{$request->search}%");
                    });
            });
        }

        $loans = $query->latest()->paginate(15);

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

    /**
     * Display overdue loans.
     */
    public function overdueLoans(Request $request)
    {
        abort_unless(auth()->user()->can('view loan applications'), 403);

        $query = LoanApplication::with(['member.user', 'loanProduct'])
            ->where('status', 'active')
            ->where('next_payment_date', '<', now());

        if ($request->search) {
            $query->where(function ($q) use ($request) {
                $q->where('reference_number', 'like', "%{$request->search}%")
                    ->orWhereHas('member.user', function ($q) use ($request) {
                        $q->where('name', 'like', "%{$request->search}%");
                    });
            });
        }

        $loans = $query->latest()->paginate(15);

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