import AdminLayout from '@/Layouts/AdminLayout';
import { DataTable, type TableMeta } from '@/components/admin/DataTable';
import PageHeader from '@/components/admin/PageHeader';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { useDataTable, type TableParams } from '@/hooks/useDataTable';
import { useDeleteWithUndo } from '@/hooks/useDeleteWithUndo';
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 { format } from 'date-fns';
import { Eye, MoreHorizontal, Pencil, Plus, Trash2, UserX } from 'lucide-react';

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

interface AdminUser {
    id: string;
    name: string;
    email: string;
    phone: string | null;
    status: 'active' | 'inactive' | 'suspended';
    job_title: string | null;
    department: string | null;
    timezone: string;
    last_login_at: string | null;
    created_at: string;
    avatar_url: string | null;
    role: string | null;
}

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

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

function fetchUsers(params: TableParams): Promise<UsersResponse> {
    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);
    if (params.filter && params.filter !== 'all')
        sp.set('filter', params.filter);
    return api.get(`/admin/api/users?${sp}`);
}

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

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

const STATUS_STYLES: Record<string, string> = {
    active: 'bg-green-500/10 text-green-700 dark:text-green-400',
    inactive: 'bg-muted text-muted-foreground',
    suspended: 'bg-red-500/10 text-red-600 dark:text-red-400',
};

function StatusBadge({ status }: { status: string }) {
    return (
        <span
            className={cn(
                'rounded-full px-2 py-0.5 text-[10px] font-semibold capitalize',
                STATUS_STYLES[status] ?? STATUS_STYLES.inactive,
            )}
        >
            {status}
        </span>
    );
}

// ── Avatar ────────────────────────────────────────────────────────────────────

function Avatar({ user }: { user: AdminUser }) {
    if (user.avatar_url) {
        return (
            <img
                src={user.avatar_url}
                alt={user.name}
                className="ring-border h-8 w-8 rounded-full object-cover ring-1"
            />
        );
    }
    const initials = user.name
        .split(' ')
        .map((w) => w[0])
        .join('')
        .slice(0, 2)
        .toUpperCase();
    return (
        <span className="bg-primary/10 text-primary ring-border flex h-8 w-8 items-center justify-center rounded-full text-xs font-semibold ring-1">
            {initials}
        </span>
    );
}

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

function RowActions({
    user,
    onDelete,
}: {
    user: AdminUser;
    onDelete: (u: AdminUser) => 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</span>
                </button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="w-44">
                <DropdownMenuItem asChild className="gap-2 text-xs">
                    <Link href={`/admin/users/${user.id}`}>
                        <Eye className="h-3.5 w-3.5" />
                        View profile
                    </Link>
                </DropdownMenuItem>
                <DropdownMenuItem asChild className="gap-2 text-xs">
                    <Link href={`/admin/users/${user.id}/edit`}>
                        <Pencil className="h-3.5 w-3.5" />
                        Edit
                    </Link>
                </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={() => onDelete(user)}
                >
                    <UserX className="h-3.5 w-3.5" />
                    Delete
                </DropdownMenuItem>
            </DropdownMenuContent>
        </DropdownMenu>
    );
}

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

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

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

