import { ActivityLogSidebar } from '@/components/activity-log/ActivityLogSidebar';
import { useModelActivityLog } from '@/components/activity-log/useModelActivityLog';
import { DataTable } from '@/components/datatable';
import { FilterConfig } from '@/components/datatable-toolbar';
import { BulkStatusEditModal } from '@/components/modals/bulk-status-edit-modal';
import { BulkExportModal } from '@/components/modals/bulkExportModal';
import { SendEmailModal } from '@/components/modals/sendEmailModal';
import { UserModal } from '@/components/modals/UserModal';
import StatisticCardLarge from '@/components/dashboard/StatisticCardLarge';
import { SkeletonTableWithStateCard } from '@/components/skeleton';
import { userTableColumns } from '@/components/tableColumns/userTableColumns';
import { Button } from '@/components/ui/button';
import { useModal } from '@/components/ui/modal';
import AppLayout from '@/layouts/app-layout';
import { fetchDatatable } from '@/lib/datatable-fetch';
import { bgColor } from '@/lib/Icon-bg-Color';
import { type PaginatedData, type User } from '@/types';
import { Head, router, usePage } from '@inertiajs/react';
import { Download, Plus, Send, Upload, Users } from 'lucide-react';
import { ReactNode, useEffect, useState } from 'react';
import { toast } from 'sonner';

declare const can: (permission: string) => any;
declare const route: (...args: any[]) => string;

interface UserSummaryItem {
    title: string;
    value: number;
}

interface UserStatusItem {
    label: string;
    value: string;
}
type UsersIndexData = PaginatedData<User> & { userSummary?: UserSummaryItem[]; userStatuses?: UserStatusItem[] };
type UsersIndexProps = { usersData: UsersIndexData };

function IndexLayout({ children, pageTitle }: { children: ReactNode; pageTitle: string }) {
    return (
        <AppLayout
            title={pageTitle}
            breadcrumbs={[
                { title: 'Home', href: '/' },
                { title: 'Users', href: '#' },
                { title: pageTitle, href: '#' },
            ]}
        >
            {children}
        </AppLayout>
    );
}

