import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Field, FieldError } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import roleRoutes from '@/routes/system/role';
import type { Permission, Role } from '@/types';
import { Head, Link, useForm } from '@inertiajs/react';
import { ArrowLeft, Loader, Save } from 'lucide-react';
import React, { useMemo } from 'react';
import { toast } from 'sonner';

export default function RoleEdit({
    role,
    permissions,
}: {
    role: Role;
    permissions: Permission[];
}) {
    const { data, setData, put, processing, errors } = useForm<{
        name: string;
        guard_name: string;
        permissions: number[];
    }>({
        name: role.name,
        guard_name: role.guard_name,
        permissions: role.permissions?.map((p: Permission) => p.id) || [],
    });

    const onSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        put(roleRoutes.update(role.id).url, {
            onSuccess: (response: any) => {
                toast.success(response.props.flash.success);
            },
        });
    };

    const groupedPermissions = useMemo(() => {
        const groups: Record<string, Permission[]> = {};
        permissions.forEach((permission) => {
            const parts = permission.name.split(':');
            const groupName = parts.length > 1 ? parts[1] : 'Lainnya';
            if (!groups[groupName]) {
                groups[groupName] = [];
            }
            groups[groupName].push(permission);
        });
        return groups;
    }, [permissions]);

    const handleCheckboxChange = (id: number, checked: boolean) => {
        if (checked) {
            setData('permissions', [...data.permissions, id]);
        } else {
            setData(
                'permissions',
                data.permissions.filter((pId) => pId !== id),
            );
        }
    };

    const toggleGroup = (groupName: string) => {
        const groupPermissionIds = groupedPermissions[groupName].map(
            (p) => p.id,
        );
        const allInGroupSelected = groupPermissionIds.every((id) =>
            data.permissions.includes(id),
        );

        if (allInGroupSelected) {
            setData(
                'permissions',
                data.permissions.filter(
                    (id) => !groupPermissionIds.includes(id),
                ),
            );
        } else {
            const otherPermissions = data.permissions.filter(
                (id) => !groupPermissionIds.includes(id),
            );
            setData('permissions', [
                ...otherPermissions,
                ...groupPermissionIds,
            ]);
        }
    };

    const selectAll = () => {
        setData(
            'permissions',
            permissions.map((p) => p.id),
        );
    };

    const deselectAll = () => {
        setData('permissions', []);
    };

    return (
        <div className="flex flex-col gap-6 p-6">
            <Head title="Ubah Role" />

            <div className="flex items-center justify-between">
                <div>
                    <h1 className="text-3xl font-bold tracking-tight">
                        Ubah Role
                    </h1>
                </div>
                <Link href={roleRoutes.index().url}>
                    <Button variant="outline" className="gap-2">
                        <ArrowLeft className="size-4" />
                        Kembali
                    </Button>
                </Link>
            </div>

            <form onSubmit={onSubmit} className="space-y-6">
                <Card className="overflow-hidden border-none bg-card/50 shadow-lg backdrop-blur-sm">
                    <CardContent className="p-0">
                        <div className="border-b bg-muted/30 p-6">
                            <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
                                <Field>
                                    <Label htmlFor="name" required>
                                        Nama
                                    </Label>
                                    <Input
                                        id="name"
                                        name="name"
                                        value={data.name}
                                        onChange={(e) =>
                                            setData('name', e.target.value)
                                        }
                                        autoComplete="off"
                                    />
                                    <FieldError
                                        error={errors.name}
                                        label="Nama"
                                        className="text-xs"
                                    />
                                </Field>

                                <Field>
                                    <Label htmlFor="guard_name" required>
                                        Guard
                                    </Label>
                                    <Input
                                        id="guard_name"
                                        name="guard_name"
                                        value={data.guard_name}
                                        onChange={(e) =>
                                            setData(
                                                'guard_name',
                                                e.target.value,
                                            )
                                        }
                                        autoComplete="off"
                                    />
                                    <FieldError
                                        error={errors.guard_name}
                                        label="Guard"
                                        className="text-xs"
                                    />
                                </Field>
                            </div>
                        </div>

                        <div className="space-y-8 p-6">
                            {Object.entries(groupedPermissions).map(
                                ([groupName, groupPermissions]) => {
                                    const allInGroupSelected =
                                        groupPermissions.every((p) =>
                                            data.permissions.includes(p.id),
                                        );

                                    return (
                                        <div
                                            key={groupName}
                                            className="space-y-4"
                                        >
                                            <div className="flex items-center justify-between border-b pb-2">
                                                <h3 className="text-xs font-bold tracking-widest text-muted-foreground uppercase">
                                                    {groupName}
                                                </h3>
                                                <Button
                                                    type="button"
                                                    variant="outline"
                                                    size="sm"
                                                    className="h-8 gap-1.5"
                                                    onClick={() =>
                                                        toggleGroup(groupName)
                                                    }
                                                >
                                                    {allInGroupSelected
                                                        ? 'Lepas Semua'
                                                        : 'Pilih Semua'}
                                                </Button>
                                            </div>
                                            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
                                                {groupPermissions.map(
                                                    (permission) => (
                                                        <div
                                                            key={permission.id}
                                                            className="group flex items-center space-x-3"
                                                        >
                                                            <Checkbox
                                                                id={`permission-${permission.id}`}
                                                                checked={data.permissions.includes(
                                                                    permission.id,
                                                                )}
                                                                onCheckedChange={(
                                                                    checked,
                                                                ) =>
                                                                    handleCheckboxChange(
                                                                        permission.id,
                                                                        checked as boolean,
                                                                    )
                                                                }
                                                                className="transition-transform active:scale-90"
                                                            />
                                                            <Label
                                                                htmlFor={`permission-${permission.id}`}
                                                                className="cursor-pointer text-sm leading-none font-medium transition-colors group-hover:text-primary"
                                                            >
                                                                {
                                                                    permission.name.split(
                                                                        ':',
                                                                    )[0]
                                                                }
                                                            </Label>
                                                        </div>
                                                    ),
                                                )}
                                            </div>
                                        </div>
                                    );
                                },
                            )}
                        </div>
                    </CardContent>
                </Card>

                <div className="flex justify-end">
                    <Button type="submit" disabled={processing}>
                        {processing ? (
                            <Loader className="size-4 animate-spin" />
                        ) : (
                            <Save className="size-4" />
                        )}
                        {processing ? 'Menyimpan...' : 'Simpan'}
                    </Button>
                </div>
            </form>
        </div>
    );
}

RoleEdit.layout = {
    breadcrumbs: [{ title: 'Sistem' }],
};
