import { Head, Link, router, useForm, usePage } from '@inertiajs/react';
import {
    ArrowLeft,
    Check,
    CreditCard,
    Mail,
    Printer,
    Send,
} from 'lucide-react';
import { useState } from 'react';
import type { FormEvent } from 'react';
import InvoiceController from '@/actions/App/Http/Controllers/Admin/InvoiceController';
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,
    CardDescription,
    CardHeader,
    CardTitle,
} from '@/components/ui/card';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { formatCurrency, formatDate } from '@/lib/utils';
import { dashboard } from '@/routes';
import { index, pdf } from '@/routes/admin/invoices';
import { show as stockExitShow } from '@/routes/admin/stock-exits';
import { InvoiceStatusBadge } from './status-badge';

type Line = {
    id: number;
    product_id: number | null;
    service_id: number | null;
    description: string;
    quantity: number;
    unit_price: number;
    discount_rate: number;
    tax_rate: number;
    line_subtotal: number;
    line_tax: number;
    line_total: number;
    product: { id: number; code: string; name: string } | null;
    service: { id: number; code: string; name: string } | null;
};

type Payment = {
    id: number;
    amount: number;
    paid_at: string | null;
    method: string | null;
    reference: string | null;
    recorder: { id: number; name: string } | null;
};

type Invoice = {
    id: number;
    code: string | null;
    display_code: string;
    status: string;
    status_label: string;
    stored_status: string;
    issue_date: string | null;
    due_date: string | null;
    subtotal: number;
    discount_amount: number;
    tax_amount: number;
    total_amount: number;
    amount_paid: number;
    balance_due: number;
    notes: string | null;
    sent_at: string | null;
    paid_at: string | null;
    warehouse_id: number | null;
    warehouse: { id: number; code: string; name: string } | null;
    stock_exit: { id: number; code: string } | null;
    customer: {
        id: number;
        code: string;
        name: string;
        contact_name: string | null;
        email: string | null;
        phone: string | null;
        address: string | null;
    };
    creator: { id: number; name: string } | null;
    lines: Line[];
    payments: Payment[];
};

