import './css/tooltip.scss';
import { createElement } from "../functions";
import { global } from '../utility';

const pointerHeight = 12;

export function setTooltip(container, content, flag = false, parent = null, maxLeft = null) {
    const isParent = parent instanceof HTMLElement;
    if (isParent) {
        const tipid = container.dataset.tipId;
        const tip = parent.querySelector(`.ui-tooltip-wrapper[data-tip-id="${tipid}"]`);
        tip?.remove();
    } else {
        const tip = container.querySelector('.ui-tooltip-wrapper');
        tip?.remove();
    }
    const wrapper = createElement('div', wrapper => {
        wrapper.className = 'ui-tooltip-wrapper ui-tooltip-color';
        // wrapper.style.visibility = 'hidden';
        // wrapper.style.opacity = 0;
        // wrapper.style.top = '0';
        // wrapper.style.left = '0';
        wrapper.style.cssText += 'display: none; visibility: hidden; opacity: 0; top: 0; left: 0';
    },
        createElement('div', 'ui-tooltip-pointer ui-tooltip-color'),
        createElement('div', 'ui-tooltip-curtain ui-tooltip-color'),
        createElement('div', cnt => {
            cnt.className = 'ui-tooltip-content';
            if (content instanceof Element) {
                cnt.appendChild(content);
            } else {
                cnt.innerText = content;
            }
        })
    );
    // container.insertAdjacentElement('afterend', wrapper);
    if (isParent) {
        const tipId = String(Math.random()).substring(2);
        container.dataset.tipId = tipId;
        wrapper.dataset.tipId = tipId;
        parent.appendChild(wrapper);
    } else {
        container.appendChild(wrapper);
    }

    let tid;
    container.addEventListener('mouseenter', () => {
        tid && clearTimeout(tid);
        let c = container;
        while (c?.offsetWidth == null) {
            c = c.parentElement;
        }
        if (c == null) {
            return;
        }
        if (!flag || c.scrollWidth > c.offsetWidth) {
            wrapper.style.cssText += 'left: -9999px; top: -9999px; display: block';
            tid = setTimeout(() => {
                let p;
                let left;
                let top;
                left = c.offsetLeft;
                top = c.offsetTop;
                if (isParent) {
                    p = c.offsetParent;
                    while (p != null && p !== parent) {
                        left += p.offsetLeft;
                        top += p.offsetTop;
                        p = p.offsetParent;
                    }
                }
                p = c.parentElement;
                const offsetParent = isParent ? parent : c.offsetParent;
                while (p != null && p !== offsetParent) {
                    left -= p.scrollLeft;
                    top -= p.scrollTop;
                    p = p.parentElement;
                }
                const offsetHeight = wrapper.offsetHeight;
                const offsetWidth = wrapper.offsetWidth;
                if (isParent) {
                    top -= offsetHeight + pointerHeight;
                    if (top < 0) {
                        top += c.offsetHeight + offsetHeight + pointerHeight * 2;
                        wrapper.classList.add('ui-tooltip-down');
                    }
                    left += (c.offsetWidth - offsetWidth) / 2;
                    if (left < 1) {
                        left = 1;
                    }
                } else {
                    // check overflow
                    let t = c.offsetTop;
                    let l = c.offsetLeft;
                    p = c.offsetParent;
                    if (p == null) {
                        return;
                    }
                    let lastWidth = p.clientWidth;
                    let lastHeight = p.clientHeight;
                    while (p != null) {
                        const overflow = global.getComputedStyle(p).overflow;
                        if (overflow !== 'visible') {
                            break;
                        }
                        t += p.offsetTop;
                        l += p.offsetLeft;
                        const parent = p.offsetParent;
                        while (p != null) {
                            const w = p.clientWidth;
                            if (w < lastWidth) {
                                lastWidth += l;
                            } else {
                                lastWidth = p.clientWidth;
                            }
                            const h = p.clientHeight;
                            if (h < lastHeight) {
                                lastHeight += t;
                            } else {
                                lastHeight = p.clientHeight;
                            }
                            t -= p.scrollTop;
                            l -= p.scrollLeft;
                            if (p === parent) {
                                break;
                            }
                            p = p.parentElement;
                        }
                    }
                    if (t - offsetHeight - pointerHeight < 0) {
                        const containerOffsetHeight = c.offsetHeight;
                        if (t + containerOffsetHeight + offsetHeight + pointerHeight > lastHeight) {
                            top = t + (containerOffsetHeight - offsetHeight) / 2;
                            if (top + offsetHeight + 1 > lastHeight) {
                                top = lastHeight - offsetHeight - 1;
                            }
                            wrapper.classList.add('ui-tooltip-no');
                        } else {
                            top += containerOffsetHeight + pointerHeight;
                            wrapper.classList.add('ui-tooltip-down');
                        }
                    } else {
                        top -= offsetHeight + pointerHeight;
                        wrapper.classList.remove('ui-tooltip-down');
                    }
                    left += (c.offsetWidth - offsetWidth) / 2;
                    if (l - offsetWidth < 0) {
                        left = 1;
                    } else if (left + offsetWidth + 1 > lastWidth) {
                        left = lastWidth - offsetWidth - 1;
                    }
                }
                if (typeof maxLeft === 'function') {
                    const max = maxLeft(offsetWidth);
                    if (left > max) {
                        wrapper.style.setProperty('--pointer-left', 'calc(100% - 20px)');
                        left = max;
                    } else {
                        wrapper.style.setProperty('--pointer-left', null);
                    }
                }
                // wrapper.style.left = `${left}px`;
                // wrapper.style.top = `${top}px`;
                // wrapper.style.visibility = 'visible';
                // wrapper.style.opacity = 1;
                wrapper.style.cssText += `left: ${left}px; top: ${top}px; visibility: visible; opacity: 1`;
            }, 100);
        }
    });
    container.addEventListener('mouseleave', () => {
        tid && clearTimeout(tid);
        tid = setTimeout(() => {
            wrapper.style.visibility = 'hidden';
            wrapper.style.opacity = 0;
            tid = setTimeout(() => wrapper.style.display = 'none', 120);
        }, 300);
    });
    return container;
}

export function resolveTooltip(container = document.body) {
    const tips = container.querySelectorAll('[title]');
    for (let tip of tips) {
        const title = tip.getAttribute('title');
        if (title != null) {
            tip.removeAttribute('title');
            setTooltip(tip, title);
        }
    }
    return container;
}