import { Head, router, useForm, usePage } from '@inertiajs/react';
import { Plus, Trash2, Edit, Users, Search, ArrowUpDown, FileDown, FileUp } from 'lucide-react';
import { useState, useMemo } from 'react';
import { toast } from 'sonner';
import { store as storeUser, update as updateUser, destroy as destroyUser } from '@/routes/settings/users';
import { BulkImportModal } from '@/components/bulk-import-modal';
import { Pagination } from '@/components/pagination';
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import AppLayout from '@/layouts/app-layout';

interface Role {
    id: number;
    name: string;
    description: string | null;
}

interface UserAccount {
    id: number;
    name: string;
    email: string;
    roles?: Role[];
}

interface Props {
    users: UserAccount[];
    roles: Role[];
}

type SortField = 'name' | 'email';
type SortOrder = 'asc' | 'desc';

export default function UsersPage({ users, roles }: Props) {
    const authUser = usePage().props.auth.user as { id: number };
    const [isCreateOpen, setIsCreateOpen] = useState(false);
    const [editingUser, setEditingUser] = useState<UserAccount | null>(null);

    // Filters and Sorting State
    const [searchQuery, setSearchQuery] = useState('');
    const [roleFilter, setRoleFilter] = useState<string>('all');
    const [sortField, setSortField] = useState<SortField>('name');
    const [sortOrder, setSortOrder] = useState<SortOrder>('asc');

    // Pagination & Bulk Import/Export State
    const [currentPage, setCurrentPage] = useState(1);
    const [pageSize, setPageSize] = useState(10);
    const [isImportOpen, setIsImportOpen] = useState(false);

    const createForm = useForm({
        name: '',
        email: '',
        password: '',
        role_ids: [] as number[],
    });

    const editForm = useForm({
        name: '',
        email: '',
        password: '',
        role_ids: [] as number[],
    });

    const handleCreate = (e: React.FormEvent) => {
        e.preventDefault();
        createForm.post(storeUser.url(), {
            onSuccess: () => {
                setIsCreateOpen(false);
                createForm.reset();
                toast.success('User created successfully.');
            },
            onError: (errors) => {
                toast.error(
                    errors.email ||
                        errors.name ||
                        errors.password ||
                        'Failed to create user.',
                );
            },
        });
    };

    const handleEditClick = (user: UserAccount) => {
        setEditingUser(user);
        editForm.setData({
            name: user.name,
            email: user.email,
            password: '',
            role_ids: user.roles?.map((r) => r.id) || [],
        });
    };

    const handleUpdate = (e: React.FormEvent) => {
        e.preventDefault();

        if (!editingUser) {
            return;
        }

        editForm.put(updateUser.url(editingUser.id), {
            onSuccess: () => {
                setEditingUser(null);
                toast.success('User updated successfully.');
            },
            onError: (errors) => {
                toast.error(
                    errors.email || errors.name || 'Failed to update user.',
                );
            },
        });
    };

    const handleDelete = (id: number) => {
        if (id === authUser.id) {
            toast.error('You cannot delete your own account.');

            return;
        }

        if (confirm('Are you sure you want to delete this user account?')) {
            router.delete(destroyUser.url(id), {
                onSuccess: () => {
                    toast.success('User deleted successfully.');
                },
                onError: (errors) => {
                    toast.error(errors.error || 'Failed to delete user.');
                },
            });
        }
    };

    const handleRoleChange = (
        formObj: any,
        roleId: number,
        checked: boolean,
    ) => {
        const currentRoles = formObj.data.role_ids;

        if (checked) {
            formObj.setData('role_ids', [...currentRoles, roleId]);
        } else {
            formObj.setData(
                'role_ids',
                currentRoles.filter((id: number) => id !== roleId),
            );
        }
    };

    const handleSort = (field: SortField) => {
        if (sortField === field) {
            setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
        } else {
            setSortField(field);
            setSortOrder('asc');
        }
    };

    // Filtered and Sorted list
    const processedUsers = useMemo(() => {
        let list = [...users];

        // Search filter
        if (searchQuery.trim() !== '') {
            const query = searchQuery.toLowerCase();
            list = list.filter(
                (u) =>
                    u.name.toLowerCase().includes(query) ||
                    u.email.toLowerCase().includes(query),
            );
        }

        // Role filter
        if (roleFilter !== 'all') {
            list = list.filter((u) =>
                u.roles?.some((r) => r.name === roleFilter),
            );
        }

        // Sorting
        list.sort((a, b) => {
            const valA = a[sortField].toLowerCase();
            const valB = b[sortField].toLowerCase();

            if (valA < valB) {
                return sortOrder === 'asc' ? -1 : 1;
            }

            if (valA > valB) {
                return sortOrder === 'asc' ? 1 : -1;
            }

            return 0;
        });

        return list;
    }, [users, searchQuery, roleFilter, sortField, sortOrder]);

    const paginatedUsers = useMemo(() => {
        const start = (currentPage - 1) * pageSize;

        return processedUsers.slice(start, start + pageSize);
    }, [processedUsers, currentPage, pageSize]);

    const handleSearchChange = (val: string) => {
        setSearchQuery(val);
        setCurrentPage(1);
    };

    const handleRoleFilterChange = (val: string) => {
        setRoleFilter(val);
        setCurrentPage(1);
    };

    const handleExportCSV = () => {
        const headers = ['Name', 'Email', 'Roles'];
        const rows = processedUsers.map(user => [
            user.name,
            user.email,
            user.roles?.map(r => r.name).join('; ') ?? ''
        ]);
        const csvContent = "data:text/csv;charset=utf-8," 
            + [headers.join(','), ...rows.map(e => e.map(val => `"${val.replace(/"/g, '""')}"`).join(','))].join('\n');
        const encodedUri = encodeURI(csvContent);
        const link = document.createElement("a");
        link.setAttribute("href", encodedUri);
        link.setAttribute("download", "users_export.csv");
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        toast.success('User list exported successfully.');
    };

    return (
        <>
            <Head title="User Directory & Accounts" />
            <div className="from-zinc-550/20 min-h-screen w-full space-y-8 bg-gradient-to-b via-transparent to-transparent p-6 md:p-10">
                {/* Premium Gradient Header Banner */}
                <div className="from-indigo-600 relative flex flex-col items-start justify-between gap-6 overflow-hidden rounded-3xl border border-white/10 bg-gradient-to-r via-purple-600 to-pink-500 p-8 text-white shadow-2xl md:flex-row md:items-center md:p-10">
                    <div className="absolute inset-0 bg-[radial-gradient(circle_at_top_right,rgba(255,255,255,0.15),transparent_50%)]" />
                    <div className="relative max-w-2xl space-y-2">
                        <span className="rounded-full border border-white/20 bg-white/20 px-3 py-1 text-[10px] font-extrabold tracking-widest text-white/90 uppercase backdrop-blur-md">
                            Access Management
                        </span>
                        <h3 className="text-2xl font-extrabold tracking-tight md:text-3xl">
                            User Directory & Accounts
                        </h3>
                        <p className="text-sm font-medium text-indigo-100">
                            Register corporate workspace operator profiles,
                            configure password attributes, and assign RBAC
                            security role permissions.
                        </p>
                    </div>
                    <div className="flex flex-wrap gap-2.5 shrink-0">
                        <Button
                            variant="outline"
                            onClick={handleExportCSV}
                            className="relative flex items-center gap-2 rounded-xl border border-white/20 bg-white/10 hover:bg-white/20 px-4 py-6 font-bold text-white shadow-lg transition-all duration-300 hover:-translate-y-0.5"
                        >
                            <FileDown className="size-4" /> Export CSV
                        </Button>
                        <Button
                            variant="outline"
                            onClick={() => setIsImportOpen(true)}
                            className="relative flex items-center gap-2 rounded-xl border border-white/20 bg-white/10 hover:bg-white/20 px-4 py-6 font-bold text-white shadow-lg transition-all duration-300 hover:-translate-y-0.5"
                        >
                            <FileUp className="size-4" /> Bulk Import
                        </Button>
                        <Button
                            onClick={() => setIsCreateOpen(true)}
                            className="relative flex items-center gap-2 rounded-xl border border-white/20 bg-white px-5 py-6 font-bold text-indigo-950 shadow-lg transition-all duration-300 hover:-translate-y-0.5 hover:bg-zinc-100 hover:shadow-indigo-500/20"
                        >
                            <Plus className="size-4 stroke-[3px]" /> Add Platform User
                        </Button>
                    </div>
                </div>

                {/* Filters and Search Toolbar */}
                <div className="flex flex-col items-center gap-4 rounded-2xl border border-zinc-200/80 bg-white/60 p-5 shadow-sm backdrop-blur-2xl sm:flex-row dark:border-zinc-800/80 dark:bg-zinc-900/60">
                    <div className="relative w-full sm:flex-1">
                        <Search className="absolute top-1/2 left-3.5 size-4 -translate-y-1/2 text-zinc-400" />
                        <Input
                            className="h-11 rounded-xl border-zinc-200 bg-white/80 pl-10 text-xs shadow-inner focus-visible:ring-indigo-500/50 dark:border-zinc-800 dark:bg-zinc-950/80"
                            placeholder="Search user profile name or registration email..."
                            value={searchQuery}
                            onChange={(e) => handleSearchChange(e.target.value)}
                        />
                    </div>
                    <div className="w-full min-w-[160px] sm:w-auto">
                        <select
                            className="dark:text-zinc-350 h-11 w-full cursor-pointer rounded-xl border border-zinc-200 bg-white/80 px-3.5 py-2 text-xs font-semibold text-zinc-700 shadow-sm focus:ring-2 focus:ring-indigo-500/30 focus:outline-none dark:border-zinc-800 dark:bg-zinc-950/80"
                            value={roleFilter}
                            onChange={(e) => handleRoleFilterChange(e.target.value)}
                        >
                            <option value="all">All Role Scopes</option>
                            {roles.map((role) => (
                                <option
                                    key={role.id}
                                    value={role.name}
                                    className="capitalize"
                                >
                                    🔑 {role.name}
                                </option>
                            ))}
                        </select>
                    </div>
                </div>

                {processedUsers.length === 0 ? (
                    <Card className="flex flex-col items-center justify-center rounded-3xl border-2 border-dashed border-zinc-200 bg-white/30 p-16 text-center backdrop-blur-sm dark:border-zinc-800 dark:bg-zinc-950/10">
                        <div className="mb-4 animate-pulse rounded-full border border-indigo-100 bg-indigo-50 p-4 dark:border-indigo-900 dark:bg-indigo-950/50">
                            <Users className="size-8 text-indigo-500" />
                        </div>
                        <p className="text-base font-bold text-zinc-800 dark:text-zinc-200">
                            No matching user accounts registered
                        </p>
                    </Card>
                ) : (
                    <div className="overflow-hidden rounded-3xl border border-zinc-200/80 bg-white/60 shadow-xl backdrop-blur-2xl transition-all duration-500 dark:border-zinc-800/80 dark:bg-zinc-900/60">
                        <table className="w-full border-collapse text-left text-xs">
                            <thead>
                                <tr className="border-b border-zinc-200 bg-zinc-50/80 text-[10px] font-bold tracking-wider text-zinc-500 uppercase select-none dark:border-zinc-800 dark:bg-zinc-900/50">
                                    <th
                                        className="hover:text-indigo-600 w-[45%] cursor-pointer p-5 pl-8 transition-colors dark:hover:text-indigo-400"
                                        onClick={() => handleSort('name')}
                                    >
                                        <div className="flex items-center gap-1.5">
                                            Collaborator{' '}
                                            <ArrowUpDown className="size-3.5 text-zinc-400" />
                                        </div>
                                    </th>
                                    <th
                                        className="hover:text-indigo-600 w-[40%] cursor-pointer p-5 transition-colors dark:hover:text-indigo-400"
                                        onClick={() => handleSort('email')}
                                    >
                                        <div className="flex items-center gap-1.5">
                                            Email Address{' '}
                                            <ArrowUpDown className="size-3.5 text-zinc-400" />
                                        </div>
                                    </th>
                                    <th className="p-5">Roles Allocated</th>
                                    <th className="w-[150px] p-5 pr-8 text-right">
                                        Actions
                                    </th>
                                </tr>
                            </thead>
                            <tbody className="divide-y divide-zinc-100 dark:divide-zinc-800/80">
                                {paginatedUsers.map((user) => (
                                    <tr
                                        key={user.id}
                                        className="group transition-all duration-300 hover:bg-indigo-50/10 dark:hover:bg-indigo-950/5"
                                    >
                                        <td className="p-5 pl-8">
                                            <div className="flex items-center gap-3">
                                                <div className="flex size-9 shrink-0 items-center justify-center rounded-full border-2 border-white bg-gradient-to-br from-indigo-500 to-purple-500 text-xs font-bold text-white uppercase shadow-sm dark:border-zinc-950">
                                                    {user.name.charAt(0)}
                                                </div>
                                                <div>
                                                    <div className="flex items-center gap-1.5 text-sm font-extrabold text-zinc-900 dark:text-zinc-100">
                                                        <span>{user.name}</span>
                                                        {user.id ===
                                                            authUser.id && (
                                                            <span className="rounded-md border bg-zinc-100 px-2 py-0.5 text-[8px] leading-none font-extrabold tracking-wider text-zinc-500 uppercase shadow-sm dark:bg-zinc-800">
                                                                YOU
                                                            </span>
                                                        )}
                                                    </div>
                                                </div>
                                            </div>
                                        </td>
                                        <td className="p-5">
                                            <div className="text-sm font-medium text-zinc-650 dark:text-zinc-350">
                                                {user.email}
                                            </div>
                                        </td>
                                        <td className="p-5">
                                            <div className="flex flex-wrap gap-1.5">
                                                {user.roles &&
                                                user.roles.length > 0 ? (
                                                    user.roles.map((r) => {
                                                        const isBtn =
                                                            r.name === 'admin';

                                                        return (
                                                            <span
                                                                key={r.id}
                                                                className={`rounded-md border px-2.5 py-0.5 text-[9px] font-bold tracking-wider uppercase ${
                                                                    isBtn
                                                                        ? 'border-purple-250 bg-purple-50 text-purple-600'
                                                                        : 'border-zinc-200/50 bg-zinc-100 text-zinc-600 dark:border-zinc-700/50 dark:bg-zinc-800 dark:text-zinc-400'
                                                                }`}
                                                            >
                                                                {r.name}
                                                            </span>
                                                        );
                                                    })
                                                ) : (
                                                    <span className="text-[11px] text-zinc-400 italic">
                                                        No roles assigned
                                                    </span>
                                                )}
                                            </div>
                                        </td>
                                        <td className="p-5 pr-8 text-right">
                                            <div className="flex items-center justify-end gap-1.5 opacity-0 transition-opacity duration-300 group-hover:opacity-100">
                                                <Button
                                                    variant="ghost"
                                                    size="icon"
                                                    className="size-8 rounded-lg text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900 dark:hover:bg-zinc-800"
                                                    onClick={() =>
                                                        handleEditClick(user)
                                                    }
                                                >
                                                    <Edit className="size-3.5" />
                                                </Button>
                                                <Button
                                                    variant="ghost"
                                                    size="icon"
                                                    className="size-8 rounded-lg text-red-500 hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-950/20"
                                                    disabled={
                                                        user.id === authUser.id
                                                    }
                                                    onClick={() =>
                                                        handleDelete(user.id)
                                                    }
                                                >
                                                    <Trash2 className="size-3.5" />
                                                </Button>
                                            </div>
                                        </td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                        <Pagination
                            currentPage={currentPage}
                            pageSize={pageSize}
                            totalItems={processedUsers.length}
                            onPageChange={setCurrentPage}
                            onPageSizeChange={setPageSize}
                        />
                    </div>
                )}

                {/* Create Dialog */}
                <Dialog open={isCreateOpen} onOpenChange={setIsCreateOpen}>
                    <DialogContent className="max-w-sm rounded-2xl">
                        <DialogHeader>
                            <DialogTitle>Register User</DialogTitle>
                            <DialogDescription>
                                Create a new collaborator profile and allocate
                                permissions.
                            </DialogDescription>
                        </DialogHeader>
                        <form
                            onSubmit={handleCreate}
                            className="space-y-4 pt-2"
                        >
                            <div className="space-y-1">
                                <Label htmlFor="create-name">Name</Label>
                                <Input
                                    id="create-name"
                                    value={createForm.data.name}
                                    onChange={(e) =>
                                        createForm.setData(
                                            'name',
                                            e.target.value,
                                        )
                                    }
                                    placeholder="e.g. Sarah Jenkins"
                                    required
                                />
                            </div>
                            <div className="space-y-1">
                                <Label htmlFor="create-email">Email</Label>
                                <Input
                                    id="create-email"
                                    type="email"
                                    value={createForm.data.email}
                                    onChange={(e) =>
                                        createForm.setData(
                                            'email',
                                            e.target.value,
                                        )
                                    }
                                    placeholder="e.g. sarah@company.com"
                                    required
                                />
                            </div>
                            <div className="space-y-1">
                                <Label htmlFor="create-password">
                                    Initial Password
                                </Label>
                                <Input
                                    id="create-password"
                                    type="password"
                                    value={createForm.data.password}
                                    onChange={(e) =>
                                        createForm.setData(
                                            'password',
                                            e.target.value,
                                        )
                                    }
                                    placeholder="Minimum 8 characters..."
                                    required
                                />
                            </div>
                            <div className="space-y-2 pt-1">
                                <Label className="text-xs font-bold tracking-wider text-zinc-400 uppercase">
                                    Allocate System Roles
                                </Label>
                                <div className="grid grid-cols-2 gap-3">
                                    {roles.map((role) => (
                                        <div
                                            key={role.id}
                                            className="flex items-center space-x-2"
                                        >
                                            <Checkbox
                                                id={`create-role-${role.id}`}
                                                checked={createForm.data.role_ids.includes(
                                                    role.id,
                                                )}
                                                onCheckedChange={(checked) =>
                                                    handleRoleChange(
                                                        createForm,
                                                        role.id,
                                                        checked === true,
                                                    )
                                                }
                                            />
                                            <Label
                                                htmlFor={`create-role-${role.id}`}
                                                className="text-xs capitalize"
                                            >
                                                {role.name}
                                            </Label>
                                        </div>
                                    ))}
                                </div>
                            </div>
                            <DialogFooter className="pt-2">
                                <Button
                                    type="button"
                                    variant="outline"
                                    onClick={() => setIsCreateOpen(false)}
                                    className="rounded-xl"
                                >
                                    Cancel
                                </Button>
                                <Button
                                    type="submit"
                                    disabled={createForm.processing}
                                    className="rounded-xl"
                                >
                                    Create
                                </Button>
                            </DialogFooter>
                        </form>
                    </DialogContent>
                </Dialog>

                {/* Edit Dialog */}
                <Dialog
                    open={!!editingUser}
                    onOpenChange={(open) => !open && setEditingUser(null)}
                >
                    <DialogContent className="max-w-sm rounded-2xl">
                        <DialogHeader>
                            <DialogTitle>Edit User Profile</DialogTitle>
                            <DialogDescription>
                                Modify metadata, modify roles, or trigger
                                credential change.
                            </DialogDescription>
                        </DialogHeader>
                        <form
                            onSubmit={handleUpdate}
                            className="space-y-4 pt-2"
                        >
                            <div className="space-y-1">
                                <Label htmlFor="edit-name">Name</Label>
                                <Input
                                    id="edit-name"
                                    value={editForm.data.name}
                                    onChange={(e) =>
                                        editForm.setData('name', e.target.value)
                                    }
                                    required
                                />
                            </div>
                            <div className="space-y-1">
                                <Label htmlFor="edit-email">Email</Label>
                                <Input
                                    id="edit-email"
                                    type="email"
                                    value={editForm.data.email}
                                    onChange={(e) =>
                                        editForm.setData(
                                            'email',
                                            e.target.value,
                                        )
                                    }
                                    required
                                />
                            </div>
                            <div className="space-y-1">
                                <div className="flex items-center justify-between">
                                    <Label htmlFor="edit-password">
                                        Update Password
                                    </Label>
                                    <span className="text-[10px] text-zinc-400">
                                        Leave blank to keep same
                                    </span>
                                </div>
                                <Input
                                    id="edit-password"
                                    type="password"
                                    value={editForm.data.password}
                                    onChange={(e) =>
                                        editForm.setData(
                                            'password',
                                            e.target.value,
                                        )
                                    }
                                    placeholder="New password..."
                                />
                            </div>
                            <div className="space-y-2 pt-1">
                                <Label className="text-xs font-bold tracking-wider text-zinc-400 uppercase">
                                    Allocate System Roles
                                </Label>
                                <div className="grid grid-cols-2 gap-3">
                                    {roles.map((role) => (
                                        <div
                                            key={role.id}
                                            className="flex items-center space-x-2"
                                        >
                                            <Checkbox
                                                id={`edit-role-${role.id}`}
                                                checked={editForm.data.role_ids.includes(
                                                    role.id,
                                                )}
                                                onCheckedChange={(checked) =>
                                                    handleRoleChange(
                                                        editForm,
                                                        role.id,
                                                        checked === true,
                                                    )
                                                }
                                            />
                                            <Label
                                                htmlFor={`edit-role-${role.id}`}
                                                className="text-xs capitalize"
                                            >
                                                {role.name}
                                            </Label>
                                        </div>
                                    ))}
                                </div>
                            </div>
                            <DialogFooter className="pt-2">
                                <Button
                                    type="button"
                                    variant="outline"
                                    onClick={() => setEditingUser(null)}
                                    className="rounded-xl"
                                >
                                    Cancel
                                </Button>
                                <Button
                                    type="submit"
                                    disabled={editForm.processing}
                                    className="rounded-xl"
                                >
                                    Save Changes
                                </Button>
                            </DialogFooter>
                        </form>
                    </DialogContent>
                </Dialog>

                {/* Bulk Import Modal */}
                <BulkImportModal
                    isOpen={isImportOpen}
                    onClose={() => setIsImportOpen(false)}
                    importUrl="/settings/users/bulk-import"
                    sampleHeaders={['name', 'email', 'password', 'role_name']}
                    sampleRows={[
                        ['Operator Alice', 'alice@company.com', 'password123', 'operator'],
                        ['Admin Bob', 'bob@company.com', 'securepass123', 'admin']
                    ]}
                    title="Import Users"
                />
            </div>
        </>
    );
}

UsersPage.layout = (page: React.ReactNode) => <AppLayout>{page}</AppLayout>;
