import { useEffect } from "react";
import { Head, Link, useForm } from "@inertiajs/react";
import {
    AlertTriangle,
    CheckCircle2,
    FileSpreadsheet,
    Lock,
    Upload,
} from "lucide-react";
import { Callout, PageHeader, SectionCard } from "@/components/crm/page-header";
import { Button } from "@/components/ui/button";
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from "@/components/ui/table";
import { formatCurrency, formatDate, formatNumber } from "@/lib/format";

type ImportRow = {
    sheet: string;
    row: number;
    name: string;
    address: string | null;
    phone: string | null;
    contract_date: string | null;
    panels: number | null;
    system_size: number | null;
    sale_price: number;
    deposit: number;
    balance: number;
    customer_id: number | null;
    customer_number: string | null;
    customer_name: string | null;
    matched_on: string | null;
    job_id: number | null;
    job_number: string | null;
    job_system_size: number | null;
    job_panel_count: number | null;
    outcome: string;
    reason: string | null;
    invoice_action: string;
    job_changed: boolean;
};

type Preview = {
    source: string;
    sheets: Array<{ title: string; header_row: number; columns: number }>;
    stats: {
        sheets: number;
        rows: number;
        matched: number;
        ready: number;
        unchanged: number;
        unmatched: number;
        no_job: number;
        duplicate: number;
        no_amount: number;
        invoice_create: number;
        invoice_update: number;
        invoice_skip: number;
    };
    totals: {
        sale_price: number;
        deposit: number;
        balance: number;
        invoice_amount: number;
    };
    rows: ImportRow[];
    truncated: boolean;
};

type UploadState = {
    token: string;
    name: string;
    sheets: Array<{ title: string; header_row: number; columns: number }>;
};

type PageProps = {
    state: {
        enabled: boolean;
        opened_at: string | null;
        opened_by: string | null;
    };
    upload: UploadState | null;
    preview: Preview | null;
};

const outcomeStyles: Record<string, string> = {
    ready: "bg-emerald-500/10 text-emerald-700 ring-emerald-600/20 dark:text-emerald-300",
    unchanged: "bg-slate-500/10 text-slate-600 ring-slate-500/20 dark:text-slate-300",
    unmatched: "bg-amber-500/10 text-amber-700 ring-amber-600/20 dark:text-amber-300",
    no_job: "bg-amber-500/10 text-amber-700 ring-amber-600/20 dark:text-amber-300",
    duplicate: "bg-orange-500/10 text-orange-700 ring-orange-600/20 dark:text-orange-300",
    no_amount: "bg-slate-500/10 text-slate-600 ring-slate-500/20 dark:text-slate-300",
};

/**
 * Customers -> Client information import.
 *
 * The sales workbook is shown before anything is written: who each row matched,
 * which job it will land on, the three money figures and the reason a row was
 * left alone. The import itself is behind a second button.
 */
