import { Head, Link, router, useForm, usePage } from '@inertiajs/react';
import { Download, FileSpreadsheet } from 'lucide-react';
import { useState } from 'react';
import type { FormEvent } from 'react';
import PayrollRunController from '@/actions/App/Http/Controllers/Admin/PayrollRunController';
import InputError from '@/components/input-error';
import Heading from '@/components/heading';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { formatCurrency } from '@/lib/utils';
import { dashboard } from '@/routes';
import { index } from '@/routes/admin/payroll-runs';
import { show as showPayslip } from '@/routes/admin/payslips';

type Named = { id: number; name: string };

type PayrollRunShow = {
    id: number;
    code: string;
    period_label: string;
    period_start: string;
    period_end: string;
    status: string;
    status_label: string;
    total_gross: number;
    total_employee_contributions: number;
    total_employer_contributions: number;
    total_net: number;
    journal_entry: { id: number; reference: string; status: string } | null;
    journal_missing: boolean;
    cancellation_reason: string | null;
    payslips: Array<{
        id: number;
        code: string;
        employee_full_name: string;
        employee_code: string | null;
        job_title: string | null;
        status_label: string;
        gross_salary: number;
        igr_amount: number;
        cn_amount: number;
        cnps_employee_amount: number;
        net_salary: number;
        payment_method_label: string | null;
    }>;
    can: {
        calculate: boolean;
        validate: boolean;
        close: boolean;
        cancel: boolean;
        delete: boolean;
    };
    calculated_by: Named | null;
    validated_by: Named | null;
};

