<script setup lang="ts">
// import

import type { ToastOptions } from "~/composables/global/useToast";
import { useToast } from "~/composables/global/useToast";

// type

type Props = {
    id: number;
    message: string;
    options: ToastOptions;
};

// props

const props = defineProps<Props>();
const { id, options } = toRefs(props);

// state

const { destroyToast } = useToast();

const open = ref(true);

// methods

const onSwipeEnd = () => {
    setTimeout(() => {
        destroyToast(id.value);
    }, 1000);
};

// computed

const statusIcon = computed(() => {
    const status = options.value.status;

    switch (status) {
        case "success":
            return {
                name: "duo-icons:check-circle",
                class: "**:fill-success-500 [filter:drop-shadow(0_0_10px_var(--color-success-500))]",
            };
        case "error":
            return {
                name: "duo-icons:alert-triangle",
                class: "**:fill-danger-500 [filter:drop-shadow(0_0_10px_var(--color-danger-500))]",
            };
        case "info":
            return {
                name: "duo-icons:info",
                class: "**:fill-cyan-500 [filter:drop-shadow(0_0_10px_var(--color-cyan-500))]",
            };
        case "warning":
            return {
                name: "duo-icons:alert-octagon",
                class: "**:fill-warning-500 [filter:drop-shadow(0_0_10px_var(--color-warning-500))]",
            };
        default:
            return {
                name: "duo-icons:info",
                class: "**:fill-slate-500 [filter:drop-shadow(0_0_10px_var(--color-slate-500))]",
            };
    }
});

// watch

watch(
    () => open.value,
    (value) => {
        if (!value) onSwipeEnd();
    }
);

// lifecycle

onMounted(() => {
    setTimeout(() => {
        open.value = false;
    }, options.value.duration ?? 4000);
});
</script>

<template>
    <ToastRoot
        :duration="options.duration ?? 4000"
        @swipeEnd="onSwipeEnd"
        v-model:open="open"
        class="bg-white shadow-md shadow-black/3 border-t-[0.5px] border-slate-200 border-black p-4 grid [grid-template-areas:_'title_action'_'description_action'] grid-cols-[auto_max-content] gap-x-[15px] items-center data-[state=open]:animate-toast-in data-[state=closed]:animate-toast-hide data-[swipe=move]:translate-x-[var(--reka-toast-swipe-move-x)] data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-[transform_200ms_ease-out] data-[swipe=end]:animate-toast-out"
        :class="options.description ? 'rounded-150' : 'rounded-full'"
    >
        <ToastTitle
            :class="[{ 'mb-1.5': options.description }]"
            class="[grid-area:_title] font-medium text-slate-600 text-sm flex items-center gap-2"
        >
            <Icon :name="statusIcon.name" :class="statusIcon.class" size="24" />
            <span>{{ message }}</span>
        </ToastTitle>
        <ToastDescription v-if="options.description" as-child>
            <div
                class="[grid-area:_description] m-0 mr-8 text-slate-500 typo-p-sm text-justify"
            >
                {{ options.description }}
            </div>
        </ToastDescription>
    </ToastRoot>
</template>
