type SwalType = typeof import('sweetalert2').default;

let swalPromise: Promise<SwalType> | null = null;

const loadSwal = (): Promise<SwalType> => {
    if (!swalPromise) {
        swalPromise = import('sweetalert2').then((module) => module.default);
    }
    return swalPromise;
};

const TOAST_STACK_ID = 'colored-toast-stack';
const TOAST_MS = 5000;

function toastStack() {
    let stack = document.getElementById(TOAST_STACK_ID);
    if (!stack) {
        stack = document.createElement('div');
        stack.id = TOAST_STACK_ID;
        stack.style.position = 'fixed';
        stack.style.top = '1rem';
        stack.style.right = '1rem';
        stack.style.zIndex = '9999';
        stack.style.display = 'flex';
        stack.style.flexDirection = 'column';
        stack.style.alignItems = 'flex-end';
        stack.style.gap = '0.5rem';
        stack.style.width = 'max-content';
        stack.style.maxWidth = 'calc(100vw - 2rem)';
        stack.style.pointerEvents = 'none';
        document.body.appendChild(stack);
    }
    return stack;
}

function pinToastBox(holder: HTMLElement) {
    const lock = (prop: string, value: string) => holder.style.setProperty(prop, value, 'important');
    lock('position', 'relative');
    lock('inset', 'auto');
    lock('display', 'block');
    lock('width', 'auto');
    lock('height', 'auto');
    lock('overflow', 'visible');
    lock('padding', '0');
    lock('margin', '0');
    lock('background', 'transparent');
    lock('pointer-events', 'auto');
}

export const coloredToast = (color: any, message: string) => {
    if (typeof document === 'undefined') return;

    const holder = document.createElement('div');
    holder.className = 'swal2-container swal2-top-end swal2-backdrop-hide';
    pinToastBox(holder);

    const popup = document.createElement('div');
    popup.className = `swal2-popup swal2-toast swal2-show color-${color}`;
    popup.setAttribute('role', 'alert');

    const close = document.createElement('button');
    close.type = 'button';
    close.className = 'swal2-close';
    close.setAttribute('aria-label', 'Tutup');
    close.textContent = '×';

    const title = document.createElement('h2');
    title.className = 'swal2-title';
    title.textContent = message;

    popup.append(close, title);
    holder.appendChild(popup);
    toastStack().appendChild(holder);

    const timer = window.setTimeout(() => holder.remove(), TOAST_MS);
    close.addEventListener('click', () => {
        window.clearTimeout(timer);
        holder.remove();
    });
};

let activeToast: any = null;

export const progressToast = (message: string, progress: number, total: number) => {
    loadSwal().then((Swal) => {
        if (!activeToast) {
            activeToast = Swal.mixin({
                toast: true,
                position: 'top-end',
                showConfirmButton: false,
                showCloseButton: true,
                didClose: () => {
                    activeToast = null;
                },
            }).fire({
                html: `<div class="swalMessage">${message} ${progress}/${total}</div>`,
                background: '#716add',
            });
        } else if (Swal.isVisible()) {
            activeToast.update({
                html: `<div class="swalMessage">${message} ${progress}/${total}</div>`,
            });
        } else {
            activeToast = Swal.mixin({
                toast: true,
                position: 'top-end',
                showConfirmButton: false,
                showCloseButton: true,
                didClose: () => {
                    activeToast = null;
                },
            }).fire({
                html: `<div class="swalMessage">${message} ${progress}/${total}</div>`,
                background: '#716add',
            });
        }
    });
};

export const confirmToast = async (message: string, confirmText: string): Promise<boolean> => {
    const Swal = await loadSwal();
    return Swal.fire({
        title: 'Are you sure?',
        text: message,
        showCancelButton: true,
        confirmButtonColor: '#d33',
        cancelButtonColor: '#ffffff',
        confirmButtonText: `Yes, ${confirmText} it!`,
    }).then((result) => {
        if (result.isConfirmed) {
            return true;
        } else {
            return false;
        }
    });
};

export const deleteToast = async (message: string): Promise<boolean> => {
    const Swal = await loadSwal();
    return Swal.fire({
        title: 'Are you sure?',
        text: message,
        showCancelButton: true,
        confirmButtonColor: '#d33',
        cancelButtonColor: '#ffffff',
        confirmButtonText: 'Yes, delete it!',
    }).then((result) => {
        if (result.isConfirmed) {
            return true;
        } else {
            return false;
        }
    });
};
