import { router, useForm } from '@inertiajs/react';
import type { ColumnDef } from '@tanstack/react-table';
import { Plus, UserCheck, UserMinus } from 'lucide-react';
import type { FormEvent } from 'react';
import { useState, useMemo } from 'react';
import { toast } from 'sonner';
import { DataTable } from '@/components/data-table';
import { FormField } from '@/components/form-field';
import { FormDrawer } from '@/components/layout/form-drawer';
import { PageHeader } from '@/components/layout/page-header';
import { SectionCard } from '@/components/layout/section-card';
import { Button } from '@/components/ui/button';
import { SheetFooter } from '@/components/ui/sheet';
import { Input } from '@/components/ui/input';
import { NativeSelect } from '@/components/ui/native-select';
import { Switch } from '@/components/ui/switch';
import { cn } from '@/lib/utils';
import { index as adminUsersIndex, store as adminUsersStore, edit as adminUserEdit, toggleStatus } from '@/routes/admin/users';

type UserRow = {
    id: number;
    name: string;
    email: string;
    role: string;
    roles: string[];
    is_active: boolean;
    locations: { id: number; name: string }[];
    created_at: string;
};

type Props = {
    users: UserRow[];
    allRoles: string[];
};

const ROLE_COLORS: Record<string, string> = {
    admin: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
    manager: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
    technician: 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400',
};

function StatusToggle({ user }: { user: UserRow }) {
    const [active, setActive] = useState(user.is_active);

    function handleChange(checked: boolean) {
        const prev = active;
        setActive(checked);

        toast[checked ? 'info' : 'warning'](
            checked ? `Activate ${user.name}?` : `Deactivate ${user.name}?`,
            {
                description: checked
                    ? 'They will regain access to the system.'
                    : 'They will lose access until reactivated.',
                action: {
                    label: 'Confirm',
                    onClick: () => {
                        router.post(
                            toggleStatus.url({ user: user.id }),
                            { is_active: checked },
                            {
                                preserveScroll: true,
                                onSuccess: () =>
                                    toast.success(checked ? `${user.name} activated.` : `${user.name} deactivated.`),
                                onError: () => {
                                    setActive(prev);
                                    toast.error('Failed to update status.');
                                },
                            },
                        );
                    },
                },
                cancel: {
                    label: 'Cancel',
                    onClick: () => setActive(prev),
                },
                duration: 8000,
            },
        );
    }

    return (
        <div className="flex items-center gap-2">
            <Switch
                checked={active}
                onCheckedChange={handleChange}
                aria-label={active ? 'Deactivate user' : 'Activate user'}
            />
            <span className={cn(
                'inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide',
                active
                    ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400'
                    : 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',
            )}>
                {active ? (
                    <><UserCheck className="size-2.5" /> Active</>
                ) : (
                    <><UserMinus className="size-2.5" /> Inactive</>
                )}
            </span>
        </div>
    );
}

