<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\Controller;
use App\Models\FnfSettlement;
use App\Services\AuditService;
use App\Services\Hr\FnfSettlementCalculator;
use Illuminate\Http\Request;

class FnfSettlementController extends Controller
{
    public function __construct(
        protected FnfSettlementCalculator $calculator,
        protected AuditService $audit
    ) {}

    public function show(FnfSettlement $fnf)
    {
        $this->authorizeCompany($fnf);
        $fnf->load(['user', 'offboarding.checklistItems', 'approver', 'payer']);

        return view('hr.fnf-show', compact('fnf'));
    }

    public function update(Request $request, FnfSettlement $fnf)
    {
        $this->authorizeCompany($fnf);

        if (! $fnf->isEditable()) {
            return back()->with('error', 'This settlement cannot be edited.');
        }

        $validated = $request->validate([
            'notice_period_days' => 'nullable|integer|min:0|max:180',
            'notice_served_days' => 'nullable|integer|min:0|max:180',
            'notice_pay_amount' => 'nullable|numeric|min:0',
            'leave_encashment_days' => 'nullable|numeric|min:0',
            'salary_dues_amount' => 'nullable|numeric|min:0',
            'bonus_gratuity_amount' => 'nullable|numeric|min:0',
            'other_earnings' => 'nullable|numeric|min:0',
            'loan_recovery' => 'nullable|numeric|min:0',
            'asset_recovery' => 'nullable|numeric|min:0',
            'other_recovery' => 'nullable|numeric|min:0',
            'notes' => 'nullable|string|max:2000',
        ]);

        $this->calculator->recalculate($fnf, $validated);

        return back()->with('success', 'F&F worksheet recalculated.');
    }

    public function recalculate(FnfSettlement $fnf)
    {
        $this->authorizeCompany($fnf);
        $this->calculator->recalculate($fnf);

        return back()->with('success', 'F&F worksheet refreshed from current leave balances.');
    }

    public function approve(FnfSettlement $fnf)
    {
        $this->authorizeCompany($fnf);

        if (! in_array($fnf->status, [FnfSettlement::STATUS_DRAFT, FnfSettlement::STATUS_PENDING_APPROVAL], true)) {
            return back()->with('error', 'Settlement is not pending approval.');
        }

        $this->calculator->approve($fnf, (int) auth()->id());
        $this->audit->log('fnf.approved', $fnf);

        return back()->with('success', 'F&F settlement approved.');
    }

    public function markPaid(FnfSettlement $fnf)
    {
        $this->authorizeCompany($fnf);

        if ($fnf->status !== FnfSettlement::STATUS_APPROVED) {
            return back()->with('error', 'Settlement must be approved before marking paid.');
        }

        try {
            $this->calculator->markPaid($fnf, (int) auth()->id());
            $this->audit->log('fnf.mark_paid', $fnf);
        } catch (\Throwable $e) {
            return back()->with('error', $e->getMessage());
        }

        return back()->with('success', 'F&F marked as paid. Leave balances encashed and employee deactivated.');
    }

    public function download(FnfSettlement $fnf)
    {
        $this->authorizeCompany($fnf);
        $fnf->load(['user', 'offboarding', 'approver']);

        if (! class_exists(\Barryvdh\DomPDF\Facade\Pdf::class)) {
            return back()->with('error', 'PDF download requires barryvdh/laravel-dompdf.');
        }

        $pdf = \Barryvdh\DomPDF\Facade\Pdf::loadView('hr.fnf-pdf', [
            'fnf' => $fnf,
            'company' => auth()->user()?->company,
        ]);

        $filename = 'fnf-' . $fnf->user_id . '-' . $fnf->id . '.pdf';

        return $pdf->download($filename);
    }

    protected function authorizeCompany(FnfSettlement $fnf): void
    {
        $companyId = auth()->user()?->company_id;
        if ($companyId && (int) $fnf->company_id !== (int) $companyId) {
            abort(403);
        }
    }
}
