import AdminLayout from '@/Layouts/AdminLayout';
import { DataTable, type TableMeta } from '@/components/admin/DataTable';
import PageHeader from '@/components/admin/PageHeader';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { useDataTable, type TableParams } from '@/hooks/useDataTable';
import { api } from '@/lib/api';
import { parseServerDate } from '@/lib/date';
import { Head, Link } from '@inertiajs/react';
import { keepPreviousData, useQuery } from '@tanstack/react-query';
import type { ColumnDef } from '@tanstack/react-table';
import { format } from 'date-fns';
import { Download, Eye, MoreHorizontal } from 'lucide-react';

// ── Types ─────────────────────────────────────────────────────────────────────

interface Invoice {
    id: string;
    invoice_number: string;
    tenant_id: string;
    tenant_name: string;
    amount: number;
    tax_amount: number;
    total: number;
    total_fmt: string;
    currency: string;
    status: string;
    plan_name: string;
    due_date: string | null;
    paid_at: string | null;
    created_at: string;
}

interface InvoicesResponse {
    data: Invoice[];
    meta: TableMeta;
    filter_counts: Record<string, number>;
}

// ── Status badge ──────────────────────────────────────────────────────────────

const STATUS_STYLES: Record<string, string> = {
    draft: 'bg-muted text-muted-foreground',
    sent: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',
    paid: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400',
    overdue: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',
    void: 'bg-muted text-muted-foreground dark:text-muted-foreground/50',
};

function InvoiceStatusBadge({ status }: { status: string }) {
    const cls = STATUS_STYLES[status] ?? 'bg-muted text-muted-foreground';
    return (
        <span
            className={`inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-medium capitalize ${cls}`}
        >
            {status}
        </span>
    );
}

// ── Quick filters ─────────────────────────────────────────────────────────────

const FILTER_DEFS = [
    { value: 'all', label: 'All' },
    { value: 'draft', label: 'Draft' },
    { value: 'sent', label: 'Sent' },
    { value: 'paid', label: 'Paid' },
    { value: 'overdue', label: 'Overdue' },
    { value: 'void', label: 'Void' },
];

// ── API fetch ─────────────────────────────────────────────────────────────────

function fetchInvoices(params: TableParams): Promise<InvoicesResponse> {
    const sp = new URLSearchParams({ page: String(params.page) });
    if (params.filter && params.filter !== 'all')
        sp.set('filter', params.filter);
    if (params.sort) sp.set('sort', params.sort);
    if (params.dir !== 'asc') sp.set('dir', params.dir);
    if (params.search) sp.set('search', params.search);
    return api.get(`/admin/api/invoices?${sp}`);
}

// ── Row actions ───────────────────────────────────────────────────────────────

function RowActions({ invoice }: { invoice: Invoice }) {
    return (
        <DropdownMenu>
            <DropdownMenuTrigger asChild>
                <button className="text-muted-foreground hover:bg-muted/60 hover:text-foreground flex h-7 w-7 items-center justify-center rounded-md transition-colors focus:outline-none">
                    <MoreHorizontal className="h-4 w-4" />
                    <span className="sr-only">
                        Actions for {invoice.invoice_number}
                    </span>
                </button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="w-44">
                <DropdownMenuItem asChild className="gap-2 text-xs">
                    <Link href={`/admin/tenants/${invoice.tenant_id}`}>
                        <Eye className="h-3.5 w-3.5" />
                        View tenant
                    </Link>
                </DropdownMenuItem>
            </DropdownMenuContent>
        </DropdownMenu>
    );
}

// ── Column definitions ────────────────────────────────────────────────────────

