<?php

namespace App\Http\Controllers;

use App\Models\Loan;
use App\Models\LoanInstallment;
use App\Models\LoanInstallmentExcuse;
use App\Services\AuditService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

class LoanInstallmentExcuseController extends Controller
{
    public function store(Request $request, Loan $loan, LoanInstallment $installment): RedirectResponse
    {
        abort_unless($request->user()->canAccessBranch($loan->branch_id), 403);
        abort_unless($installment->loan_id === $loan->id, 404);
        abort_unless($loan->status === 'active', 422, 'Excuses can only be recorded for an active loan.');
        abort_unless($loan->payment_deadline_enabled, 422, 'This loan does not use payment deadlines.');

        if ($installment->penaltyCharges()->where('source','payment_deadline')->exists()) {
            throw ValidationException::withMessages([
                'reason'=>'A deadline penalty has already been charged for this installment. Use an authorized adjustment process instead of silently changing the historical charge.',
            ]);
        }

        $data = $request->validate(['reason'=>['required','string','min:3','max:1500']]);
        $existing = LoanInstallmentExcuse::query()->where('loan_installment_id',$installment->id)->first();
        $before = $existing?->toArray() ?? [];

        $excuse = LoanInstallmentExcuse::updateOrCreate(
            ['loan_installment_id'=>$installment->id],
            [
                'loan_id'=>$loan->id,
                'branch_id'=>$loan->branch_id,
                'reason'=>$data['reason'],
                'excused_by'=>$request->user()->id,
                'excused_at'=>now(),
            ],
        );

        AuditService::record('loan.installment_excused',$excuse,$before,$excuse->fresh()->toArray(),$loan->branch_id);
        return back()->with('success','Payment deadline excuse recorded for installment #'.$installment->installment_number.'.');
    }

    public function destroy(Request $request, Loan $loan, LoanInstallment $installment): RedirectResponse
    {
        abort_unless($request->user()->canAccessBranch($loan->branch_id), 403);
        abort_unless($installment->loan_id === $loan->id, 404);
        $excuse = LoanInstallmentExcuse::query()->where('loan_installment_id',$installment->id)->firstOrFail();
        $before = $excuse->toArray();
        AuditService::record('loan.installment_excuse_removed',$excuse,$before,[],$loan->branch_id);
        $excuse->delete();
        return back()->with('success','Payment deadline excuse removed.');
    }
}