export default function PayrollRunsShow({ run }: { run: PayrollRunShow }) {
    const [cancelOpen, setCancelOpen] = useState(false);
    const cancelForm = useForm({ cancellation_reason: '' });
    const errors = (usePage().props as { errors?: Record<string, string> }).errors ?? {};

    function submitCancel(event: FormEvent) {
        event.preventDefault();
        cancelForm.post(PayrollRunController.cancel.url(run.code), {
            onSuccess: () => setCancelOpen(false),
        });
    }

    return (
        <>
            <Head title={`Paie ${run.code}`} />
            <div className="flex h-full flex-1 flex-col gap-6 p-4 md:p-6">
                <div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
                    <Heading
                        title={run.code}
                        description={`Période ${run.period_label} · ${run.period_start} → ${run.period_end}`}
                    />
                    <div className="flex flex-wrap gap-2">
                        {run.can.calculate && (
                            <Button onClick={() => router.post(PayrollRunController.calculate.url(run.code))}>
                                Calculer
                            </Button>
                        )}
                        {run.can.validate && (
                            <Button onClick={() => router.post(PayrollRunController.validateRun.url(run.code))}>
                                Valider le cycle
                            </Button>
                        )}
                        {run.can.close && (
                            <Button variant="secondary" onClick={() => router.post(PayrollRunController.close.url(run.code))}>
                                Clôturer
                            </Button>
                        )}
                        {run.can.cancel && (
                            <Button variant="outline" onClick={() => setCancelOpen(true)}>
                                Annuler
                            </Button>
                        )}
                        {run.can.delete && (
                            <Button
                                variant="destructive"
                                onClick={() => router.delete(PayrollRunController.destroy.url(run.code))}
                            >
                                Supprimer
                            </Button>
                        )}
                        <Button variant="outline" asChild>
                            <a href={PayrollRunController.downloadSummaryPdf.url(run.code)}>
                                <Download className="size-4" />
                                PDF
                            </a>
                        </Button>
                        <Button variant="outline" asChild>
                            <a href={PayrollRunController.downloadSummaryExcel.url(run.code)}>
                                <FileSpreadsheet className="size-4" />
                                Excel
                            </a>
                        </Button>
                    </div>
                </div>
                <InputError message={errors.payroll ?? errors.status} />

                <div className="flex flex-wrap items-center gap-3">
                    <Badge>{run.status_label}</Badge>
                    {run.journal_missing && (
                        <p className="text-sm text-amber-700">
                            Aucune écriture comptable n'a été générée. Vérifiez les comptes de paie dans les barèmes.
                        </p>
                    )}
                    {run.journal_entry && (
                        <p className="text-sm text-muted-foreground">
                            Écriture {run.journal_entry.reference}
                        </p>
                    )}
                </div>

                <div className="grid gap-4 sm:grid-cols-4">
                    <Kpi label="Brut" value={formatCurrency(run.total_gross)} />
                    <Kpi label="Retenues salariales" value={formatCurrency(run.total_employee_contributions)} />
                    <Kpi label="Charges patronales" value={formatCurrency(run.total_employer_contributions)} />
                    <Kpi label="Net" value={formatCurrency(run.total_net)} />
                </div>

                {run.payslips.length === 0 ? (
                    <p className="text-sm text-muted-foreground">
                        Aucun bulletin. Calculez le cycle après avoir saisi barèmes et rémunérations.
                    </p>
                ) : (
                    <div className="overflow-x-auto rounded-md border">
                        <table className="w-full text-sm">
                            <thead className="bg-muted/50 text-left">
                                <tr>
                                    <th className="p-3">Matricule</th>
                                    <th className="p-3">Nom</th>
                                    <th className="p-3">Poste</th>
                                    <th className="p-3 text-right">Brut</th>
                                    <th className="p-3 text-right">IGR</th>
                                    <th className="p-3 text-right">CN</th>
                                    <th className="p-3 text-right">CNPS</th>
                                    <th className="p-3 text-right">Net</th>
                                    <th className="p-3"></th>
                                </tr>
                            </thead>
                            <tbody>
                                {run.payslips.map((payslip) => (
                                    <tr key={payslip.id} className="border-t">
                                        <td className="p-3 font-mono text-xs">{payslip.employee_code}</td>
                                        <td className="p-3">{payslip.employee_full_name}</td>
                                        <td className="p-3 text-muted-foreground">{payslip.job_title ?? '—'}</td>
                                        <td className="p-3 text-right">{formatCurrency(payslip.gross_salary)}</td>
                                        <td className="p-3 text-right">{formatCurrency(payslip.igr_amount)}</td>
                                        <td className="p-3 text-right">{formatCurrency(payslip.cn_amount)}</td>
                                        <td className="p-3 text-right">{formatCurrency(payslip.cnps_employee_amount)}</td>
                                        <td className="p-3 text-right font-medium">{formatCurrency(payslip.net_salary)}</td>
                                        <td className="p-3">
                                            <Button variant="ghost" size="sm" asChild>
                                                <Link href={showPayslip.url(payslip.code)}>Voir</Link>
                                            </Button>
                                        </td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>
                )}
            </div>

            <Dialog open={cancelOpen} onOpenChange={setCancelOpen}>
                <DialogContent>
                    <DialogHeader>
                        <DialogTitle>Annuler le cycle</DialogTitle>
                        <DialogDescription>
                            L'annulation est possible tant que le cycle n'est pas validé.
                        </DialogDescription>
                    </DialogHeader>
                    <form onSubmit={submitCancel} className="space-y-3">
                        <Label htmlFor="cancellation_reason">Motif</Label>
                        <Input
                            id="cancellation_reason"
                            value={cancelForm.data.cancellation_reason}
                            onChange={(event) => cancelForm.setData('cancellation_reason', event.target.value)}
                        />
                        <InputError message={cancelForm.errors.cancellation_reason} />
                        <Button type="submit" variant="destructive" disabled={cancelForm.processing}>
                            Confirmer l'annulation
                        </Button>
                    </form>
                </DialogContent>
            </Dialog>
        </>
    );
}

function Kpi({ label, value }: { label: string; value: string }) {
    return (
        <div className="rounded-lg border p-4">
            <p className="text-xs uppercase tracking-wide text-muted-foreground">{label}</p>
            <p className="mt-1 text-lg font-semibold">{value}</p>
        </div>
    );
}

PayrollRunsShow.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: 'Paie', href: index() },
    ],
};
