<script setup lang="ts">
import {
    AccordionItem,
    AccordionTrigger,
    AccordionContent,
} from '@/components/ui/accordion';
import { useDebounceFn } from '@vueuse/core';
import { toast } from 'vue-sonner';
import { deleteUserWarren } from '~/lib/api/admin/deleteUserWarren';
import { editUserWarren } from '~/lib/api/admin/editUserWarren';
import type { UserWarren } from '~/shared/types/warrens';

const props = defineProps<{
    userWarren: UserWarren;
}>();
let realUserWarrenState: UserWarren = JSON.parse(
    JSON.stringify(props.userWarren)
);
const userWarren = props.userWarren;

const adminStore = useAdminStore();

const updatePermissionsDebounced = useDebounceFn(
    async (uw: UserWarren) => {
        const result = await editUserWarren(uw);

        if (result.success) {
            for (const [key, value] of Object.entries(result.data)) {
                if (key in userWarren) {
                    // @ts-expect-error Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
                    userWarren[key] = value;
                }
            }
            realUserWarrenState = JSON.parse(JSON.stringify(result.data));
            toast.success('Permissions', {
                description: `Successfully updated the user's permissions`,
            });
        } else {
            for (const [key, value] of Object.entries(realUserWarrenState)) {
                if (key in userWarren) {
                    // @ts-expect-error Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
                    userWarren[key] = value;
                }
            }
            userWarren.canCreateShares = realUserWarrenState.canCreateShares;

            toast.error('Permissions', {
                description: `Failed to update the user's permissions`,
            });
        }
    },
    1000,
    { maxWait: 5000 }
);

function permissionChanged(userWarren: UserWarren) {
    updatePermissionsDebounced(userWarren);
}

async function onDeleteClicked() {
    const { success } = await deleteUserWarren(
        userWarren.userId,
        userWarren.warrenId
    );
    if (!success) {
        return;
    }

    if (adminStore.editUserDialog != null) {
        // TODO: remove
        /* adminStore.editUserDialog.user.warrens =
            adminStore.editUserDialog.user.warrens.filter(
                (uw) =>
                    uw.userId !== userWarren.userId ||
                    uw.warrenId != userWarren.warrenId
            ); */
    }
}
</script>

<template>
    <AccordionItem
        :value="userWarren.warrenId"
        class="bg-accent/30 group/user-warren w-full justify-start rounded-md"
    >
        <AccordionTrigger class="items-center px-4">
            <div class="flex w-full flex-row justify-between">
                <div
                    class="flex w-full flex-col gap-0 overflow-hidden text-left leading-4"
                >
                    <span class="font-medium !no-underline">{{
                        adminStore.resources.warrens[userWarren.warrenId]?.name
                    }}</span>
                    <span class="text-muted-foreground text-xs">{{
                        adminStore.resources.warrens[userWarren.warrenId]?.path
                    }}</span>
                </div>
                <Button
                    class="transition-all not-pointer-coarse:opacity-0 not-pointer-coarse:group-hover/user-warren:opacity-100"
                    variant="destructive"
                    size="icon"
                    @click="onDeleteClicked"
                >
                    <Icon name="lucide:trash-2" />
                </Button>
            </div>
        </AccordionTrigger>
        <AccordionContent class="px-4">
            <div class="grid w-full grid-cols-1 gap-4 pt-1 sm:grid-cols-2">
                <div
                    v-for="[permissionKey] in getUserWarrenPermissions(
                        userWarren
                    )"
                    :key="permissionKey"
                    class="flex w-full flex-row items-center justify-between"
                >
                    <Label :for="permissionKey" class="grow">{{
                        getUserWarrenPermissionName(permissionKey)
                    }}</Label>
                    <Switch
                        :id="permissionKey"
                        v-model="userWarren[permissionKey]"
                        @update:model-value="
                            () => permissionChanged(userWarren)
                        "
                    />
                </div>
            </div>
        </AccordionContent>
    </AccordionItem>
</template>