export default function ClientInformationImport({
    state,
    upload,
    preview,
}: PageProps) {
    const uploadForm = useForm<{ workbook: File | null }>({ workbook: null });
    const commitForm = useForm({ token: upload?.token ?? "" });

    // Inertia keeps this component mounted when the preview comes back, so the
    // commit form has to pick up the token of the upload just read.
    useEffect(() => {
        if (upload?.token) {
            commitForm.setData("token", upload.token);
        }
    }, [upload?.token]);

    const chooseWorkbook = (event: React.FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        uploadForm.post("/customers/information-import/preview", {
            forceFormData: true,
            preserveScroll: true,
        });
    };

    const commit = () => {
        if (!preview || preview.stats.ready === 0) {
            return;
        }

        if (
            window.confirm(
                `Update ${preview.stats.ready} jobs and record their balances as invoices? A verified database backup is taken first.`,
            )
        ) {
            commitForm.post("/customers/information-import/commit", {
                preserveScroll: true,
            });
        }
    };

    return (
        <>
            <Head title="Client information import" />

            <div className="flex flex-col gap-5">
                <PageHeader
                    eyebrow={
                        <>
                            <FileSpreadsheet className="size-3.5 text-solar" />
                            <span>Temporary import · opened {formatDate(state.opened_at)}</span>
                        </>
                    }
                    title="Client information import"
                    description="Read the old Client Information sales workbook into the clients already here, then close the door."
                    actions={
                        <Button size="sm" variant="outline" asChild>
                            <Link href="/settings/client-information-import">
                                <Lock />
                                Open/close in Settings
                            </Link>
                        </Button>
                    }
                />

                <Callout
                    tone="warning"
                    icon={AlertTriangle}
                    title="This is a migration door, not a permanent import"
                >
                    <p>
                        It matches by phone, exact name and then property
                        address. It never creates a customer. The sale price and
                        deposit go onto the job; the balance becomes one customer
                        invoice, so Finance shows what is still owed.
                    </p>
                    <p className="mt-2">
                        Close it from{" "}
                        <span className="font-medium">
                            Settings → Client information import
                        </span>{" "}
                        as soon as the old sheet has been read. Closing leaves
                        every imported job and invoice in place.
                    </p>
                </Callout>

                {!preview ? (
                    <SectionCard
                        title="Choose the workbook"
                        description="Every sales tab is read. Paperwork, cancelled and contract-summary tabs are ignored."
                        icon={Upload}
                        tone="info"
                    >
                        <form
                            onSubmit={chooseWorkbook}
                            className="flex flex-col gap-4"
                        >
                            <label className="flex cursor-pointer flex-col items-center justify-center gap-2 rounded-xl border border-dashed border-hairline px-6 py-10 text-center transition-colors hover:bg-accent/30">
                                <FileSpreadsheet className="size-7 text-muted-foreground" />
                                <span className="text-sm font-medium">
                                    {uploadForm.data.workbook
                                        ? uploadForm.data.workbook.name
                                        : "Choose Client_Information.xlsx"}
                                </span>
                                <span className="text-xs text-muted-foreground">
                                    .xlsx only, up to 20 MB. Nothing is written
                                    until you press Import.
                                </span>
                                <input
                                    type="file"
                                    accept=".xlsx"
                                    className="sr-only"
                                    onChange={(event) =>
                                        uploadForm.setData(
                                            "workbook",
                                            event.target.files?.[0] ?? null,
                                        )
                                    }
                                />
                            </label>

                            {uploadForm.errors.workbook ? (
                                <p className="text-xs font-medium text-destructive">
                                    {uploadForm.errors.workbook}
                                </p>
                            ) : null}

                            <div className="flex justify-end">
                                <Button
                                    type="submit"
                                    disabled={
                                        uploadForm.processing ||
                                        !uploadForm.data.workbook
                                    }
                                >
                                    <FileSpreadsheet />
                                    Read and preview
                                </Button>
                            </div>
                        </form>
                    </SectionCard>
                ) : (
                    <>
                        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
                            <Stat
                                label="Rows read"
                                value={formatNumber(preview.stats.rows)}
                                hint={`${preview.sheets.map((sheet) => sheet.title).join(", ")}`}
                            />
                            <Stat
                                label="Ready to write"
                                value={formatNumber(preview.stats.ready)}
                                hint={`${formatNumber(preview.stats.matched)} matched to a customer`}
                                tone="success"
                            />
                            <Stat
                                label="Needs a person"
                                value={formatNumber(
                                    preview.stats.unmatched +
                                        preview.stats.duplicate,
                                )}
                                hint={`${formatNumber(preview.stats.unmatched)} no match, ${formatNumber(preview.stats.duplicate)} already claimed`}
                                tone={
                                    preview.stats.unmatched +
                                        preview.stats.duplicate >
                                    0
                                        ? "warning"
                                        : undefined
                                }
                            />
                            <Stat
                                label="Sale price on the sheet"
                                value={formatCurrency(preview.totals.sale_price)}
                                hint={`${formatCurrency(preview.totals.deposit)} deposits · ${formatCurrency(preview.totals.balance)} balance`}
                            />
                        </div>

                        <SectionCard
                            title={preview.source}
                            description="The first 250 rows, with anything needing a person at the top. The full report is written when the import runs."
                            icon={FileSpreadsheet}
                            tone="info"
                            actions={
                                <Button size="sm" variant="outline" asChild>
                                    <Link href="/customers/information-import">
                                        Choose another file
                                    </Link>
                                </Button>
                            }
                        >
                            <div className="overflow-x-auto">
                                <Table>
                                    <TableHeader>
                                        <TableRow>
                                            <TableHead>Row</TableHead>
                                            <TableHead>Client</TableHead>
                                            <TableHead>Matched to</TableHead>
                                            <TableHead>Job</TableHead>
                                            <TableHead className="text-right">
                                                Sale
                                            </TableHead>
                                            <TableHead className="text-right">
                                                Deposit
                                            </TableHead>
                                            <TableHead className="text-right">
                                                Balance
                                            </TableHead>
                                            <TableHead>Outcome</TableHead>
                                        </TableRow>
                                    </TableHeader>
                                    <TableBody>
                                        {preview.rows.map((row) => (
                                            <TableRow
                                                key={`${row.sheet}-${row.row}`}
                                            >
                                                <TableCell className="text-xs whitespace-nowrap text-muted-foreground">
                                                    {row.sheet} · {row.row}
                                                </TableCell>
                                                <TableCell className="max-w-[240px]">
                                                    <p className="text-sm font-medium">
                                                        {row.name}
                                                    </p>
                                                    <p className="text-xs text-muted-foreground">
                                                        {row.address ?? "No address"}
                                                    </p>
                                                    <p className="text-[11px] text-muted-foreground">
                                                        {row.contract_date
                                                            ? formatDate(
                                                                  row.contract_date,
                                                              )
                                                            : "No contract date"}
                                                    </p>
                                                </TableCell>
                                                <TableCell className="max-w-[220px]">
                                                    {row.customer_id ? (
                                                        <>
                                                            <p className="text-sm">
                                                                {row.customer_name}
                                                            </p>
                                                            <p className="text-xs text-muted-foreground">
                                                                {
                                                                    row.customer_number
                                                                }{" "}
                                                                ·{" "}
                                                                {row.matched_on}
                                                            </p>
                                                        </>
                                                    ) : (
                                                        <span className="text-xs text-muted-foreground">
                                                            No customer match
                                                        </span>
                                                    )}
                                                </TableCell>
                                                <TableCell className="max-w-[180px]">
                                                    {row.job_number ? (
                                                        <>
                                                            <p className="text-sm">
                                                                {row.job_number}
                                                            </p>
                                                            <p className="text-xs text-muted-foreground">
                                                                {row.job_system_size
                                                                    ? `${row.job_system_size} kW`
                                                                    : "size unknown"}
                                                                {row.job_panel_count
                                                                    ? ` · ${row.job_panel_count} panels`
                                                                    : ""}
                                                            </p>
                                                        </>
                                                    ) : (
                                                        <span className="text-xs text-muted-foreground">
                                                            —
                                                        </span>
                                                    )}
                                                </TableCell>
                                                <TableCell className="text-right text-sm tabular-nums">
                                                    {formatCurrency(
                                                        row.sale_price,
                                                    )}
                                                </TableCell>
                                                <TableCell className="text-right text-sm tabular-nums">
                                                    {formatCurrency(row.deposit)}
                                                </TableCell>
                                                <TableCell className="text-right text-sm font-medium tabular-nums">
                                                    {formatCurrency(row.balance)}
                                                </TableCell>
                                                <TableCell className="max-w-[260px]">
                                                    <span
                                                        className={`inline-flex rounded-full px-2 py-0.5 text-[11px] font-medium ring-1 ring-inset ${outcomeStyles[row.outcome] ?? outcomeStyles.unchanged}`}
                                                    >
                                                        {row.outcome.replace(
                                                            "_",
                                                            " ",
                                                        )}
                                                    </span>
                                                    {row.reason ? (
                                                        <p className="mt-1 text-[11px] leading-snug text-muted-foreground">
                                                            {row.reason}
                                                        </p>
                                                    ) : null}
                                                </TableCell>
                                            </TableRow>
                                        ))}
                                    </TableBody>
                                </Table>
                            </div>

                            {preview.truncated ? (
                                <p className="mt-3 text-xs text-muted-foreground">
                                    Showing 250 of{" "}
                                    {formatNumber(preview.stats.rows)} rows. The
                                    totals and the import cover every row.
                                </p>
                            ) : null}

                            <div className="mt-5 flex flex-wrap items-center justify-between gap-3 border-t border-hairline pt-4">
                                <p className="text-xs text-muted-foreground">
                                    {preview.stats.invoice_create} new balance
                                    invoices ·{" "}
                                    {preview.stats.invoice_update} updated ·{" "}
                                    {preview.stats.invoice_skip} manual
                                    invoices left alone
                                </p>
                                <Button
                                    onClick={commit}
                                    disabled={
                                        commitForm.processing ||
                                        preview.stats.ready === 0
                                    }
                                >
                                    <CheckCircle2 />
                                    Import {formatNumber(preview.stats.ready)}{" "}
                                    rows
                                </Button>
                            </div>

                            {commitForm.errors.token ? (
                                <p className="mt-3 text-xs font-medium text-destructive">
                                    {commitForm.errors.token}
                                </p>
                            ) : null}
                        </SectionCard>
                    </>
                )}
            </div>
        </>
    );
}

function Stat({
    label,
    value,
    hint,
    tone,
}: {
    label: string;
    value: string;
    hint?: string;
    tone?: "success" | "warning";
}) {
    return (
        <div className="rounded-xl border border-hairline bg-card px-4 py-3">
            <p className="text-xs text-muted-foreground">{label}</p>
            <p
                className={
                    tone === "success"
                        ? "mt-1 text-xl font-semibold text-emerald-700 dark:text-emerald-300"
                        : tone === "warning"
                          ? "mt-1 text-xl font-semibold text-amber-700 dark:text-amber-300"
                          : "mt-1 text-xl font-semibold"
                }
            >
                {value}
            </p>
            {hint ? (
                <p className="mt-1 line-clamp-2 text-[11px] text-muted-foreground">
                    {hint}
                </p>
            ) : null}
        </div>
    );
}
