import AdminLayout from '@/Layouts/AdminLayout';
import { DataTable, type TableMeta } from '@/components/admin/DataTable';
import PageHeader from '@/components/admin/PageHeader';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { useDataTable, type TableParams } from '@/hooks/useDataTable';
import { api } from '@/lib/api';
import { parseServerDate } from '@/lib/date';
import { cn } from '@/lib/utils';
import { Head, Link } from '@inertiajs/react';
import {
    keepPreviousData,
    useQuery,
    useQueryClient,
} from '@tanstack/react-query';
import type { ColumnDef } from '@tanstack/react-table';
import { formatDistanceToNow } from 'date-fns';
import {
    ArchiveRestore,
    ArrowLeft,
    MoreHorizontal,
    Trash2,
    UserX,
} from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';

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

interface TrashedUser {
    id: string;
    name: string;
    email: string;
    avatar_url: string | null;
    department: string | null;
    job_title: string | null;
    deleted_at: string;
}

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

// ── API helpers ───────────────────────────────────────────────────────────────

function fetchTrash(params: TableParams): Promise<TrashResponse> {
    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.search) sp.set('search', params.search);
    return api.get(`/admin/api/users/trash?${sp}`);
}

const apiRestore = (id: string) => api.post(`/admin/users/${id}/restore`);
const apiForceDelete = (id: string) => api.delete(`/admin/users/${id}/force`);
const apiBulkRestore = (ids: string[]) =>
    api.post('/admin/users/bulk-restore', { ids });
const apiBulkForceDelete = (ids: string[]) =>
    api.post('/admin/users/bulk-force-delete', { ids });

// ── Delete dialog descriptions ────────────────────────────────────────────────

function SingleDeleteDescription({ user }: { user: TrashedUser }) {
    return (
        <div className="space-y-3">
            <p>
                You are about to permanently delete <strong>{user.name}</strong>{' '}
                ({user.email}). This action <strong>cannot be undone</strong>.
            </p>
            <div className="rounded-lg border border-red-200 bg-red-50 p-3 dark:border-red-900/40 dark:bg-red-950/20">
                <p className="mb-1.5 text-xs font-semibold tracking-wide text-red-700 uppercase dark:text-red-400">
                    The following will also be removed
                </p>
                <ul className="space-y-1 text-xs text-red-700 dark:text-red-400">
                    <li>• Avatar and all uploaded files for this account</li>
                    <li>• All role assignments (model_has_roles entries)</li>
                    <li>• All session and authentication data</li>
                </ul>
            </div>
        </div>
    );
}

function BulkDeleteDescription({ users }: { users: TrashedUser[] }) {
    return (
        <div className="space-y-3">
            <p>
                You are about to permanently delete{' '}
                <strong>{users.length} admins</strong>. This action{' '}
                <strong>cannot be undone</strong>.
            </p>
            <div className="rounded-lg border border-red-200 bg-red-50 p-3 dark:border-red-900/40 dark:bg-red-950/20">
                <p className="mb-1.5 text-xs font-semibold tracking-wide text-red-700 uppercase dark:text-red-400">
                    For each admin, the following will also be removed
                </p>
                <ul className="space-y-1 text-xs text-red-700 dark:text-red-400">
                    <li>• Avatar and all uploaded files</li>
                    <li>• All role assignments (model_has_roles entries)</li>
                    <li>• All session and authentication data</li>
                </ul>
            </div>
        </div>
    );
}

// ── Avatar cell ───────────────────────────────────────────────────────────────