function Index() {
    const { roles, branches = [], pageTitle = 'Employees', userType = 1 } = usePage().props as any;

    // Derive permission group name from user type
    const userGroup = (() => {
        switch (Number(userType)) {
            case 2: return 'partner';
            case 3: return 'teacher';
            case 4: return 'board_member';
            default: return 'employee';
        }
    })();

    const [selectedUsersForStatus, setSelectedUsersForStatus] = useState<User[]>([]);
    const [selectedUsersForExport, setSelectedUsersForExport] = useState<User[]>([]);
    const [selectedUserForEmail, setSelectedUserForEmail] = useState<User | null>(null);
    const [selectedUsersForBulkEmail, setSelectedUsersForBulkEmail] = useState<User[]>([]);
    const [selectAllAcrossPages, setSelectAllAcrossPages] = useState(false);
    const [selectedUserForEdit, setSelectedUserForEdit] = useState<User | null>(null);
    const [selectedColumns, setSelectedColumns] = useState<string[]>([]);
    const { isOpen: isStatusModalOpen, openModal: openStatusModal, closeModal: closeStatusModal } = useModal();
    const { isOpen: isBulkExportModalOpen, openModal: openBulkExportModal, closeModal: closeBulkExportModal } = useModal();
    const { isOpen: isEmailModalOpen, openModal: openEmailModal, closeModal: closeEmailModal } = useModal();
    const { isOpen: isBulkEmailModalOpen, openModal: openBulkEmailModal, closeModal: closeBulkEmailModal } = useModal();
    const { isOpen: isUserModalOpen, openModal: openUserModal, closeModal: closeUserModal } = useModal();
    const { isOpen: isExportModalOpen, openModal: openExportModal, closeModal: closeExportModal } = useModal();
    const [clientData, setClientData] = useState<any>({});
    const [summary, setSummary] = useState<UserSummaryItem[]>([]);
    const [isLoading, setIsLoading] = useState(true);

    const activityLogCtl = useModelActivityLog();

    const handleColumnChange = (columnValue: string, checked: boolean) => {
        if (checked) {
            setSelectedColumns((prev) => [...prev, columnValue]);
        } else {
            setSelectedColumns((prev) => prev.filter((col) => col !== columnValue));
        }
    };

    useEffect(() => {
        refetchUsers();
    }, []);

    const handleDeleteUser = (userId: number | string) => {
        router.delete(route('users.destroy', userId));
        refetchUsers();
    };

    const refetchUsers = async () => {
        const url = route('users.index');
        const params = { ...(clientData?.queryParams || {}), type: userType };
        const json = await fetchDatatable<User>(url, params);
        setClientData({
            data: json.data,
            meta: json.meta,
            queryParams: { ...(clientData?.queryParams || {}), type: userType },
            userStatuses: (json as any).userStatuses || [],
            links: {
                prev: json.meta.current_page > 1 ? '' : null,
                next: json.meta.current_page < json.meta.last_page ? '' : null,
            },
        });
        if ((json as any).userSummary) {
            setSummary((json as any).userSummary as any);
        }
    };

    const handleSendEmail = (user: User) => {
        setSelectedUserForEmail(user);
        openEmailModal();
    };

    const handleEditUser = (user: User) => {
        router.visit(route('users.edit', (user as any).uid));
    };
    const handleCreateUser = () => {
        setSelectedUserForEdit(null);
        openUserModal();
    };

    const humanize = (str: string | undefined): string => {
        if (!str) return '';
        return str
            .replace(/[_-]+/g, ' ')
            .replace(/\s+/g, ' ')
            .trim()
            .toLowerCase()
            .split(' ')
            .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
            .join(' ');
    };

    const roleOptions = Array.isArray(roles)
        ? roles.map((r: any) => ({
            label: humanize(r.name || r.slug || ''),
            value: r.slug || (r.name ? r.name.toLowerCase() : r.id),
        }))
        : [];

    const filters: FilterConfig[] = [
        {
            type: 'searchable-multiselect',
            label: 'Role',
            name: 'role',
            value: clientData?.queryParams?.role || '',
            options: roleOptions,
        },
        {
            type: 'searchable-multiselect',
            label: 'Status',
            name: 'status',
            value: clientData?.queryParams?.status || '',
            options: clientData?.userStatuses || [],
        },
        {
            type: 'date-range',
            label: 'Created At',
            name: 'created_at',
            value: '',
        },
    ];

    const bulkActions = [
        can(`export_${userGroup}`) && {
            label: 'Export Data',
            icon: Download,
            confirm: false,
            className: '',
            onClick: (items: User[]) => {
                setSelectedUsersForExport(items);
                openBulkExportModal();
            },
        },
        can(`bulk_action_${userGroup}`) && {
            label: 'Status Update',
            icon: Users,
            confirm: false,
            className: '',
            onClick: (items: User[]) => {
                setSelectedUsersForStatus(items);
                openStatusModal();
            },
        },
        can(`edit_${userGroup}`) && {
            label: 'Send Email',
            icon: Send,
            confirm: false,
            className: '',
            onClick: (items: User[]) => {
                setSelectedUsersForBulkEmail(items);
                openBulkEmailModal();
            },
        },
    ].filter(Boolean);

    useEffect(() => {
        setSelectAllAcrossPages(false);
    }, [
        clientData?.queryParams?.page,
        clientData?.queryParams?.per_page,
        clientData?.queryParams?.search,
        clientData?.queryParams?.role,
        clientData?.queryParams?.status,
    ]);

    const handleUserStatus = (id: number, status: string) => {
        router.put(route('users.status', id), { status: status }, {
            onSuccess: () => {
                toast.success('User status updated successfully!');
                refetchUsers();
            },
            onError: (errors) => {
                console.error('Status update errors:', errors);
                toast.error('Failed to update user status. Please try again.');
            },
        });
    };

    const entityLabel = pageTitle.replace(/s$/, '');
    const statusOptions = clientData?.userStatuses || [];
    const dataColumns = userTableColumns({
        handleDeleteUser,
        handleSendEmail,
        handleEditUser,
        handleUserStatus,
        statusOptions,
        entityLabel,
        userGroup,
    });

    const handleActivitySidebar = () => {
        return activityLogCtl.show({ modelClass: 'User', title: 'User Model Activity' });
    };

    useEffect(() => {
        const timer = setTimeout(() => {
            setIsLoading(false);
        }, 500);
        return () => clearTimeout(timer);
    }, []);

    const bulkStatusOptions = [
        { label: 'Active', value: 'active' },
        { label: 'Inactive', value: 'inactive' },
    ].map((status: any) => {
        const getStatusColor = (value: string | number) => {
            switch (value) {
                case 'active':
                    return 'border-brand-900 text-green-900';
                case 'inactive':
                    return 'border-gray-500 text-gray-500';
            }
        };
        return {
            value: status?.value,
            label: status?.label,
            color: getStatusColor(status?.value),
        };
    });

    if (isLoading) {
        return (
            <>
                <Head title={`Loading ${pageTitle}...`} />
                <SkeletonTableWithStateCard
                    showBreadcrumbs={true}
                    showActionButtons={true}
                    showStats={true}
                    statCount={4}
                    showTable={true}
                    tableRows={6}
                    animation="pulse"
                />
            </>
        );
    }

    return (
        <>
            <Head title={pageTitle} />
            <div className="no-scrollbar rounded-xl bg-gray-100/55 p-2 sm:p-4">
                <div className="">
                    <div className="mb-6 flex flex-col items-start justify-between gap-4 sm:flex-row sm:items-center">
                        <div className="grid grid-cols-1 gap-1">
                            <h2 className="text-xl font-bold sm:text-2xl" onClick={refetchUsers}>
                                {pageTitle}
                            </h2>
                            <div className="flex items-center text-sm text-gray-600">
                                <span>Users</span>
                                <span className="mx-2">›</span>
                                <span>{pageTitle}</span>
                            </div>
                        </div>
                        <div className="flex flex-wrap gap-2 sm:gap-4">
                            {can(`create_${userGroup}`) && (
                                <Button className="bg-success text-white hover:bg-brand-800" size="sm" onClick={handleCreateUser}>
                                    <div className="flex items-center gap-2">
                                        <Plus className="size-4" />
                                        <span className="hidden sm:inline">Add {pageTitle.replace(/s$/, '')}</span>
                                    </div>
                                </Button>
                            )}
                            {can(`import_${userGroup}`) && (
                                <Button variant="outline" size="sm" onClick={() => router.visit(`${route('users.import')}?type=${userType}`)}>
                                    <div className="flex items-center gap-2">
                                        <Upload className="size-4" />
                                        <span className="hidden sm:inline">Import</span>
                                    </div>
                                </Button>
                            )}
                            {can(`export_${userGroup}`) && (
                                <Button
                                    variant="outline"
                                    size="sm"
                                    onClick={() => {
                                        setSelectedUsersForExport(clientData?.data);
                                        openExportModal();
                                    }}
                                >
                                    <div className="flex items-center gap-2">
                                        <Download className="size-4" />
                                        <span className="hidden sm:inline">Export</span>
                                    </div>
                                </Button>
                            )}
                        </div>
                    </div>

                    {summary && summary.length > 0 && (
                        <div className="mb-4 grid grid-cols-2 gap-4 lg:grid-cols-4">
                            {summary.map((s: UserSummaryItem, idx: number) => {
                                const { icon: Icon, bg, icons } = bgColor(s?.title);
                                return (
                                    <StatisticCardLarge
                                        key={idx}
                                        title={s.title || ''}
                                        value={s.value}
                                        icon={Icon as any}
                                        iconBg={bg}
                                        iconColor={icons}
                                    />
                                );
                            })}
                        </div>
                    )}
                    <div className="w-full">
                        <DataTable
                            columns={dataColumns}
                            data={clientData?.data || []}
                            paginatedData={clientData}
                            bulkActions={bulkActions}
                            tableKey="users-table"
                            filters={filters}
                            enableRowClick={false}
                            fullHeight={false}
                            selectAllActive={selectAllAcrossPages}
                            onSelectAllAcrossPages={() => setSelectAllAcrossPages(true)}
                            onClearSelectAllAcrossPages={() => setSelectAllAcrossPages(false)}
                            onNavigate={async (params) => {
                                const url = route('users.data');
                                const json = await fetchDatatable<User>(url, { ...params, type: userType });
                                setClientData({
                                    data: json.data,
                                    meta: json.meta,
                                    queryParams: { ...params, type: userType },
                                    userStatuses: (json as any).userStatuses || [],
                                    links: {
                                        prev: json.meta.current_page > 1 ? '' : null,
                                        next: json.meta.current_page < json.meta.last_page ? '' : null,
                                    },
                                });
                                if ((json as any).userSummary) {
                                    setSummary((json as any).userSummary as any);
                                }
                            }}
                            handleActivitySidebar={handleActivitySidebar}
                        />
                    </div>
                </div>
            </div>

            <BulkStatusEditModal
                open={isStatusModalOpen}
                onOpenChange={closeStatusModal}
                selectedUsers={selectedUsersForStatus}
                selectAll={selectAllAcrossPages}
                totalCount={clientData?.meta?.total}
                currentFilters={clientData?.queryParams}
                statusOptions={bulkStatusOptions}
                apiRoute="users.bulk-action"
                onSuccess={() => {
                    setSelectedUsersForStatus([]);
                    router.reload();
                    refetchUsers();
                }}
            />

            <BulkExportModal
                open={isBulkExportModalOpen}
                onOpenChange={closeBulkExportModal}
                selectedUsers={selectedUsersForExport}
                selectAll={selectAllAcrossPages}
                totalCount={clientData?.meta?.total}
                currentFilters={clientData?.queryParams}
                onSuccess={() => setSelectedUsersForExport([])}
                config={{
                    route: 'users.bulk-action',
                    payload: {
                        type: 'export',
                        ids: selectedUsersForExport.map((user) => user.id),
                        data: { columns: selectedColumns },
                    },
                }}
                handleColumnChange={handleColumnChange}
                selectedColumns={selectedColumns}
                title={`Export ${pageTitle}`}
                itemName="user"
            />

            <BulkExportModal
                open={isExportModalOpen}
                onOpenChange={closeExportModal}
                selectedUsers={selectedUsersForExport}
                selectAll={selectAllAcrossPages}
                totalCount={clientData?.meta?.total}
                currentFilters={clientData?.queryParams}
                onSuccess={() => setSelectedUsersForExport([])}
                config={{
                    route: 'users.export',
                    payload: { columns: selectedColumns },
                }}
                handleColumnChange={handleColumnChange}
                selectedColumns={selectedColumns}
                title={`Export ${pageTitle}`}
                itemName="user"
            />

            <SendEmailModal
                open={isEmailModalOpen}
                onOpenChange={closeEmailModal}
                selectedUser={selectedUserForEmail}
                onSuccess={() => setSelectedUserForEmail(null)}
            />
            <SendEmailModal
                open={isBulkEmailModalOpen}
                onOpenChange={(open) => {
                    if (!open) {
                        setSelectedUsersForBulkEmail([]);
                        closeBulkEmailModal();
                    } else {
                        openBulkEmailModal();
                    }
                }}
                selectedUsers={selectedUsersForBulkEmail}
                selectAll={selectAllAcrossPages}
                currentFilters={clientData?.queryParams}
                onSuccess={() => setSelectedUsersForBulkEmail([])}
                isBulk={true}
            />

            <UserModal
                open={isUserModalOpen}
                onOpenChange={closeUserModal}
                user={selectedUserForEdit}
                roles={roles}
                branches={branches}
                userType={userType}
                entityLabel={entityLabel}
                onSuccess={async () => {
                    setSelectedUserForEdit(null);
                    await refetchUsers();
                }}
            />
            <ActivityLogSidebar
                open={activityLogCtl.open}
                onOpenChange={activityLogCtl.setOpen}
                modelClass={activityLogCtl.modelClass}
                modelId={activityLogCtl.modelId}
                title={activityLogCtl.title}
            />
        </>
    );
}

Index.layout = (page: ReactNode) => {
    const props = (page as any).props as { pageTitle?: string };
    const title = props?.pageTitle || 'Employees';
    return (
        <IndexLayout pageTitle={title}>
            {page}
        </IndexLayout>
    );
};

export default Index;
