import { Head, Link, router, useForm, usePage } from '@inertiajs/react';
import { ArrowLeft, Check, Download, Pencil, Send, X } from 'lucide-react';
import { useState } from 'react';
import type { FormEvent } from 'react';
import ExpenseReportController from '@/actions/App/Http/Controllers/Admin/ExpenseReportController';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { ConfirmDialog } from '@/components/confirm-dialog';
import Heading from '@/components/heading';
import InputError from '@/components/input-error';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Label } from '@/components/ui/label';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { Textarea } from '@/components/ui/textarea';
import { formatCurrency, formatDate } from '@/lib/utils';
import { dashboard } from '@/routes';
import { edit, index } from '@/routes/admin/expense-reports';
import { ExpenseStatusBadge } from './status-badge';

type Line = {
    id: number;
    category: string;
    category_label: string;
    description: string;
    amount: string | number;
    spent_at: string | null;
    has_receipt: boolean;
    receipt_name: string | null;
    receipt_url: string | null;
};

type Report = {
    id: number;
    code: string;
    title: string;
    status: string;
    status_label: string;
    total_amount: string | number;
    user: { id: number; name: string } | null;
    submitted_at: string | null;
    manager_validated_at: string | null;
    manager_validator: string | null;
    accounting_validated_at: string | null;
    accounting_validator: string | null;
    reimbursed_at: string | null;
    reimburser: string | null;
    rejected_at: string | null;
    rejecter: string | null;
    rejection_reason: string | null;
    created_at: string | null;
    lines: Line[];
};

type Can = {
    update: boolean;
    submit: boolean;
    validateManager: boolean;
    validateAccounting: boolean;
    reimburse: boolean;
    reject: boolean;
    delete: boolean;
    downloadPdf: boolean;
};