function UserCell({ user }: { user: TrashedUser }) {
    const initials = user.name
        .split(' ')
        .map((w) => w[0])
        .join('')
        .slice(0, 2)
        .toUpperCase();
    return (
        <div className="flex items-center gap-3">
            {user.avatar_url ? (
                <img
                    src={user.avatar_url}
                    alt={user.name}
                    className="ring-border h-8 w-8 rounded-full object-cover opacity-60 ring-1"
                />
            ) : (
                <span className="bg-muted text-muted-foreground ring-border flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-[10px] font-semibold ring-1">
                    {initials}
                </span>
            )}
            <div className="min-w-0">
                <p className="text-foreground/60 text-sm font-medium line-through">
                    {user.name}
                </p>
                <p className="text-muted-foreground dark:text-muted-foreground/60 text-[11px]">
                    {user.email}
                </p>
            </div>
        </div>
    );
}

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

function RowActions({
    user,
    onRestore,
    onForceDelete,
}: {
    user: TrashedUser;
    onRestore: (u: TrashedUser) => void;
    onForceDelete: (u: TrashedUser) => void;
}) {
    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 {user.name}</span>
                </button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="w-48">
                <DropdownMenuItem
                    className="gap-2 text-xs"
                    onClick={() => onRestore(user)}
                >
                    <ArchiveRestore className="h-3.5 w-3.5" />
                    Restore
                </DropdownMenuItem>
                <DropdownMenuSeparator />
                <DropdownMenuItem
                    className="gap-2 text-xs text-red-600 focus:text-red-600 dark:text-red-400 dark:focus:text-red-400"
                    onClick={() => onForceDelete(user)}
                >
                    <UserX className="h-3.5 w-3.5" />
                    Delete permanently
                </DropdownMenuItem>
            </DropdownMenuContent>
        </DropdownMenu>
    );
}

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

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

// ── Delete target union ───────────────────────────────────────────────────────

type DeleteTarget =
    | { kind: 'single'; user: TrashedUser }
    | { kind: 'bulk'; users: TrashedUser[] };

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