const columns: ColumnDef<Invoice, unknown>[] = [
    {
        accessorKey: 'invoice_number',
        header: 'Invoice',
        meta: { sortable: true, label: 'Invoice' },
        cell: ({ row }) => (
            <span className="text-foreground font-mono text-xs font-medium">
                {row.original.invoice_number}
            </span>
        ),
    },
    {
        accessorKey: 'tenant_name',
        header: 'Tenant',
        meta: { sortable: true, label: 'Tenant' },
        cell: ({ row }) => (
            <Link
                href={`/admin/tenants/${row.original.tenant_id}`}
                className="block min-w-0 hover:opacity-80"
            >
                <p className="text-foreground truncate font-medium">
                    {row.original.tenant_name}
                </p>
                {row.original.plan_name && (
                    <p className="text-muted-foreground truncate text-[11px]">
                        {row.original.plan_name}
                    </p>
                )}
            </Link>
        ),
    },
    {
        accessorKey: 'total',
        header: 'Amount',
        meta: { sortable: true, label: 'Amount' },
        cell: ({ row }) => (
            <span className="text-foreground/90 font-medium tabular-nums">
                {row.original.total_fmt}
            </span>
        ),
    },
    {
        accessorKey: 'status',
        header: 'Status',
        meta: { sortable: true, label: 'Status' },
        cell: ({ row }) => <InvoiceStatusBadge status={row.original.status} />,
    },
    {
        accessorKey: 'due_date',
        header: 'Due',
        meta: { sortable: true, label: 'Due' },
        cell: ({ row }) => {
            const date = row.original.due_date;
            return date ? (
                <span className="text-muted-foreground text-xs tabular-nums">
                    {format(parseServerDate(date), 'dd MMM yyyy')}
                </span>
            ) : (
                <span className="text-muted-foreground text-xs">—</span>
            );
        },
    },
    {
        accessorKey: 'paid_at',
        header: 'Paid',
        meta: { sortable: true, label: 'Paid' },
        cell: ({ row }) => {
            const date = row.original.paid_at;
            return date ? (
                <span className="text-xs text-emerald-600 tabular-nums dark:text-emerald-400">
                    {format(parseServerDate(date), 'dd MMM yyyy')}
                </span>
            ) : (
                <span className="text-muted-foreground text-xs">—</span>
            );
        },
    },
    {
        accessorKey: 'created_at',
        header: 'Created',
        meta: { sortable: true, label: 'Created' },
        cell: ({ row }) => (
            <span className="text-muted-foreground text-xs tabular-nums">
                {format(
                    parseServerDate(row.original.created_at),
                    'dd MMM yyyy',
                )}
            </span>
        ),
    },
    {
        id: '_actions',
        header: '',
        cell: ({ row }) => <RowActions invoice={row.original} />,
        enableHiding: false,
    },
];

// ── Empty meta placeholder ────────────────────────────────────────────────────

const EMPTY_META: TableMeta = {
    current_page: 1,
    last_page: 1,
    total: 0,
    per_page: 25,
    from: 0,
    to: 0,
};

// ── Page ──────────────────────────────────────────────────────────────────────

export default function InvoicesIndex() {
    const { params, setParams } = useDataTable({
        sort: 'created_at',
        dir: 'desc',
    });

    const { data, isLoading, isFetching } = useQuery({
        queryKey: ['admin.invoices', params],
        queryFn: () => fetchInvoices(params),
        placeholderData: keepPreviousData,
    });

    const filterCounts = data?.filter_counts ?? {};

    const quickFilters = FILTER_DEFS.map((f) => ({
        ...f,
        count: filterCounts[f.value] ?? 0,
    }));

    return (
        <AdminLayout title="Invoices">
            <Head title="Invoices" />

            <div className="space-y-6 p-6 lg:p-8">
                <PageHeader
                    title="Invoices"
                    description="All billing invoices across every tenant"
                />

                <DataTable
                    columns={columns}
                    data={data?.data ?? []}
                    meta={data?.meta ?? EMPTY_META}
                    params={params}
                    isLoading={isLoading}
                    isFetching={isFetching}
                    onParamsChange={setParams}
                    quickFilters={quickFilters}
                    bulkActions={[
                        {
                            label: 'Export CSV',
                            icon: Download,
                            onClick: (rows) => {
                                const csv = [
                                    'Invoice #,Tenant,Amount,Currency,Status,Due,Paid,Created',
                                ]
                                    .concat(
                                        rows.map(
                                            (r) =>
                                                `${r.invoice_number},${r.tenant_name},${r.total},${r.currency},${r.status},${r.due_date ?? ''},${r.paid_at ?? ''},${r.created_at}`,
                                        ),
                                    )
                                    .join('\n');
                                const a = document.createElement('a');
                                a.href =
                                    'data:text/csv,' + encodeURIComponent(csv);
                                a.download = 'invoices.csv';
                                a.click();
                            },
                        },
                    ]}
                    searchPlaceholder="Search by invoice # or tenant…"
                    noun="invoices"
                    getRowId={(row) => String(row.id)}
                />
            </div>
        </AdminLayout>
    );
}
