<script setup lang="ts">
import {
    Combobox,
    ComboboxAnchor,
    ComboboxEmpty,
    ComboboxGroup,
    ComboboxInput,
    ComboboxItem,
    ComboboxItemIndicator,
    ComboboxList,
} from '@/components/ui/combobox';
import {
    AlertDialog,
    AlertDialogTrigger,
    AlertDialogHeader,
    AlertDialogTitle,
    AlertDialogDescription,
    AlertDialogContent,
    AlertDialogFooter,
    AlertDialogCancel,
} from '@/components/ui/alert-dialog';
import { toTypedSchema } from '@vee-validate/yup';
import { useForm } from 'vee-validate';
import { userWarrenSchema } from '~/lib/schemas/admin';
import type { AuthUserWithWarrens } from '~/shared/types/admin';
import { createUserWarren } from '~/lib/api/admin/createUserWarren';

const adminStore = useAdminStore();

const { user } = defineProps<{
    user: AuthUserWithWarrens;
}>();

const availableWarrens = computed<typeof adminStore.resources.warrens>(() =>
    Object.entries(adminStore.resources.warrens)
        .filter(
            ([_, warren]) =>
                user.warrens.findIndex((uw) => uw.warrenId === warren.id) === -1
        )
        .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
);

const creating = ref(false);
const open = ref(false);

const form = useForm({
    validationSchema: toTypedSchema(userWarrenSchema),
    initialValues: {
        userId: user.id,
        canListFiles: false,
        canReadFiles: false,
        canModifyFiles: false,
        canDeleteFiles: false,

        canListShares: false,
        canCreateShares: false,
        canModifyShares: false,
        canDeleteShares: false,
    },
});

const onSubmit = form.handleSubmit(async (values) => {
    if (creating.value) {
        return;
    }

    creating.value = true;

    const result = await createUserWarren(values);

    if (result.success) {
        form.resetForm();
        open.value = false;
    }

    creating.value = false;
});
</script>

