import { Form, FormField } from '@admin/components/form';
import { Button } from '@admin/components/ui/button';
import { Card, CardContent } from '@admin/components/ui/card';
import { Checkbox } from '@admin/components/ui/checkbox';
import { Label } from '@admin/components/ui/label';
import { Switch } from '@admin/components/ui/switch';
import AppLayout from '@admin/layouts/app-layout';
import SettingsLayout from '@admin/layouts/settings/layout';
import { Head, router, usePage } from '@inertiajs/react';
import { Activity, Save } from 'lucide-react';
import { useEffect, useState } from 'react';

import { ActivityLogSidebar } from '@admin/components/activity-log/ActivityLogSidebar';
import { useModelActivityLog } from '@admin/components/activity-log/useModelActivityLog';
import HeadingSmall from '@admin/components/heading-small';
import { ReactNode } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';

type NotificationType = {
    id: number;
    name: string;
    slug: string;
    notification_id: number;
    status: number;
};

type Notification = {
    id: number;
    name: string;
    slug: string;
    status: number;
    types: NotificationType[];
    group?: string;
};

// Skeleton Loader Components
const SkeletonCard = () => (
    <Card className="animate-pulse overflow-hidden p-0">
        <div className="flex items-center justify-between bg-muted/40 px-6 py-3">
            <div className="flex items-center gap-3">
                <div className="h-6 w-32 rounded bg-gray-200"></div>
                <div className="h-5 w-20 rounded bg-gray-200"></div>
            </div>
            <div className="flex items-center space-x-2">
                <div className="h-4 w-16 rounded bg-gray-200"></div>
                <div className="h-4 w-4 rounded bg-gray-200"></div>
            </div>
        </div>
        <div className="grid grid-cols-1 gap-4 p-6 md:grid-cols-4">
            {[...Array(4)].map((_, index) => (
                <div key={index} className="flex items-center gap-2 rounded-lg">
                    <div className="h-4 w-4 rounded bg-gray-200"></div>
                    <div className="h-4 w-24 rounded bg-gray-200"></div>
                </div>
            ))}
        </div>
    </Card>
);

const SkeletonHeading = () => (
    <div className="space-y-2">
        <div className="h-6 w-48 animate-pulse rounded bg-gray-200"></div>
        <div className="h-4 w-96 animate-pulse rounded bg-gray-200"></div>
    </div>
);

const SkeletonButton = () => <div className="h-9 w-24 animate-pulse rounded bg-gray-200"></div>;

const SkeletonSubmitButton = () => <div className="h-10 w-32 animate-pulse rounded bg-gray-200"></div>;

