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 Client {
    id: string;
    name: string;
    email: string;
    avatar: string | null;
    provider: string;
    verified: boolean;
    owned_apps_count: number;
    member_apps_count: number;
    joined_at: string;
}

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

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

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

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

function RowActions({ client }: { client: Client }) {
    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 {client.name}</span>
                </button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="w-44">
                <DropdownMenuItem asChild className="gap-2 text-xs">
                    <Link href={`/admin/clients/${client.id}`}>
                        <Eye className="h-3.5 w-3.5" />
                        View client
                    </Link>
                </DropdownMenuItem>
            </DropdownMenuContent>
        </DropdownMenu>
    );
}

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

const columns: ColumnDef<Client, unknown>[] = [
    {
        accessorKey: 'name',
        header: 'Client',
        meta: { sortable: true, label: 'Client' },
        cell: ({ row }) => (
            <Link
                href={`/admin/clients/${row.original.id}`}
                className="flex min-w-0 items-center gap-3 hover:opacity-80"
            >
                {row.original.avatar ? (
                    <img
                        src={row.original.avatar}
                        alt=""
                        className="h-8 w-8 shrink-0 rounded-full object-cover"
                    />
                ) : (
                    <div className="bg-primary/10 text-primary flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-xs font-bold">
                        {row.original.name[0]}
                    </div>
                )}
                <div className="min-w-0">
                    <p className="text-foreground truncate font-medium">
                        {row.original.name}
                    </p>
                    <p className="text-muted-foreground truncate text-[11px]">
                        {row.original.email}
                    </p>
                </div>
            </Link>
        ),
    },
    {
        accessorKey: 'provider',
        header: 'Signup',
        meta: { label: 'Signup' },
        cell: ({ row }) => (
            <span className="text-foreground/80 text-xs capitalize">
                {row.original.provider}
            </span>
        ),
    },
    {
        accessorKey: 'verified',
        header: 'Verified',
        meta: { label: 'Verified' },
        cell: ({ row }) =>
            row.original.verified ? (
                <span className="rounded-full bg-emerald-100 px-2 py-0.5 text-[10px] font-semibold text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400">
                    verified
                </span>
            ) : (
                <span className="rounded-full bg-amber-100 px-2 py-0.5 text-[10px] font-semibold text-amber-700 dark:bg-amber-900/30 dark:text-amber-400">
                    unverified
                </span>
            ),
    },
    {
        accessorKey: 'owned_apps_count',
        header: 'Tenants',
        meta: { sortable: true, label: 'Tenants' },
        cell: ({ row }) => (
            <span className="text-foreground/80 text-xs tabular-nums">
                {row.original.owned_apps_count} owned
                {row.original.member_apps_count >
                    row.original.owned_apps_count &&
                    ` · ${row.original.member_apps_count} total`}
            </span>
        ),
    },
    {
        accessorKey: 'joined_at',
        header: 'Joined',
        meta: { sortable: true, sortKey: 'created_at', label: 'Joined' },
        cell: ({ row }) => (
            <span className="text-muted-foreground text-xs tabular-nums">
                {format(parseServerDate(row.original.joined_at), 'dd MMM yyyy')}
            </span>
        ),
    },
    {
        id: '_actions',
        header: '',
        cell: ({ row }) => <RowActions client={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 ClientsIndex() {
    const { params, setParams } = useDataTable({
        sort: 'created_at',
        dir: 'desc',
    });

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

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

    const quickFilters = [
        { label: 'All', value: 'all', count: counts.all },
        { label: 'Verified', value: 'verified', count: counts.verified },
        { label: 'Unverified', value: 'unverified', count: counts.unverified },
        { label: 'No tenant yet', value: 'no_app', count: counts.no_app },
    ];

    return (
        <AdminLayout title="All Clients">
            <Head title="All Clients" />

            <div className="space-y-6 p-6 lg:p-8">
                <PageHeader
                    title="All Clients"
                    description="Everyone who has registered an account, whether or not they created a 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 = [
                                    'Name,Email,Signup,Verified,Owned Tenants,Joined',
                                ]
                                    .concat(
                                        rows.map(
                                            (r) =>
                                                `${r.name},${r.email},${r.provider},${r.verified ? 'yes' : 'no'},${r.owned_apps_count},${r.joined_at}`,
                                        ),
                                    )
                                    .join('\n');
                                const a = document.createElement('a');
                                a.href =
                                    'data:text/csv,' + encodeURIComponent(csv);
                                a.download = 'clients.csv';
                                a.click();
                            },
                        },
                    ]}
                    searchPlaceholder="Search clients…"
                    noun="clients"
                    getRowId={(row) => String(row.id)}
                />
            </div>
        </AdminLayout>
    );
}
