import { Head, router } from '@inertiajs/react';
import { Save } from 'lucide-react';
import { useState } from 'react';
import { PageHeader } from '@/components/page-header';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { update } from '@/routes/admin/developer/roles';
import type {
    PermissionGroups,
    RoleWithPermissions,
} from '@/types/role-permission';
import { formatRoleLabel } from '@/types/role-permission';

type Props = {
    roles: RoleWithPermissions[];
    permissionGroups: PermissionGroups;
};

export default function RolePermissionIndex({
    roles,
    permissionGroups,
}: Props) {
    const [selectedRoleId, setSelectedRoleId] = useState<number | undefined>(
        roles[0]?.id,
    );
    const selectedRole = roles.find((role) => role.id === selectedRoleId);
    const [selected, setSelected] = useState<string[]>(
        selectedRole?.permissions ?? [],
    );
    const [processing, setProcessing] = useState(false);

    function handleSelectRole(id: string) {
        const role = roles.find((r) => r.id === Number(id));
        setSelectedRoleId(role?.id);
        setSelected(role?.permissions ?? []);
    }

    function toggle(name: string, checked: boolean) {
        setSelected((prev) =>
            checked ? [...prev, name] : prev.filter((p) => p !== name),
        );
    }

    function toggleGroup(names: string[], checked: boolean) {
        setSelected((prev) => {
            const withoutGroup = prev.filter((p) => !names.includes(p));

            return checked ? [...withoutGroup, ...names] : withoutGroup;
        });
    }

    function handleSave() {
        if (!selectedRole) {
            return;
        }

        setProcessing(true);
        router.put(
            update.url(selectedRole.id),
            { permissions: selected },
            {
                preserveScroll: true,
                onFinish: () => setProcessing(false),
            },
        );
    }

    return (
        <>
            <Head title="Role & Permission" />

            <div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto p-4 md:p-6">
                <PageHeader
                    title="Role & Permission"
                    actions={
                        selectedRole && (
                            <Button onClick={handleSave} disabled={processing}>
                                <Save className="h-4 w-4" />
                                Simpan
                            </Button>
                        )
                    }
                />

                <div className="flex items-center gap-3">
                    <Select
                        value={
                            selectedRoleId ? String(selectedRoleId) : undefined
                        }
                        onValueChange={handleSelectRole}
                    >
                        <SelectTrigger className="w-full sm:w-72">
                            <SelectValue placeholder="Pilih role" />
                        </SelectTrigger>
                        <SelectContent>
                            {roles.map((role) => (
                                <SelectItem
                                    key={role.id}
                                    value={String(role.id)}
                                >
                                    {formatRoleLabel(role.name)}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                    {selectedRole && (
                        <Badge variant="secondary">
                            {selected.length} permission
                        </Badge>
                    )}
                </div>

                {selectedRole && (
                    <div className="grid gap-4">
                        {Object.entries(permissionGroups).map(
                            ([group, names]) => {
                                const allChecked = names.every((name) =>
                                    selected.includes(name),
                                );

                                return (
                                    <Card key={group}>
                                        <CardHeader className="flex flex-row items-center justify-between gap-4">
                                            <CardTitle className="text-base">
                                                {group}
                                            </CardTitle>
                                            <label className="flex items-center gap-2 text-sm font-normal text-muted-foreground">
                                                <Checkbox
                                                    checked={allChecked}
                                                    onCheckedChange={(
                                                        checked,
                                                    ) =>
                                                        toggleGroup(
                                                            names,
                                                            checked === true,
                                                        )
                                                    }
                                                />
                                                Pilih Semua
                                            </label>
                                        </CardHeader>
                                        <CardContent className="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3">
                                            {names.map((name) => (
                                                <label
                                                    key={name}
                                                    className="flex items-center gap-2 rounded-md border p-2 text-sm hover:bg-muted"
                                                >
                                                    <Checkbox
                                                        checked={selected.includes(
                                                            name,
                                                        )}
                                                        onCheckedChange={(
                                                            checked,
                                                        ) =>
                                                            toggle(
                                                                name,
                                                                checked ===
                                                                    true,
                                                            )
                                                        }
                                                    />
                                                    <span className="font-mono text-xs">
                                                        {name}
                                                    </span>
                                                </label>
                                            ))}
                                        </CardContent>
                                    </Card>
                                );
                            },
                        )}
                    </div>
                )}
            </div>
        </>
    );
}
