import "../../css/popup.scss";
import { createElement } from "../functions";
import { r } from "../utility";
import { createIcon } from "./icon";

class Popup {
    #mask;
    #option;

    constructor(opts = {}) {
        this.#option = opts;
    }

    get container() { return this.#mask.querySelector('.popup-container') }

    create() {
        const mask = createElement('div', 'popup-mask');
        const container = createElement('div', 'popup-container');
        const close = () => {
            mask.classList.add('popup-active');
            mask.style.opacity = 0;
            setTimeout(() => mask.remove(), 120);
        };
        let content = this.#option.content;
        if (!(content instanceof HTMLElement)) {
            content = createElement('div', d => d.innerText = content);
        }
        container.append(
            createElement('div', header => {
                header.className = 'popup-header';
                let title = this.#option.title;
                if (!(title instanceof HTMLElement)) {
                    title = createElement('div', t => t.innerText = title);
                }
                header.appendChild(title);
                const move = title.querySelector('.popup-move') ?? title;
                move.addEventListener('mousedown', e => {
                    const x = e.clientX - container.offsetLeft;
                    const y = e.clientY - container.offsetTop;
                    const move = e => {
                        container.style.left = `${e.clientX - x}px`;
                        container.style.top = `${e.clientY - y}px`;
                    };
                    mask.addEventListener('mousemove', move, { passive: false });
                    mask.addEventListener('mouseup', () => {
                        mask.removeEventListener('mousemove', move, { passive: false });
                    });
                });
                const cancel = createIcon('fa-regular', 'times');
                cancel.addEventListener('click', () => close());
                header.appendChild(cancel);
            }),
            createElement('div', 'popup-body', content, createElement('div', 'popup-loading',
                createElement('div', null, createIcon('fa-regular', 'spinner-third'))
            ))
        );
        if (Array.isArray(this.#option.buttons)) {
            container.appendChild(
                createElement('div', 'popup-footer', ...this.#option.buttons.map(b => {
                    const button = createElement('div', 'popup-button');
                    button.innerText = b.text;
                    button.addEventListener('click', () => {
                        if (typeof b.trigger === 'function') {
                            const result = b.trigger(this);
                            if (typeof result?.then === 'function') {
                                result.then(r => r !== false && close()).catch(() => { });
                            } else if (result !== false) {
                                close();
                            }
                        } else {
                            close();
                        }
                    });
                    return button;
                }))
            );
        }
        mask.appendChild(container);
        this.#mask = mask;
        return mask;
    }

    show(parent = document.body) {
        if (parent == null) {
            return;
        }
        let mask = this.#mask ?? this.create();
        parent.appendChild(mask);
        return new Promise(resolve => {
            setTimeout(() => {
                mask.style.opacity = 1
                resolve(mask);
            }, 0);
        });
    }

    get loading() { return this.#mask?.querySelector('.popup-body>.popup-loading')?.style?.visibility === 'visible' }
    set loading(flag) {
        let loading = this.#mask?.querySelector('.popup-body>.popup-loading');
        if (loading == null) {
            return;
        }
        if (flag === false) {
            loading.style.visibility = 'hidden';
            loading.style.opacity = 0;
        } else {
            loading.style.visibility = 'visible';
            loading.style.opacity = 1;
        }
    }
}

export default Popup;

export function createPopup(title, content, ...buttons) {
    const popup = new Popup({
        title,
        content,
        buttons
    });
    return popup;
}

const iconTypes = {
    'info': 'info-circle',
    'information': 'info-circle',
    'warn': 'exclamation-triangle',
    'warning': 'exclamation-triangle',
    'question': 'question-circle',
    'error': 'times-circle'
}

export function showAlert(title, message, iconType = 'info', parent = document.body) {
    return new Promise(resolve => {
        const popup = new Popup({
            title,
            content: createElement('div', 'message-wrapper',
                createIcon('fa-solid', iconTypes[iconType] ?? 'info-circle'),
                createElement('span', span => span.innerText = message)
            ),
            buttons: [
                { text: r('ok', 'OK'), trigger: resolve }
            ]
        });
        popup.show(parent);
    });
}

export function showConfirm(title, content, buttons, iconType = 'question', parent = document.body) {
    return new Promise(resolve => {
        const popup = new Popup({
            title,
            content: createElement('div', 'message-wrapper',
                createIcon('fa-solid', iconTypes[iconType] ?? 'question-circle'),
                createElement('span', null, content)
            ),
            buttons: buttons?.map(b => {
                return {
                    text: b.text, trigger: p => resolve({
                        key: b.key,
                        popup: p
                    })
                };
            }) ??
                [
                    { text: r('yes', 'Yes'), trigger: p => resolve({ key: 'yes', popup: p }) },
                    { text: r('no', 'No'), trigger: p => resolve({ key: 'no', popup: p }) }
                ]
        });
        popup.show(parent);
    });
}