export default function ExpenseReportsShow({
    report,
    can,
    canViewAll,
}: {
    report: Report;
    can: Can;
    canViewAll: boolean;
}) {
    const { auth } = usePage<{ auth: { user: { has_signature?: boolean } | null } }>().props;
    const [rejectOpen, setRejectOpen] = useState(false);
    const rejectForm = useForm({ rejection_reason: '' });

    function action(url: string) {
        router.post(url, {}, { preserveScroll: true });
    }

    function submitReject(event: FormEvent) {
        event.preventDefault();
        rejectForm.post(ExpenseReportController.reject.url(report.id), {
            preserveScroll: true,
            onSuccess: () => {
                setRejectOpen(false);
                rejectForm.reset();
            },
        });
    }

    const showSubmit = can.submit && report.status === 'draft';
    const showEdit = can.update && report.status === 'draft';
    const showDelete = can.delete && report.status === 'draft';
    const showManager = can.validateManager && report.status === 'submitted';
    const showAccounting =
        can.validateAccounting && report.status === 'manager_approved';
    const showReimburse =
        can.reimburse && report.status === 'accounting_approved';
    const showReject =
        can.reject &&
        ['submitted', 'manager_approved', 'accounting_approved'].includes(
            report.status,
        );

    return (
        <>
            <Head title={report.code} />

            <div className="flex h-full flex-1 flex-col gap-6 p-4 md:p-6">
                {(showManager || showAccounting) && !auth.user?.has_signature && (
                    <Alert>
                        <AlertDescription>
                            Configurez votre signature dans Mon Profil pour
                            qu'elle apparaisse sur les documents que vous
                            validez.
                        </AlertDescription>
                    </Alert>
                )}

                <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
                    <Heading
                        title={report.title}
                        description={`${report.code} · ${report.user?.name ?? ''}`}
                    />
                    <div className="flex flex-wrap gap-2">
                        <Button variant="outline" asChild>
                            <Link href={index()}>
                                <ArrowLeft />
                                Retour
                            </Link>
                        </Button>
                        {can.downloadPdf && (
                            <Button variant="outline" asChild>
                                <a
                                    href={ExpenseReportController.downloadPdf.url(
                                        report.id,
                                    )}
                                    target="_blank"
                                    rel="noopener noreferrer"
                                >
                                    <Download />
                                    Télécharger le PDF
                                </a>
                            </Button>
                        )}
                        {showEdit && (
                            <Button variant="outline" asChild>
                                <Link href={edit(report.id)}>
                                    <Pencil />
                                    Modifier
                                </Link>
                            </Button>
                        )}
                    </div>
                </div>

                <div className="grid gap-6 lg:grid-cols-3">
                    <Card className="lg:col-span-2">
                        <CardHeader>
                            <CardTitle>Dépenses</CardTitle>
                        </CardHeader>
                        <CardContent>
                            <Table>
                                <TableHeader>
                                    <TableRow>
                                        <TableHead>Catégorie</TableHead>
                                        <TableHead>Description</TableHead>
                                        <TableHead>Date</TableHead>
                                        <TableHead className="text-right">
                                            Montant
                                        </TableHead>
                                        <TableHead>Justificatif</TableHead>
                                    </TableRow>
                                </TableHeader>
                                <TableBody>
                                    {report.lines.map((line) => (
                                        <TableRow key={line.id}>
                                            <TableCell>
                                                {line.category_label}
                                            </TableCell>
                                            <TableCell>
                                                {line.description}
                                            </TableCell>
                                            <TableCell className="text-muted-foreground">
                                                {formatDate(line.spent_at)}
                                            </TableCell>
                                            <TableCell className="text-right tabular-nums">
                                                {formatCurrency(line.amount)}
                                            </TableCell>
                                            <TableCell>
                                                {line.has_receipt &&
                                                line.receipt_url ? (
                                                    <a
                                                        href={line.receipt_url}
                                                        target="_blank"
                                                        rel="noopener noreferrer"
                                                        className="inline-flex items-center gap-1 text-sm text-primary underline-offset-4 hover:underline"
                                                    >
                                                        <Download className="size-3.5" />
                                                        Voir
                                                    </a>
                                                ) : (
                                                    <span className="text-muted-foreground">
                                                        —
                                                    </span>
                                                )}
                                            </TableCell>
                                        </TableRow>
                                    ))}
                                    <TableRow>
                                        <TableCell
                                            colSpan={3}
                                            className="text-right font-medium"
                                        >
                                            Total
                                        </TableCell>
                                        <TableCell className="text-right font-semibold tabular-nums">
                                            {formatCurrency(
                                                report.total_amount,
                                            )}
                                        </TableCell>
                                        <TableCell />
                                    </TableRow>
                                </TableBody>
                            </Table>
                        </CardContent>
                    </Card>

                    <div className="space-y-6">
                        <Card>
                            <CardHeader>
                                <CardTitle>Statut</CardTitle>
                            </CardHeader>
                            <CardContent className="space-y-4">
                                <div className="flex items-center justify-between text-sm">
                                    <span className="text-muted-foreground">
                                        État actuel
                                    </span>
                                    <ExpenseStatusBadge
                                        status={report.status}
                                        label={report.status_label}
                                    />
                                </div>

                                <div className="flex flex-wrap gap-2">
                                    {showSubmit && (
                                        <Button
                                            size="sm"
                                            onClick={() =>
                                                action(
                                                    ExpenseReportController.submit.url(
                                                        report.id,
                                                    ),
                                                )
                                            }
                                        >
                                            <Send />
                                            Soumettre
                                        </Button>
                                    )}
                                    {showManager && (
                                        <Button
                                            size="sm"
                                            onClick={() =>
                                                action(
                                                    ExpenseReportController.approveManager.url(
                                                        report.id,
                                                    ),
                                                )
                                            }
                                        >
                                            <Check />
                                            Valider
                                        </Button>
                                    )}
                                    {showAccounting && (
                                        <Button
                                            size="sm"
                                            onClick={() =>
                                                action(
                                                    ExpenseReportController.approveAccounting.url(
                                                        report.id,
                                                    ),
                                                )
                                            }
                                        >
                                            <Check />
                                            Valider
                                        </Button>
                                    )}
                                    {showReimburse && (
                                        <Button
                                            size="sm"
                                            onClick={() =>
                                                action(
                                                    ExpenseReportController.reimburse.url(
                                                        report.id,
                                                    ),
                                                )
                                            }
                                        >
                                            <Check />
                                            Rembourser
                                        </Button>
                                    )}
                                    {showReject && (
                                        <Button
                                            size="sm"
                                            variant="destructive"
                                            onClick={() => setRejectOpen(true)}
                                        >
                                            <X />
                                            Rejeter
                                        </Button>
                                    )}
                                </div>

                                {report.rejection_reason && (
                                    <div className="rounded-lg bg-destructive/5 p-3 text-sm">
                                        <p className="font-medium text-destructive-foreground">
                                            Motif du rejet
                                        </p>
                                        <p className="text-muted-foreground">
                                            {report.rejection_reason}
                                        </p>
                                    </div>
                                )}
                            </CardContent>
                        </Card>

                        <Card>
                            <CardHeader>
                                <CardTitle>Suivi de validation</CardTitle>
                            </CardHeader>
                            <CardContent className="space-y-3 text-sm">
                                <TimelineRow
                                    label="Soumise"
                                    date={report.submitted_at}
                                />
                                {canViewAll && (
                                    <>
                                        <TimelineRow
                                            label="Validée manager"
                                            date={report.manager_validated_at}
                                            by={report.manager_validator}
                                        />
                                        <TimelineRow
                                            label="Validée comptabilité"
                                            date={
                                                report.accounting_validated_at
                                            }
                                            by={report.accounting_validator}
                                        />
                                    </>
                                )}
                                <TimelineRow
                                    label="Remboursée"
                                    date={report.reimbursed_at}
                                    by={report.reimburser}
                                />
                                {report.rejected_at && (
                                    <TimelineRow
                                        label="Rejetée"
                                        date={report.rejected_at}
                                        by={report.rejecter}
                                    />
                                )}
                            </CardContent>
                        </Card>

                        {showDelete && (
                            <ConfirmDialog
                                trigger={
                                    <Button variant="destructive" size="sm">
                                        Supprimer la note
                                    </Button>
                                }
                                title={`Supprimer la note ${report.code} ?`}
                                description="Cette action est irréversible."
                                confirmLabel="Supprimer"
                                onConfirm={() =>
                                    router.delete(
                                        ExpenseReportController.destroy.url(
                                            report.id,
                                        ),
                                    )
                                }
                            />
                        )}
                    </div>
                </div>
            </div>

            <Dialog open={rejectOpen} onOpenChange={setRejectOpen}>
                <DialogContent>
                    <DialogHeader>
                        <DialogTitle>Rejeter la note de frais</DialogTitle>
                        <DialogDescription>
                            Indiquez le motif du rejet. Le collaborateur pourra
                            corriger et resoumettre.
                        </DialogDescription>
                    </DialogHeader>
                    <form onSubmit={submitReject} className="space-y-4">
                        <div className="grid gap-2">
                            <Label htmlFor="rejection-reason">Motif</Label>
                            <Textarea
                                id="rejection-reason"
                                rows={4}
                                value={rejectForm.data.rejection_reason}
                                onChange={(event) =>
                                    rejectForm.setData(
                                        'rejection_reason',
                                        event.target.value,
                                    )
                                }
                                required
                                autoFocus
                            />
                            <InputError
                                message={rejectForm.errors.rejection_reason}
                            />
                        </div>
                        <DialogFooter>
                            <Button
                                type="button"
                                variant="outline"
                                onClick={() => setRejectOpen(false)}
                            >
                                Annuler
                            </Button>
                            <Button
                                type="submit"
                                variant="destructive"
                                disabled={rejectForm.processing}
                            >
                                Rejeter
                            </Button>
                        </DialogFooter>
                    </form>
                </DialogContent>
            </Dialog>
        </>
    );
}

function TimelineRow({
    label,
    date,
    by,
}: {
    label: string;
    date: string | null;
    by?: string | null;
}) {
    return (
        <div className="flex items-center justify-between gap-4">
            <span className="text-muted-foreground">{label}</span>
            <span className="text-right font-medium">
                {date ? (
                    <>
                        {formatDate(date)}
                        {by ? ` · ${by}` : ''}
                    </>
                ) : (
                    '—'
                )}
            </span>
        </div>
    );
}

ExpenseReportsShow.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: 'Notes de frais', href: index() },
        { title: 'Détail', href: '#' },
    ],
};