export default function InvoicesShow({
    invoice,
    canUpdate,
    canValidate,
    canSend,
    canSendEmail,
    canRecordPayment,
    canDownloadPdf,
    canViewStockExit,
}: {
    invoice: Invoice;
    canUpdate: boolean;
    canValidate: boolean;
    canSend: boolean;
    canSendEmail: boolean;
    canRecordPayment: boolean;
    canDownloadPdf: boolean;
    canViewStockExit: boolean;
}) {
    const { auth } = usePage<{ auth: { user: { has_signature?: boolean } | null } }>().props;
    const [paymentOpen, setPaymentOpen] = useState(false);
    const paymentForm = useForm({
        amount: invoice.balance_due > 0 ? String(invoice.balance_due) : '',
        paid_at: new Date().toISOString().slice(0, 10),
        method: '',
        reference: '',
    });

    function submitPayment(event: FormEvent) {
        event.preventDefault();

        paymentForm.post(
            InvoiceController.recordPayment.url(invoice.id),
            {
                preserveScroll: true,
                onSuccess: () => {
                    setPaymentOpen(false);
                    paymentForm.reset();
                },
            },
        );
    }

    return (
        <>
            <Head title={invoice.display_code} />

            <div className="flex h-full flex-1 flex-col gap-6 p-4 md:p-6">
                {canValidate && !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">
                    <div className="space-y-2">
                        <Heading
                            title={`Facture ${invoice.display_code}`}
                            description={invoice.customer.name}
                        />
                        <InvoiceStatusBadge
                            status={invoice.status}
                            label={invoice.status_label}
                        />
                    </div>
                    <div className="flex flex-wrap gap-2">
                        <Button variant="outline" asChild>
                            <Link href={index()}>
                                <ArrowLeft />
                                Retour
                            </Link>
                        </Button>
                        {canDownloadPdf && (
                            <Button variant="outline" asChild>
                                <a
                                    href={pdf(invoice.id).url}
                                    target="_blank"
                                    rel="noopener noreferrer"
                                >
                                    <Printer />
                                    PDF
                                </a>
                            </Button>
                        )}
                        {canValidate && (
                            <ConfirmDialog
                                trigger={
                                    <Button variant="secondary">
                                        <Check />
                                        Valider
                                    </Button>
                                }
                                title="Valider cette facture ?"
                                description="La facture passera au statut validée et pourra ensuite être émise."
                                confirmLabel="Valider"
                                onConfirm={() => {
                                    router.post(
                                        InvoiceController.validateInvoice.url(
                                            invoice.id,
                                        ),
                                        {},
                                        { preserveScroll: true },
                                    );
                                }}
                            />
                        )}
                        {canSend && (
                            <ConfirmDialog
                                trigger={
                                    <Button>
                                        <Send />
                                        Émettre
                                    </Button>
                                }
                                title="Émettre cette facture ?"
                                description={
                                    invoice.lines.some((line) => line.product_id)
                                        ? 'La facture recevra un numéro définitif, passera au statut envoyée et une sortie de stock « Vente » sera créée.'
                                        : 'La facture recevra un numéro définitif et passera au statut envoyée.'
                                }
                                confirmLabel="Émettre"
                                onConfirm={() => {
                                    router.post(
                                        InvoiceController.send.url(
                                            invoice.id,
                                        ),
                                        {},
                                        { preserveScroll: true },
                                    );
                                }}
                            />
                        )}
                        {canSendEmail && (
                            <ConfirmDialog
                                trigger={
                                    <Button variant="secondary">
                                        <Mail />
                                        Envoyer par e-mail
                                    </Button>
                                }
                                title="Envoyer la facture par e-mail ?"
                                description={
                                    invoice.customer.email
                                        ? `Un e-mail sera envoyé à ${invoice.customer.email}.`
                                        : 'Le client n’a pas d’adresse e-mail enregistrée.'
                                }
                                confirmLabel="Envoyer"
                                onConfirm={() => {
                                    router.post(
                                        InvoiceController.sendEmail.url(
                                            invoice.id,
                                        ),
                                        {},
                                        { preserveScroll: true },
                                    );
                                }}
                            />
                        )}
                        {canRecordPayment && (
                            <Button onClick={() => setPaymentOpen(true)}>
                                <CreditCard />
                                Enregistrer un paiement
                            </Button>
                        )}
                    </div>
                </div>

                <div className="grid gap-6 lg:grid-cols-3">
                    <div className="space-y-6 lg:col-span-2">
                        <Card>
                            <CardHeader>
                                <CardTitle>Informations</CardTitle>
                            </CardHeader>
                            <CardContent className="grid gap-4 sm:grid-cols-2">
                                <div>
                                    <p className="text-muted-foreground text-sm">
                                        Client
                                    </p>
                                    <p className="font-medium">
                                        {invoice.customer.name}
                                    </p>
                                    <p className="text-muted-foreground text-xs">
                                        {invoice.customer.code}
                                    </p>
                                </div>
                                <div>
                                    <p className="text-muted-foreground text-sm">
                                        Contact
                                    </p>
                                    <p className="text-sm">
                                        {invoice.customer.contact_name || '—'}
                                    </p>
                                    <p className="text-muted-foreground text-xs">
                                        {invoice.customer.email || '—'}
                                    </p>
                                </div>
                                <div>
                                    <p className="text-muted-foreground text-sm">
                                        Date d'émission
                                    </p>
                                    <p>{formatDate(invoice.issue_date)}</p>
                                </div>
                                <div>
                                    <p className="text-muted-foreground text-sm">
                                        Date d'échéance
                                    </p>
                                    <p>{formatDate(invoice.due_date)}</p>
                                </div>
                                {invoice.warehouse && (
                                    <div>
                                        <p className="text-muted-foreground text-sm">
                                            Entrepôt
                                        </p>
                                        <p className="font-medium">
                                            {invoice.warehouse.name}
                                        </p>
                                        <p className="text-muted-foreground text-xs">
                                            {invoice.warehouse.code}
                                        </p>
                                    </div>
                                )}
                                {invoice.stock_exit && (
                                    <div>
                                        <p className="text-muted-foreground text-sm">
                                            Sortie de stock
                                        </p>
                                        {canViewStockExit ? (
                                            <Link
                                                href={stockExitShow(
                                                    invoice.stock_exit.id,
                                                ).url}
                                                className="font-medium text-primary hover:underline"
                                            >
                                                {invoice.stock_exit.code}
                                            </Link>
                                        ) : (
                                            <p className="font-medium">
                                                {invoice.stock_exit.code}
                                            </p>
                                        )}
                                    </div>
                                )}
                                {invoice.notes && (
                                    <div className="sm:col-span-2">
                                        <p className="text-muted-foreground text-sm">
                                            Notes
                                        </p>
                                        <p className="whitespace-pre-wrap text-sm">
                                            {invoice.notes}
                                        </p>
                                    </div>
                                )}
                            </CardContent>
                        </Card>

                        <Card>
                            <CardHeader>
                                <CardTitle>Lignes</CardTitle>
                                <CardDescription>
                                    {invoice.lines.length}{' '}
                                    {invoice.lines.length > 1
                                        ? 'lignes'
                                        : 'ligne'}
                                </CardDescription>
                            </CardHeader>
                            <CardContent>
                                <Table>
                                    <TableHeader>
                                        <TableRow>
                                            <TableHead>Description</TableHead>
                                            <TableHead className="text-right">
                                                Qté
                                            </TableHead>
                                            <TableHead className="text-right">
                                                P.U.
                                            </TableHead>
                                            <TableHead className="text-right">
                                                Rem.
                                            </TableHead>
                                            <TableHead className="text-right">
                                                TVA
                                            </TableHead>
                                            <TableHead className="text-right">
                                                Total
                                            </TableHead>
                                        </TableRow>
                                    </TableHeader>
                                    <TableBody>
                                        {invoice.lines.map((line) => (
                                            <TableRow key={line.id}>
                                                <TableCell>
                                                    <div>
                                                        <p className="font-medium">
                                                            {line.description}
                                                        </p>
                                                        {line.product && (
                                                            <p className="text-muted-foreground text-xs">
                                                                {
                                                                    line.product
                                                                        .code
                                                                }{' '}
                                                                —{' '}
                                                                {
                                                                    line.product
                                                                        .name
                                                                }
                                                            </p>
                                                        )}
                                                        {line.service && (
                                                            <p className="text-muted-foreground text-xs">
                                                                {
                                                                    line.service
                                                                        .code
                                                                }{' '}
                                                                —{' '}
                                                                {
                                                                    line.service
                                                                        .name
                                                                }
                                                            </p>
                                                        )}
                                                    </div>
                                                </TableCell>
                                                <TableCell className="text-right tabular-nums">
                                                    {line.quantity}
                                                </TableCell>
                                                <TableCell className="text-right tabular-nums">
                                                    {formatCurrency(
                                                        line.unit_price,
                                                    )}
                                                </TableCell>
                                                <TableCell className="text-right tabular-nums">
                                                    {line.discount_rate}%
                                                </TableCell>
                                                <TableCell className="text-right tabular-nums">
                                                    {line.tax_rate}%
                                                </TableCell>
                                                <TableCell className="text-right tabular-nums">
                                                    {formatCurrency(
                                                        line.line_total,
                                                    )}
                                                </TableCell>
                                            </TableRow>
                                        ))}
                                    </TableBody>
                                </Table>
                            </CardContent>
                        </Card>

                        {invoice.payments.length > 0 && (
                            <Card>
                                <CardHeader>
                                    <CardTitle>Paiements</CardTitle>
                                    <CardDescription>
                                        Historique des règlements enregistrés
                                    </CardDescription>
                                </CardHeader>
                                <CardContent>
                                    <Table>
                                        <TableHeader>
                                            <TableRow>
                                                <TableHead>Date</TableHead>
                                                <TableHead>Montant</TableHead>
                                                <TableHead>Méthode</TableHead>
                                                <TableHead>Référence</TableHead>
                                                <TableHead>Enregistré par</TableHead>
                                            </TableRow>
                                        </TableHeader>
                                        <TableBody>
                                            {invoice.payments.map((payment) => (
                                                <TableRow key={payment.id}>
                                                    <TableCell>
                                                        {formatDate(
                                                            payment.paid_at,
                                                        )}
                                                    </TableCell>
                                                    <TableCell className="tabular-nums">
                                                        {formatCurrency(
                                                            payment.amount,
                                                        )}
                                                    </TableCell>
                                                    <TableCell>
                                                        {payment.method || '—'}
                                                    </TableCell>
                                                    <TableCell>
                                                        {payment.reference ||
                                                            '—'}
                                                    </TableCell>
                                                    <TableCell>
                                                        {payment.recorder
                                                            ?.name ?? '—'}
                                                    </TableCell>
                                                </TableRow>
                                            ))}
                                        </TableBody>
                                    </Table>
                                </CardContent>
                            </Card>
                        )}
                    </div>

                    <div className="lg:col-span-1">
                        <Card className="lg:sticky lg:top-6">
                            <CardHeader>
                                <CardTitle>Totaux</CardTitle>
                            </CardHeader>
                            <CardContent className="space-y-3 text-sm">
                                <div className="flex items-center justify-between">
                                    <span className="text-muted-foreground">
                                        Total HT
                                    </span>
                                    <span className="tabular-nums">
                                        {formatCurrency(invoice.subtotal)}
                                    </span>
                                </div>
                                {invoice.discount_amount > 0 && (
                                    <div className="flex items-center justify-between">
                                        <span className="text-muted-foreground">
                                            Remise globale
                                        </span>
                                        <span className="tabular-nums">
                                            -
                                            {formatCurrency(
                                                invoice.discount_amount,
                                            )}
                                        </span>
                                    </div>
                                )}
                                <div className="flex items-center justify-between">
                                    <span className="text-muted-foreground">
                                        TVA
                                    </span>
                                    <span className="tabular-nums">
                                        {formatCurrency(invoice.tax_amount)}
                                    </span>
                                </div>
                                <div className="flex items-center justify-between border-t pt-3 font-medium">
                                    <span>Total TTC</span>
                                    <span className="text-lg tabular-nums">
                                        {formatCurrency(invoice.total_amount)}
                                    </span>
                                </div>
                                <div className="flex items-center justify-between">
                                    <span className="text-muted-foreground">
                                        Payé
                                    </span>
                                    <span className="tabular-nums">
                                        {formatCurrency(invoice.amount_paid)}
                                    </span>
                                </div>
                                <div className="flex items-center justify-between border-t pt-3">
                                    <span className="font-medium">
                                        Reste à payer
                                    </span>
                                    <span className="text-lg font-semibold tabular-nums">
                                        {formatCurrency(invoice.balance_due)}
                                    </span>
                                </div>
                                {canUpdate && invoice.stored_status === 'draft' && (
                                    <p className="text-muted-foreground pt-2 text-xs">
                                        Cette facture est un brouillon modifiable
                                        tant qu'elle n'est pas émise.
                                    </p>
                                )}
                            </CardContent>
                        </Card>
                    </div>
                </div>
            </div>

            <Dialog open={paymentOpen} onOpenChange={setPaymentOpen}>
                <DialogContent>
                    <DialogHeader>
                        <DialogTitle>Enregistrer un paiement</DialogTitle>
                        <DialogDescription>
                            Reste à payer :{' '}
                            {formatCurrency(invoice.balance_due)}
                        </DialogDescription>
                    </DialogHeader>

                    <form onSubmit={submitPayment} className="space-y-4">
                        <div className="grid gap-2">
                            <Label htmlFor="payment-amount">Montant</Label>
                            <Input
                                id="payment-amount"
                                type="number"
                                step="0.01"
                                min="0.01"
                                inputMode="decimal"
                                value={paymentForm.data.amount}
                                onChange={(event) =>
                                    paymentForm.setData(
                                        'amount',
                                        event.target.value,
                                    )
                                }
                                required
                            />
                            <InputError message={paymentForm.errors.amount} />
                        </div>

                        <div className="grid gap-2">
                            <Label htmlFor="payment-date">Date de paiement</Label>
                            <Input
                                id="payment-date"
                                type="date"
                                value={paymentForm.data.paid_at}
                                onChange={(event) =>
                                    paymentForm.setData(
                                        'paid_at',
                                        event.target.value,
                                    )
                                }
                                required
                            />
                            <InputError message={paymentForm.errors.paid_at} />
                        </div>

                        <div className="grid gap-2">
                            <Label htmlFor="payment-method">
                                Méthode (optionnel)
                            </Label>
                            <Input
                                id="payment-method"
                                placeholder="ex. Virement, Espèces…"
                                value={paymentForm.data.method}
                                onChange={(event) =>
                                    paymentForm.setData(
                                        'method',
                                        event.target.value,
                                    )
                                }
                            />
                            <InputError message={paymentForm.errors.method} />
                        </div>

                        <div className="grid gap-2">
                            <Label htmlFor="payment-reference">
                                Référence (optionnel)
                            </Label>
                            <Input
                                id="payment-reference"
                                value={paymentForm.data.reference}
                                onChange={(event) =>
                                    paymentForm.setData(
                                        'reference',
                                        event.target.value,
                                    )
                                }
                            />
                            <InputError
                                message={paymentForm.errors.reference}
                            />
                        </div>

                        <DialogFooter>
                            <Button
                                type="button"
                                variant="outline"
                                onClick={() => setPaymentOpen(false)}
                            >
                                Annuler
                            </Button>
                            <Button
                                type="submit"
                                disabled={paymentForm.processing}
                            >
                                Enregistrer
                            </Button>
                        </DialogFooter>
                    </form>
                </DialogContent>
            </Dialog>
        </>
    );
}

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