<script setup lang="ts">
import {
    Dialog,
    DialogTrigger,
    DialogContent,
    DialogHeader,
    DialogTitle,
    DialogDescription,
    DialogFooter,
} from '@/components/ui/dialog';
import { useShareDialog } from '@/stores';
import { toTypedSchema } from '@vee-validate/yup';
import { useForm } from 'vee-validate';
import { toast } from 'vue-sonner';
import { createShare, listShares } from '~/lib/api/shares';
import { shareSchema } from '~/lib/schemas/share';
import type { Share } from '~/shared/types/shares';

const warrenStore = useWarrenStore();
const dialog = useShareDialog();

const newScreen = ref(false);

const existingShares = ref<Share[]>([]);
useAsyncData('current-file-shares', async () => {
    if (warrenStore.current == null || dialog.target == null) {
        return [];
    }

    const result = await listShares(
        warrenStore.current.warrenId,
        joinPaths(warrenStore.current.path, dialog.target.name)
    );

    if (!result.success) {
        return [];
    }

    if (result.shares.length < 1) {
        newScreen.value = true;
    } else {
        newScreen.value = false;
    }

    existingShares.value = result.shares;
});
dialog.$subscribe(async (_, value) => {
    if (value.target !== null) {
        await refreshNuxtData('current-file-shares');
    }
});

function onOpenChange() {
    dialog.reset();
}

function onCancel() {
    if (newScreen.value && existingShares.value.length > 0) {
        newScreen.value = false;
    } else {
        dialog.reset();
    }
}

const form = useForm({
    validationSchema: toTypedSchema(shareSchema),
});

const onSubmit = form.handleSubmit(async (values) => {
    if (dialog.target == null || warrenStore.current == null) {
        return;
    }

    const result = await createShare(
        warrenStore.current.warrenId,
        joinPaths(warrenStore.current.path, dialog.target.name),
        values.password ?? null,
        values.lifetime ?? null
    );

    if (result.success) {
        toast.success('Share', {
            description: `Successfully created a share for ${dialog.target.name}`,
        });
        await refreshNuxtData('current-file-shares');
        newScreen.value = false;
    } else {
        toast.error('Share', {
            description: `Failed to create share`,
        });
    }
});
</script>

<template>
    <Dialog :open="dialog.target != null" @update:open="onOpenChange">
        <DialogTrigger as-child>
            <slot />
        </DialogTrigger>
        <DialogContent
            v-if="dialog.target != null"
            class="w-full !max-w-[calc(100vw-8px)] sm:!max-w-[min(98vw,1000px)]"
        >
            <DialogHeader class="overflow-hidden">
                <DialogTitle class="truncate"
                    >Share {{ dialog.target.name }}</DialogTitle
                >
                <DialogDescription
                    >Create a shareable link to this
                    {{ dialog.target.fileType }}</DialogDescription
                >
            </DialogHeader>

            <SharesTable v-if="!newScreen" :shares="existingShares" />
            <form
                v-else
                id="share-form"
                class="grid gap-4"
                @submit.prevent="onSubmit"
            >
                <FormField v-slot="{ componentField }" name="password">
                    <FormItem>
                        <FormLabel>Password</FormLabel>
                        <FormControl>
                            <Input
                                v-bind="componentField"
                                id="password"
                                type="password"
                                autocomplete="off"
                                data-1p-ignore
                                data-protonpass-ignore
                                data-bwignore
                            />
                        </FormControl>
                        <FormMessage />
                        <FormDescription>
                            <span
                                v-if="
                                    form.values.password == null ||
                                    form.values.password.length < 1
                                "
                            >
                                The share will not require a password
                            </span>
                            <span v-else>
                                The share will require the specified password
                            </span>
                        </FormDescription>
                    </FormItem>
                </FormField>
                <FormField v-slot="{ componentField }" name="lifetime">
                    <FormItem>
                        <FormLabel>Lifetime (seconds)</FormLabel>
                        <FormControl>
                            <div
                                class="flex w-full flex-row justify-between gap-1"
                            >
                                <Input
                                    v-bind="componentField"
                                    id="lifetime"
                                    type="number"
                                    class="w-full max-w-full min-w-0"
                                    autocomplete="off"
                                    data-1p-ignore
                                    data-protonpass-ignore
                                    data-bwignore
                                />
                            </div>
                        </FormControl>
                        <FormMessage />
                        <FormDescription>
                            <span
                                v-if="
                                    form.values.lifetime != null &&
                                    form.values.lifetime > 0
                                "
                                class="w-full"
                            >
                                The share will expire in
                                {{
                                    $dayjs
                                        .duration({
                                            seconds: form.values.lifetime,
                                        })
                                        .humanize()
                                }}
                            </span>
                            <span v-else> The share will be permanent </span>
                        </FormDescription>
                    </FormItem>
                </FormField>
            </form>

            <DialogFooter>
                <Button variant="ghost" @click="onCancel">Cancel</Button>
                <Button v-if="newScreen" type="submit" form="share-form"
                    >Share</Button
                >
                <Button v-else @click="() => (newScreen = true)">New</Button>
            </DialogFooter>
        </DialogContent>
    </Dialog>
</template>