export default function Edit() {
    const [isLoading, setIsLoading] = useState(true);
    const { notificationsByModule } = usePage().props as any;
    const activityLogCtl = useModelActivityLog() as any;

    // Show skeleton for 1 second
    useEffect(() => {
        const timer = setTimeout(() => {
            setIsLoading(false);
        }, 1000);

        return () => clearTimeout(timer);
    }, []);

    // Build modules record from server payload (module => notifications[])
    const modules: Record<string, Notification[]> = Object.entries(notificationsByModule || {}).reduce(
        (acc: Record<string, Notification[]>, [moduleName, items]) => {
            acc[moduleName] = (items as any[]).map((n) => ({
                ...n,
                types: (n.types || []).map((t: any) => ({ ...t, status: t.status === 1 })),
            }));
            return acc;
        },
        {},
    );
    // Flatten for form binding indices
    const initialNotifications: Notification[] = Object.values(modules).flat();
    const defaultValues = { notifications: initialNotifications };

    const onSubmit = async (data: any) => {
        // normalize statuses to 1/0
        const notifications: Notification[] = (data.notifications || []).map((n: any) => ({
            ...n,
            types: (n.types || []).map((t: any) => ({ ...t, status: t.status ? 1 : 0 })),
        }));
        router.patch(
            route('settings.notification.update'),
            { notifications },
            {
                onStart: () => {
                    setIsLoading(true); // show skeleton while request is running
                },
                onSuccess: () => {
                    setTimeout(() => {
                        setIsLoading(false);
                    }, 500);
                    // ✅ hide skeleton after success
                },
                onError: () => {
                    setIsLoading(false); // also hide if failed
                },
            },
        );
    };

    const GroupLabel = ({ index }: { index: number }) => {
        const notifications: any = useWatch({ name: 'notifications' });
        const types = notifications?.[index]?.types || [];
        const allSelected = types.every((t: any) => t.status === true || t.status === 1);
        return <Label className="text-sm">{allSelected ? 'Select all' : 'Select all'}</Label>;
    };

    const GroupToggle = ({ index }: { index: number }) => {
        const { setValue } = useFormContext();
        const notifications: any = useWatch({ name: 'notifications' });
        const types = notifications?.[index]?.types || [];
        const allSelected = types.length > 0 && types.every((t: any) => t.status === true || t.status === 1);
        const someSelected = types.some((t: any) => t.status === true || t.status === 1) && !allSelected;

        return (
            <div className="flex items-center space-x-2">
                <Checkbox
                    checked={allSelected}
                    aria-checked={someSelected ? 'mixed' : allSelected ? 'true' : 'false'}
                    onCheckedChange={(checked: boolean) => {
                        const updated = (notifications || []).map((n: any, idx: number) => {
                            if (idx !== index) return n;
                            return {
                                ...n,
                                types: n.types.map((t: any) => ({ ...t, status: Boolean(checked) })),
                            };
                        });
                        setValue('notifications', updated);
                    }}
                />
            </div>
        );
    };

    // Skeleton Loader
    if (isLoading) {
        return (
            <>
                <Head title="Loading Notification Settings..." />
                <SettingsLayout tab={'platform'}>
                    <div className="space-y-6">
                        <Card className="px-4 py-3">
                            <div className="flex items-start justify-between">
                                <SkeletonHeading />
                                <SkeletonButton />
                            </div>

                            <CardContent className="px-0 py-4">
                                <div className="mb-8 grid grid-cols-1 gap-4 md:grid-cols-2">
                                    {[...Array(4)].map((_, index) => (
                                        <SkeletonCard key={index} />
                                    ))}
                                </div>
                                <div className="flex items-center justify-between">
                                    <div className="h-4 w-64 animate-pulse rounded bg-gray-200"></div>
                                    <SkeletonSubmitButton />
                                </div>
                            </CardContent>
                        </Card>
                    </div>
                </SettingsLayout>
            </>
        );
    }

    return (
        <>
            <Head title="Notification Settings" />
            <SettingsLayout tab={'platform'}>
                <div className="space-y-6">
                    <Card className="px-4 py-3">
                        <div className="flex items-center justify-between border-b">
                            <HeadingSmall
                                title="Notification Settings"
                                description="Customize your notification preferences for each channel and event type"
                            />

                            <Button
                                variant="outline"
                                size="sm"
                                onClick={() =>
                                    activityLogCtl.show({
                                        modelClass: 'NotificationSettings',
                                        title: 'Notification Settings Activity',
                                        action: 'notification_settings_updated',
                                    })
                                }
                            >
                                <Activity className="mr-1 h-4 w-4" /> Activity
                            </Button>
                        </div>

                        <CardContent className="px-0 pt-4">
                            <Form submitHandler={onSubmit} defaultValues={defaultValues} formClassNames="">
                                <div className="space-y-6">
                                    {Object.entries(modules).map(([moduleName, items]) => {
                                        // Group by category within module
                                        const grouped = (items || []).reduce(
                                            (acc: Record<string, { title: string; items: Notification[] }>, n: Notification) => {
                                                const g = n.group || 'Other';
                                                if (!acc[g]) acc[g] = { title: g, items: [] };
                                                acc[g].items.push(n);
                                                return acc;
                                            },
                                            {},
                                        );
                                        // Enforce group section order at UI (config-driven names)
                                        const order: Record<string, number> = {
                                            'Authentication and Security': 0,
                                            'User And Role Management': 1,
                                        };
                                        const groups = Object.values(grouped).sort((a, b) => {
                                            const oa = order[a.title] ?? 99;
                                            const ob = order[b.title] ?? 99;
                                            if (oa === ob) return a.title.localeCompare(b.title);
                                            return oa - ob;
                                        });
                                        // map notification id to form index for fast lookup
                                        const idToIndex = new Map<number, number>();
                                        (defaultValues.notifications || []).forEach((n, i) => idToIndex.set(n.id, i));

                                        return (
                                            <Card key={moduleName} className="space-y-3 p-3">
                                                <h3 className="pb-2 text-xl font-semibold capitalize">{moduleName}</h3>
                                                {/* <p className="text-sm text-muted-foreground">{moduleName} module notifications</p> */}
                                                {groups.length > 0 && (
                                                    <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                                                        {groups.map((group) => {
                                                            const idIndices = group.items
                                                                .map((n) => idToIndex.get(n.id))
                                                                .filter((v): v is number => typeof v === 'number');
                                                            return (
                                                                <Card key={`${moduleName}-${group.title}`} className="overflow-hidden p-0">
                                                                    <div className="flex items-center justify-between border-b bg-muted px-4 py-3">
                                                                        <div className="flex items-center gap-2">
                                                                            <h2 className="text-[17px] font-semibold">{group.title}</h2>
                                                                            {/* <Badge variant="outline">{group.items.length} events</Badge> */}
                                                                        </div>
                                                                        {/* Group master toggle using form context */}
                                                                        <GroupMasterToggle indices={idIndices} />
                                                                    </div>
                                                                    <div className="my-2 grid grid-cols-1">
                                                                        {group.items.map((notification) => {
                                                                            const nIdx = defaultValues.notifications.findIndex(
                                                                                (n) => n.id === notification.id,
                                                                            );
                                                                            // Find known types by slug or name
                                                                            const findTypeIndex = (key: 'email' | 'system') =>
                                                                                notification.types.findIndex(
                                                                                    (t) =>
                                                                                        (t.slug || '').toLowerCase() === key ||
                                                                                        (t.name || '').toLowerCase() === key,
                                                                                );
                                                                            const emailIdx = findTypeIndex('email');
                                                                            const systemIdx = findTypeIndex('system');
                                                                            return (
                                                                                <Card key={notification.id} className="border-none p-0">
                                                                                    <div className="flex items-center justify-between px-4 py-3">
                                                                                        <div className="">
                                                                                            <h6 className="font-semibold">{notification.name}</h6>
                                                                                        </div>
                                                                                        <div className="flex items-center gap-6">
                                                                                            {systemIdx !== -1 && (
                                                                                                <div className="flex items-center gap-2">
                                                                                                    <FormField
                                                                                                        type="checkbox"
                                                                                                        name={`notifications.${nIdx}.types.${systemIdx}.status`}
                                                                                                    />
                                                                                                    <Label className="text-sm">System</Label>
                                                                                                </div>
                                                                                            )}
                                                                                            {emailIdx !== -1 && (
                                                                                                <div className="flex items-center gap-2">
                                                                                                    <FormField
                                                                                                        type="checkbox"
                                                                                                        name={`notifications.${nIdx}.types.${emailIdx}.status`}
                                                                                                    />
                                                                                                    <Label className="text-sm">Email</Label>
                                                                                                </div>
                                                                                            )}
                                                                                        </div>
                                                                                    </div>
                                                                                </Card>
                                                                            );
                                                                        })}
                                                                    </div>
                                                                </Card>
                                                            );
                                                        })}
                                                    </div>
                                                )}
                                            </Card>
                                        );
                                    })}
                                </div>

                                <div className="mt-3 flex items-center justify-start">
                                    <Button type="submit" className="gap-2">
                                        <Save className="h-4 w-4" />
                                        Save Changes
                                    </Button>
                                </div>
                            </Form>
                        </CardContent>
                    </Card>
                </div>
            </SettingsLayout>
            <ActivityLogSidebar
                open={activityLogCtl.open}
                onOpenChange={activityLogCtl.setOpen}
                modelClass={activityLogCtl.modelClass}
                modelId={activityLogCtl.modelId}
                title={activityLogCtl.title}
                action={activityLogCtl.action}
            />
        </>
    );
}

Edit.layout = (page: ReactNode) => (
    <AppLayout
        breadcrumbs={[
            { title: 'Home', href: '/' },
            { title: 'Settings', href: '#' },
            { title: 'Notification Settings', href: '#' },
        ]}
        title="Notification Settings"
    >
        {page}
    </AppLayout>
);

// Local helper to toggle all types for a set of notification indices
function GroupMasterToggle({ indices }: { indices: number[] }) {
    const { setValue, getValues } = useFormContext();
    const notifications: any = useWatch({ name: 'notifications' }) || [];
    const allChecked = indices.every((i) => (notifications?.[i]?.types || []).every((t: any) => Boolean(t.status)));
    return (
        <Switch
            checked={allChecked}
            onCheckedChange={(checked: boolean) => {
                const current = getValues('notifications') || [];
                const updated = current.map((n: any, idx: number) => {
                    if (!indices.includes(idx)) return n;
                    return {
                        ...n,
                        types: (n.types || []).map((t: any) => ({ ...t, status: checked })),
                    };
                });
                setValue('notifications', updated, { shouldDirty: true, shouldTouch: true });
            }}
        />
    );
}
