import { Form, FormField } from '@admin/components/form';
import HeadingSmall from '@admin/components/heading-small';
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 AdminLayout from '@admin/layouts/admin/admin-layout';
import AdminSettingsLayout from '@admin/layouts/admin/admin-settings-layout';
import { Head, router } from '@inertiajs/react';
import { Save } from 'lucide-react';
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;
};

export default function NotificationSettings() {
    const notificationsByModule: Record<string, Notification[]> = {
        Platform: [
            {
                id: 1,
                name: 'User Registration',
                slug: 'user_registration',
                status: 1,
                group: 'Authentication and Security',
                types: [
                    { id: 1, name: 'Email', slug: 'email', notification_id: 1, status: 1 },
                    { id: 2, name: 'System', slug: 'system', notification_id: 1, status: 1 },
                ],
            },
            {
                id: 2,
                name: 'Password Reset',
                slug: 'password_reset',
                status: 1,
                group: 'Authentication and Security',
                types: [
                    { id: 3, name: 'Email', slug: 'email', notification_id: 2, status: 1 },
                    { id: 4, name: 'System', slug: 'system', notification_id: 2, status: 1 },
                ],
            },
        ],
    };

    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;
        },
        {},
    );

    const initialNotifications: Notification[] = Object.values(modules).flat();
    const defaultValues = { notifications: initialNotifications };

    const onSubmit = async (data: any) => {
        const notifications: Notification[] = (data.notifications || []).map((n: any) => ({
            ...n,
            types: (n.types || []).map((t: any) => ({ ...t, status: t.status ? 1 : 0 })),
        }));
        router.patch('/admin/settings/notifications', { notifications }, { preserveScroll: true });
    };

    return (
        <>
            <Head title="Notification Settings - Admin" />
            <AdminSettingsLayout activeTab="notifications">
                <div className="space-y-6">
                    <Card className="px-4 py-4">
                        <div className="border-b pb-3">
                            <HeadingSmall
                                title="Notification Settings"
                                description="Customize notification preferences for each channel and event type"
                            />
                        </div>

                        <CardContent className="px-0 pt-4">
                            <Form submitHandler={onSubmit} defaultValues={defaultValues} formClassNames="">
                                <div className="space-y-6">
                                    {Object.entries(modules).map(([moduleName, items]) => {
                                        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;
                                            },
                                            {},
                                        );

                                        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;
                                        });

                                        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>
                                                {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>
                                                                        </div>
                                                                        <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,
                                                                            );
                                                                            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>
                                                                                            <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>
            </AdminSettingsLayout>
        </>
    );
}

NotificationSettings.layout = (page: ReactNode) => (
    <AdminLayout breadcrumbs={[{ title: 'Settings', href: '/admin/settings/general' }, { title: 'Notification Settings', href: '#' }]}>
        {page}
    </AdminLayout>
);

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 });
            }}
        />
    );
}