export default function UsersIndex() {
    const qc = useQueryClient();
    const { params, setParams } = useDataTable({ sort: 'name', dir: 'asc' });
    const { deleteWithUndo } = useDeleteWithUndo();

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

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

    const handleDelete = (user: AdminUser) => {
        deleteWithUndo({
            noun: 'user',
            onDelete: () => apiDelete(user.id),
            onUndo: () => apiRestore(user.id),
            onSuccess: invalidate,
        });
    };

    const handleBulkDelete = (rows: AdminUser[]) => {
        const ids = rows.map((r) => r.id);
        deleteWithUndo({
            noun: 'user',
            count: ids.length,
            onDelete: () => apiBulk(ids),
            onUndo: () => apiBulkRst(ids),
            onSuccess: invalidate,
        });
    };

    const exportUrl = (() => {
        const sp = new URLSearchParams();
        if (params.search) sp.set('search', params.search);
        if (params.filter && params.filter !== 'all')
            sp.set('filter', params.filter);
        const qs = sp.toString();
        return `/admin/users/export${qs ? `?${qs}` : ''}`;
    })();

    const columns: ColumnDef<AdminUser, unknown>[] = [
        {
            accessorKey: 'name',
            header: 'Admin',
            meta: { sortable: true, label: 'Admin' },
            cell: ({ row }) => (
                <div className="flex items-center gap-3">
                    <Avatar user={row.original} />
                    <div className="min-w-0">
                        <p className="text-foreground text-sm font-medium">
                            {row.original.name}
                        </p>
                        <p className="text-muted-foreground text-[11px]">
                            {row.original.email}
                        </p>
                    </div>
                </div>
            ),
        },
        {
            accessorKey: 'role',
            header: 'Role',
            meta: { label: 'Role' },
            cell: ({ row }) =>
                row.original.role ? (
                    <span className="text-foreground/70 font-mono text-xs">
                        {row.original.role}
                    </span>
                ) : (
                    <span className="text-muted-foreground dark:text-muted-foreground/65 text-xs">
                        —
                    </span>
                ),
        },
        {
            accessorKey: 'department',
            header: 'Department',
            meta: { sortable: true, label: 'Department' },
            cell: ({ row }) => (
                <div className="min-w-0">
                    {row.original.department && (
                        <p className="text-foreground/80 text-sm">
                            {row.original.department}
                        </p>
                    )}
                    {row.original.job_title && (
                        <p className="text-muted-foreground text-[11px]">
                            {row.original.job_title}
                        </p>
                    )}
                    {!row.original.department && !row.original.job_title && (
                        <span className="text-muted-foreground dark:text-muted-foreground/65 text-xs">
                            —
                        </span>
                    )}
                </div>
            ),
        },
        {
            accessorKey: 'status',
            header: 'Status',
            meta: { sortable: true, label: 'Status' },
            cell: ({ row }) => <StatusBadge status={row.original.status} />,
        },
        {
            accessorKey: 'last_login_at',
            header: 'Last Login',
            meta: { sortable: true, label: 'Last Login' },
            cell: ({ row }) => (
                <span className="text-muted-foreground text-xs">
                    {row.original.last_login_at
                        ? format(
                              parseServerDate(row.original.last_login_at),
                              'dd MMM yyyy',
                          )
                        : 'Never'}
                </span>
            ),
        },
        {
            accessorKey: 'created_at',
            header: 'Joined',
            meta: { sortable: true, label: 'Joined' },
            cell: ({ row }) => (
                <span className="text-muted-foreground text-xs">
                    {format(
                        parseServerDate(row.original.created_at),
                        'dd MMM yyyy',
                    )}
                </span>
            ),
        },
        {
            id: '_actions',
            header: '',
            cell: ({ row }) => (
                <RowActions user={row.original} onDelete={handleDelete} />
            ),
            enableHiding: false,
        },
    ];

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

            <div className="space-y-6 p-6 lg:p-8">
                <PageHeader
                    title="Admins"
                    description="Manage admin user accounts and their access levels"
                    action={
                        <div className="flex items-center gap-2">
                            <Link
                                href="/admin/users/trash"
                                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',
                                )}
                            >
                                <Trash2 className="h-3.5 w-3.5" />
                                Trash
                            </Link>
                            <Link
                                href="/admin/users/create"
                                className="bg-primary text-primary-foreground hover:bg-primary/90 flex items-center gap-1.5 rounded-lg px-3 py-2 text-xs font-semibold transition-colors"
                            >
                                <Plus className="h-3.5 w-3.5" />
                                New admin
                            </Link>
                        </div>
                    }
                />

                <DataTable
                    columns={columns}
                    data={data?.data ?? []}
                    meta={data?.meta ?? EMPTY_META}
                    params={params}
                    isLoading={isLoading}
                    isFetching={isFetching}
                    onParamsChange={setParams}
                    quickFilters={[
                        {
                            label: 'All',
                            value: 'all',
                            count: data?.filter_counts.all,
                        },
                        {
                            label: 'Active',
                            value: 'active',
                            count: data?.filter_counts.active,
                        },
                        {
                            label: 'Inactive',
                            value: 'inactive',
                            count: data?.filter_counts.inactive,
                        },
                        {
                            label: 'Suspended',
                            value: 'suspended',
                            count: data?.filter_counts.suspended,
                        },
                    ]}
                    bulkActions={[
                        {
                            label: 'Delete',
                            icon: Trash2,
                            onClick: handleBulkDelete,
                            variant: 'destructive',
                        },
                    ]}
                    exportUrl={exportUrl}
                    onRefresh={invalidate}
                    searchPlaceholder="Search admins…"
                    noun="admins"
                    getRowId={(row) => String(row.id)}
                />
            </div>
        </AdminLayout>
    );
}