<template>
    <AlertDialog v-model:open="open">
        <AlertDialogTrigger as-child>
            <slot />
        </AlertDialogTrigger>
        <AlertDialogContent>
            <AlertDialogHeader>
                <AlertDialogTitle>Add user warren</AlertDialogTitle>
                <AlertDialogDescription
                    >Assign {{ user.name }} current user to an existing
                    warren</AlertDialogDescription
                >
            </AlertDialogHeader>

            <div class="flex flex-col">
                <Combobox>
                    <ComboboxAnchor as-child>
                        <ComboboxTrigger as-child>
                            <Button variant="outline" class="justify-between">
                                {{
                                    (form.values.warrenId
                                        ? adminStore.resources.warrens[
                                              form.values.warrenId
                                          ].name
                                        : undefined) ?? 'Select warren'
                                }}

                                <Icon
                                    name="lucide:chevrons-up-down"
                                    class="ml-2 h-4 w-4 shrink-0 opacity-50"
                                />
                            </Button>
                        </ComboboxTrigger>
                    </ComboboxAnchor>

                    <ComboboxList>
                        <div class="relative w-full max-w-sm items-center">
                            <ComboboxInput
                                class="h-10 rounded-none border-0 focus-visible:ring-0"
                                placeholder="Select warren..."
                                :display-value="(warren) => warren?.name"
                            />
                            <span
                                class="absolute inset-y-0 start-0 flex items-center justify-center px-3"
                            >
                                <Icon
                                    name="lucide:search"
                                    class="text-muted-foreground size-4"
                                />
                            </span>
                        </div>

                        <ComboboxEmpty>No warrens found</ComboboxEmpty>

                        <ComboboxGroup>
                            <ComboboxItem
                                v-for="warren in availableWarrens"
                                :key="warren.id"
                                :value="warren"
                                @select="
                                    () => {
                                        form.setFieldValue(
                                            'warrenId',
                                            warren.id
                                        );
                                    }
                                "
                            >
                                {{ warren.name }}

                                <ComboboxItemIndicator>
                                    <Icon
                                        name="lucide:check"
                                        class="ml-auto h-4 w-4"
                                    />
                                </ComboboxItemIndicator>
                            </ComboboxItem>
                        </ComboboxGroup>
                    </ComboboxList>
                </Combobox>

                <span
                    v-if="form.errors.value.warrenId"
                    class="text-destructive-foreground text-sm"
                    >{{ form.errors.value.warrenId }}</span
                >
            </div>

            <form
                id="add-user-warren-form"
                class="flex w-full flex-col gap-4"
                @submit.prevent="onSubmit"
            >
                <FormField type="hidden" name="userId" :value="user.id" />

                <div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
                    <FormField
                        v-slot="{ value, handleChange }"
                        name="canListFiles"
                    >
                        <FormItem class="flex flex-row justify-between">
                            <FormLabel class="grow">List files</FormLabel>
                            <FormControl>
                                <Switch
                                    :model-value="value"
                                    @update:model-value="handleChange"
                                />
                            </FormControl>
                            <FormMessage />
                        </FormItem>
                    </FormField>

                    <FormField
                        v-slot="{ value, handleChange }"
                        name="canReadFiles"
                    >
                        <FormItem class="flex flex-row justify-between">
                            <FormLabel class="grow">Read files</FormLabel>
                            <FormControl>
                                <Switch
                                    :model-value="value"
                                    @update:model-value="handleChange"
                                />
                            </FormControl>
                            <FormMessage />
                        </FormItem>
                    </FormField>

                    <FormField
                        v-slot="{ value, handleChange }"
                        name="canModifyFiles"
                    >
                        <FormItem class="flex flex-row justify-between">
                            <FormLabel class="grow">Modify files</FormLabel>
                            <FormControl>
                                <Switch
                                    :model-value="value"
                                    @update:model-value="handleChange"
                                />
                            </FormControl>
                            <FormMessage />
                        </FormItem>
                    </FormField>

                    <FormField
                        v-slot="{ value, handleChange }"
                        name="canDeleteFiles"
                    >
                        <FormItem class="flex flex-row justify-between">
                            <FormLabel class="grow">Delete files</FormLabel>
                            <FormControl>
                                <Switch
                                    :model-value="value"
                                    @update:model-value="handleChange"
                                />
                            </FormControl>
                            <FormMessage />
                        </FormItem>
                    </FormField>

                    <FormField
                        v-slot="{ value, handleChange }"
                        name="canListShares"
                    >
                        <FormItem class="flex flex-row justify-between">
                            <FormLabel class="grow">List shares</FormLabel>
                            <FormControl>
                                <Switch
                                    :model-value="value"
                                    @update:model-value="handleChange"
                                />
                            </FormControl>
                            <FormMessage />
                        </FormItem>
                    </FormField>

                    <FormField
                        v-slot="{ value, handleChange }"
                        name="canCreateShares"
                    >
                        <FormItem class="flex flex-row justify-between">
                            <FormLabel class="grow">Create shares</FormLabel>
                            <FormControl>
                                <Switch
                                    :model-value="value"
                                    @update:model-value="handleChange"
                                />
                            </FormControl>
                            <FormMessage />
                        </FormItem>
                    </FormField>

                    <FormField
                        v-slot="{ value, handleChange }"
                        name="canModifyShares"
                    >
                        <FormItem class="flex flex-row justify-between">
                            <FormLabel class="grow">Modify shares</FormLabel>
                            <FormControl>
                                <Switch
                                    :model-value="value"
                                    @update:model-value="handleChange"
                                />
                            </FormControl>
                            <FormMessage />
                        </FormItem>
                    </FormField>

                    <FormField
                        v-slot="{ value, handleChange }"
                        name="canDeleteShares"
                    >
                        <FormItem class="flex flex-row justify-between">
                            <FormLabel class="grow">Delete shares</FormLabel>
                            <FormControl>
                                <Switch
                                    :model-value="value"
                                    @update:model-value="handleChange"
                                />
                            </FormControl>
                            <FormMessage />
                        </FormItem>
                    </FormField>
                </div>
            </form>

            <AlertDialogFooter class="space-y-0">
                <AlertDialogCancel>Cancel</AlertDialogCancel>
                <Button
                    type="submit"
                    form="add-user-warren-form"
                    :disabled="creating"
                    >Add</Button
                >
            </AlertDialogFooter>
        </AlertDialogContent>
    </AlertDialog>
</template>