export default function UsersTrash() {
    const qc = useQueryClient();
    const { params, setParams } = useDataTable({
        sort: 'deleted_at',
        dir: 'desc',
    });

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

    const invalidate = () => {
        qc.invalidateQueries({ queryKey: ['admin.users.trash'] });
        qc.invalidateQueries({ queryKey: ['admin.users'] });
    };

    // ── Delete modal state ─────────────────────────────────────────────────────
    const [deleteTarget, setDeleteTarget] = useState<DeleteTarget | null>(null);
    const [deleting, setDeleting] = useState(false);

    const openSingleDelete = (user: TrashedUser) =>
        setDeleteTarget({ kind: 'single', user });
    const openBulkDelete = (users: TrashedUser[]) =>
        setDeleteTarget({ kind: 'bulk', users });
    const closeDelete = () => {
        if (!deleting) setDeleteTarget(null);
    };

    const handleConfirmDelete = async () => {
        if (!deleteTarget) return;
        setDeleting(true);
        try {
            if (deleteTarget.kind === 'single') {
                await apiForceDelete(deleteTarget.user.id);
                toast.success(
                    `"${deleteTarget.user.name}" permanently deleted`,
                );
            } else {
                await apiBulkForceDelete(deleteTarget.users.map((u) => u.id));
                toast.success(
                    `${deleteTarget.users.length} admins permanently deleted`,
                );
            }
            invalidate();
            setDeleteTarget(null);
        } catch {
            toast.error('Failed to permanently delete');
        } finally {
            setDeleting(false);
        }
    };

    // ── Restore handlers ───────────────────────────────────────────────────────
    const handleRestore = async (user: TrashedUser) => {
        try {
            await apiRestore(user.id);
            toast.success(`"${user.name}" restored`);
            invalidate();
        } catch {
            toast.error('Failed to restore admin');
        }
    };

    const handleBulkRestore = async (rows: TrashedUser[]) => {
        try {
            await apiBulkRestore(rows.map((u) => u.id));
            toast.success(`${rows.length} admins restored`);
            invalidate();
        } catch {
            toast.error('Failed to restore admins');
        }
    };

    // ── Columns ────────────────────────────────────────────────────────────────
    const columns: ColumnDef<TrashedUser, unknown>[] = [
        {
            accessorKey: 'name',
            header: 'Admin',
            meta: { sortable: true, label: 'Admin' },
            cell: ({ row }) => <UserCell user={row.original} />,
        },
        {
            accessorKey: 'department',
            header: 'Department',
            meta: { label: 'Department' },
            cell: ({ row }) => (
                <div className="min-w-0">
                    {row.original.department && (
                        <p className="text-foreground/60 text-sm">
                            {row.original.department}
                        </p>
                    )}
                    {row.original.job_title && (
                        <p className="text-muted-foreground dark:text-muted-foreground/60 text-[11px]">
                            {row.original.job_title}
                        </p>
                    )}
                    {!row.original.department && !row.original.job_title && (
                        <span className="text-muted-foreground dark:text-muted-foreground/60 text-xs">
                            —
                        </span>
                    )}
                </div>
            ),
        },
        {
            accessorKey: 'deleted_at',
            header: 'Deleted',
            meta: { sortable: true, label: 'Deleted' },
            cell: ({ row }) => (
                <span className="text-muted-foreground text-xs">
                    {formatDistanceToNow(
                        parseServerDate(row.original.deleted_at),
                        {
                            addSuffix: true,
                        },
                    )}
                </span>
            ),
        },
        {
            id: '_actions',
            header: '',
            cell: ({ row }) => (
                <RowActions
                    user={row.original}
                    onRestore={handleRestore}
                    onForceDelete={openSingleDelete}
                />
            ),
            enableHiding: false,
        },
    ];

    return (
        <AdminLayout
            title="Admins — Trash"
            breadcrumbs={[
                { label: 'System' },
                { label: 'Admins', href: '/admin/users' },
                { label: 'Trash' },
            ]}
        >
            <Head title="Admins — Trash" />

            <div className="space-y-6 p-6 lg:p-8">
                <PageHeader
                    title="Admins Trash"
                    description="Deleted admins are kept here. Restore or permanently delete them."
                    action={
                        <Link
                            href="/admin/users"
                            className={cn(
                                'border-border flex items-center gap-1.5 rounded-lg border px-3 py-2',
                                'text-muted-foreground hover:bg-muted/40 hover:text-foreground text-xs font-medium transition-colors',
                            )}
                        >
                            <ArrowLeft className="h-3.5 w-3.5" />
                            Back to Admins
                        </Link>
                    }
                />

                <DataTable
                    columns={columns}
                    data={data?.data ?? []}
                    meta={data?.meta ?? EMPTY_META}
                    params={params}
                    isLoading={isLoading}
                    isFetching={isFetching}
                    onParamsChange={setParams}
                    quickFilters={[
                        {
                            label: 'All Trash',
                            value: 'all',
                            count: data?.filter_counts.all,
                        },
                    ]}
                    bulkActions={[
                        {
                            label: 'Restore',
                            icon: ArchiveRestore,
                            onClick: handleBulkRestore,
                        },
                        {
                            label: 'Delete permanently',
                            icon: Trash2,
                            onClick: openBulkDelete,
                            variant: 'destructive',
                        },
                    ]}
                    onRefresh={invalidate}
                    searchPlaceholder="Search deleted admins…"
                    noun="admins"
                    getRowId={(row) => String(row.id)}
                />
            </div>

            {/* ── Permanent delete confirmation modal ──────────────────────── */}
            <ConfirmDialog
                open={deleteTarget !== null}
                onOpenChange={closeDelete}
                title="Permanently delete admin?"
                description={
                    deleteTarget?.kind === 'single' ? (
                        <SingleDeleteDescription user={deleteTarget.user} />
                    ) : deleteTarget?.kind === 'bulk' ? (
                        <BulkDeleteDescription users={deleteTarget.users} />
                    ) : null
                }
                confirmLabel="Delete permanently"
                loading={deleting}
                onConfirm={handleConfirmDelete}
            />
        </AdminLayout>
    );
}
