<script setup lang="ts">
import { useForm } from '@inertiajs/vue3';
import { Save } from '@lucide/vue';
import { computed } from 'vue';
import { toast } from 'vue-sonner';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    Field,
    FieldError,
    FieldGroup,
    FieldLabel,
    FieldSet,
} from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { formErrors } from '@/lib/form';

interface PermissionOption {
    value: string;
    label: string;
    group: string;
}

const props = withDefaults(
    defineProps<{
        permissions: PermissionOption[];
        initialData?: {
            name?: string;
            permission_names?: string[];
        };
        submitUrl: string;
        method?: 'post' | 'put';
        submitLabel?: string;
    }>(),
    {
        method: 'post',
        submitLabel: 'Simpan',
    },
);

const form = useForm({
    name: props.initialData?.name ?? '',
    permissions: props.initialData?.permission_names ?? [],
});

const groupedPermissions = computed(() => {
    const groups: Record<string, PermissionOption[]> = {};
    props.permissions.forEach((perm) => {
        if (!groups[perm.group]) {
            groups[perm.group] = [];
        }

        groups[perm.group].push(perm);
    });

    return groups;
});

function togglePermission(permValue: string, checked: boolean) {
    if (checked) {
        if (!form.permissions.includes(permValue)) {
            form.permissions = [...form.permissions, permValue];
        }
    } else {
        form.permissions = form.permissions.filter((p) => p !== permValue);
    }
}

function isPermissionChecked(permValue: string): boolean {
    return form.permissions.includes(permValue);
}

function isGroupAllChecked(groupName: string): boolean {
    const groupPerms = groupedPermissions.value[groupName] || [];

    if (groupPerms.length === 0) {
        return false;
    }

    return groupPerms.every((perm) => form.permissions.includes(perm.value));
}

function toggleGroupAll(groupName: string, checked: boolean) {
    const groupPerms = groupedPermissions.value[groupName] || [];
    const groupValues = groupPerms.map((p) => p.value);

    if (checked) {
        const toAdd = groupValues.filter((v) => !form.permissions.includes(v));
        form.permissions = [...form.permissions, ...toAdd];
    } else {
        form.permissions = form.permissions.filter(
            (p) => !groupValues.includes(p),
        );
    }
}

function submit() {
    form[props.method](props.submitUrl, {
        onError: (errors: any) => {
            if (errors.system) {
                toast.error(errors.system);
            }
        },
    });
}
</script>

<template>
    <form @submit.prevent="submit">
        <div class="grid gap-6">
            <Card>
                <CardHeader>
                    <CardTitle>Informasi Role</CardTitle>
                </CardHeader>
                <CardContent>
                    <FieldGroup>
                        <FieldSet class="grid gap-4">
                            <Field>
                                <FieldLabel for="name" required>Nama</FieldLabel>
                                <Input id="name" v-model="form.name" type="text" placeholder="Contoh: admin-gudang" />
                                <FieldError :errors="formErrors(form, 'name')" />
                            </Field>
                        </FieldSet>
                    </FieldGroup>
                </CardContent>
            </Card>

            <Card>
                <CardHeader>
                    <CardTitle>Hak Akses (Permissions)</CardTitle>
                </CardHeader>
                <CardContent>
                    <div class="space-y-6">
                        <div v-for="(perms, groupName) in groupedPermissions" :key="groupName"
                            class="border-b pb-6 last:border-b-0 last:pb-0">
                            <div class="mb-3 flex items-center justify-between">
                                <h3 class="text-base font-semibold text-foreground">
                                    {{ groupName }}
                                </h3>
                                <label
                                    class="flex cursor-pointer items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground">
                                    <input type="checkbox" class="size-3.5 cursor-pointer rounded border-input"
                                        :checked="isGroupAllChecked(groupName)" @change="
                                            toggleGroupAll(
                                                groupName,
                                                (
                                                    $event.target as HTMLInputElement
                                                ).checked,
                                            )
                                            " />
                                    <span>Pilih Semua</span>
                                </label>
                            </div>

                            <div class="grid gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
                                <label v-for="perm in perms" :key="perm.value"
                                    class="flex cursor-pointer items-center gap-2 rounded-md border px-3 py-2 transition-colors hover:bg-muted/50">
                                    <input type="checkbox" class="size-4 cursor-pointer rounded border-input" :checked="isPermissionChecked(perm.value)
                                        " @change="
                                            togglePermission(
                                                perm.value,
                                                (
                                                    $event.target as HTMLInputElement
                                                ).checked,
                                            )
                                            " />
                                    <span class="text-sm">{{
                                        perm.label
                                    }}</span>
                                </label>
                            </div>
                        </div>
                        <FieldError :errors="formErrors(form, 'permissions')" />
                    </div>
                </CardContent>
            </Card>

            <div class="flex items-center justify-end">
                <Button type="submit" :disabled="form.processing">
                    <Save class="size-4" />
                    {{ form.processing ? 'Menyimpan...' : submitLabel }}
                </Button>
            </div>
        </div>
    </form>
</template>
