<script setup lang="ts">
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';
import { useForm } from '@inertiajs/vue3';
import { Save } from '@lucide/vue';
import { computed } from 'vue';
import { toast } from 'vue-sonner';

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;
        isProtected?: boolean;
    }>(),
    {
        method: 'post',
        submitLabel: 'Simpan',
        isProtected: false,
    },
);

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

// Group permissions by group/module
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);
}

// Check/Uncheck all for a specific module group
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) {
        // Add all group permissions that are not already in form.permissions
        const toAdd = groupValues.filter((v) => !form.permissions.includes(v));
        form.permissions = [...form.permissions, ...toAdd];
    } else {
        // Remove all group permissions
        form.permissions = form.permissions.filter(
            (p) => !groupValues.includes(p),
        );
    }
}

function submit() {
    form[props.method](props.submitUrl, {
        onSuccess: () => {
            toast.success(
                `Role berhasil ${props.method === 'post' ? 'dibuat' : 'diperbarui'}.`,
            );
        },
        onError: () => {
            toast.error('Gagal menyimpan data. Periksa kembali formulir.');
        },
    });
}
</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"
                                    :disabled="isProtected"
                                />
                                <span
                                    v-if="isProtected"
                                    class="mt-1 text-xs text-muted-foreground"
                                >
                                    Nama bawaan sistem (developer/owner) tidak
                                    dapat diubah.
                                </span>
                                <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>