export default function AdminUsersIndex({ users, allRoles }: Props) {
    const [addOpen, setAddOpen] = useState(false);
    const addForm = useForm({ name: '', email: '', password: '', role: allRoles[0] ?? 'admin' });

    const openAdd = () => {
        addForm.reset();
        addForm.clearErrors();
        setAddOpen(true);
    };

    const closeAdd = () => {
        setAddOpen(false);
        addForm.reset();
        addForm.clearErrors();
    };

    const submitAdd = (e: FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        addForm.post(adminUsersStore.url(), { onSuccess: () => closeAdd() });
    };

    const columns = useMemo<ColumnDef<UserRow>[]>(
        () => [
            {
                accessorKey: 'name',
                header: 'Name',
                meta: { label: 'Name' },
                cell: ({ row }) => (
                    <button
                        type="button"
                        className="font-medium hover:underline"
                        onClick={() => router.get(adminUserEdit.url({ user: row.original.id }))}
                    >
                        {row.original.name}
                    </button>
                ),
            },
            {
                accessorKey: 'email',
                header: 'Email',
                meta: { label: 'Email' },
            },
            {
                accessorKey: 'role',
                header: 'Role',
                meta: { label: 'Role' },
                cell: ({ row }) => (
                    <span
                        className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${ROLE_COLORS[row.original.role] ?? 'bg-muted text-muted-foreground'}`}
                    >
                        {row.original.role}
                    </span>
                ),
            },
            {
                id: 'locations',
                header: 'Locations',
                meta: { label: 'Locations' },
                cell: ({ row }) =>
                    row.original.locations.length > 0 ? (
                        <span className="text-sm">{row.original.locations.map((l) => l.name).join(', ')}</span>
                    ) : (
                        <span className="text-muted-foreground text-sm">—</span>
                    ),
            },
            {
                id: 'status',
                header: 'Status',
                meta: { label: 'Status' },
                cell: ({ row }) => <StatusToggle user={row.original} />,
            },
            {
                accessorKey: 'created_at',
                header: 'Joined',
                meta: { label: 'Joined' },
            },
            {
                id: 'actions',
                cell: ({ row }) => (
                    <Button
                        variant="outline"
                        size="sm"
                        onClick={() => router.get(adminUserEdit.url({ user: row.original.id }))}
                    >
                        Manage
                    </Button>
                ),
            },
        ],
        [],
    );

    return (
        <>
            <div className="flex h-full flex-1 flex-col gap-6">
                <PageHeader
                    title="Users"
                    description="Manage roles, location assignments, and direct permissions for each user."
                    actions={
                        <Button size="sm" onClick={openAdd}>
                            <Plus className="size-4" />
                            Add user
                        </Button>
                    }
                />
                <SectionCard title="Staff">
                    <DataTable columns={columns} data={users} searchPlaceholder="Search staff..." />
                </SectionCard>
            </div>

            <FormDrawer
                open={addOpen}
                onOpenChange={(open) => {
                    if (!open) {
                        closeAdd();
                    }
                }}
                title="Add user"
                direction="right"
            >
                <form onSubmit={submitAdd} className="grid gap-3">
                    <FormField label="Name" htmlFor="add-name" error={addForm.errors.name}>
                        <Input
                            id="add-name"
                            value={addForm.data.name}
                            onChange={(e) => addForm.setData('name', e.target.value)}
                            autoFocus
                        />
                    </FormField>
                    <FormField label="Email" htmlFor="add-email" error={addForm.errors.email}>
                        <Input
                            id="add-email"
                            type="email"
                            value={addForm.data.email}
                            onChange={(e) => addForm.setData('email', e.target.value)}
                        />
                    </FormField>
                    <FormField label="Password" htmlFor="add-password" error={addForm.errors.password}>
                        <Input
                            id="add-password"
                            type="password"
                            value={addForm.data.password}
                            onChange={(e) => addForm.setData('password', e.target.value)}
                        />
                    </FormField>
                    <FormField label="Role" htmlFor="add-role" error={addForm.errors.role}>
                        <NativeSelect
                            id="add-role"
                            value={addForm.data.role}
                            onChange={(e) => addForm.setData('role', e.target.value)}
                        >
                            {allRoles.map((r) => (
                                <option key={r} value={r}>{r.charAt(0).toUpperCase() + r.slice(1)}</option>
                            ))}
                        </NativeSelect>
                    </FormField>
                    <SheetFooter className="px-0 pb-0 sm:flex-row">
                        <Button type="button" variant="outline" onClick={closeAdd}>Cancel</Button>
                        <Button type="submit" disabled={addForm.processing}>Create user</Button>
                    </SheetFooter>
                </form>
            </FormDrawer>
        </>
    );
}

AdminUsersIndex.layout = {
    breadcrumbs: [{ title: 'Users', href: adminUsersIndex() }],
};
