// SPDX-FileCopyrightText: 2011 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "popupwindow.h"

#include <QAccessible>
#include <QAccessibleEvent>

PopupWindow::PopupWindow(QWidget *parent)
    : DArrowRectangle(ArrowBottom, FloatWidget, parent)
{
    setMargin(0);

    setBackgroundColor(QColor(235, 235, 235, 80));
    setBorderColor(QColor(235, 235, 235, 80));

    setWindowFlags(Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint);
    setShadowBlurRadius(20);
    setRadius(6);
    setShadowYOffset(2);
    setShadowXOffset(0);
    setArrowWidth(18);
    setArrowHeight(10);
}

PopupWindow::~PopupWindow()
{
}

void PopupWindow::setContent(QWidget *content)
{
    QWidget *lastWidget = getContent();
    if (lastWidget)
        lastWidget->removeEventFilter(this);

    if (content) {
        content->installEventFilter(this);
    }

    QAccessibleEvent event(this, QAccessible::NameChanged);
    QAccessible::updateAccessibility(&event);

    if (content && !content->objectName().trimmed().isEmpty())
        setAccessibleName(content->objectName() + "-popup");

    DArrowRectangle::setContent(content);
}

void PopupWindow::toggle(const QPoint &pos)
{
    isVisible() ? hide() : show(pos);
}

void PopupWindow::show(const QPoint &pos)
{
    m_lastPoint = pos;
    if (getContent())
        getContent()->setVisible(true);
    DArrowRectangle::show(pos.x(), pos.y());
}

void PopupWindow::toggle()
{
    isVisible() ? hide() : show(m_lastPoint);
}

void PopupWindow::hide()
{
    if (getContent())
        getContent()->setVisible(false);
    Q_EMIT visibleChanged(false);
    DArrowRectangle::hide();
}

void PopupWindow::showEvent(QShowEvent *e)
{
    Q_EMIT visibleChanged(true);
    DArrowRectangle::showEvent(e);

    QMetaObject::invokeMethod(this, &PopupWindow::ensureRaised);
}

void PopupWindow::enterEvent(QEnterEvent *e)
{
    DArrowRectangle::enterEvent(e);

    QMetaObject::invokeMethod(this, &PopupWindow::ensureRaised);
}

bool PopupWindow::eventFilter(QObject *o, QEvent *e)
{
    if (o != getContent())
        return false;

    switch (e->type()) {
    case QEvent::Resize: {
        // FIXME: ensure position move after global mouse release event
        // 目的是为了在content resize之后重新设置弹窗的位置和大小
        if (isVisible()) {
            QMetaObject::invokeMethod(this, [ this ] {
                if (isVisible())
                    show(m_lastPoint);
            }, Qt::QueuedConnection);
        }
    }
        break;
    case QEvent::ParentChange: {
        emit contentDetach();
    }
        break;
    default:
        break;
    }

    return false;
}

void PopupWindow::ensureRaised()
{
    if (!isVisible())
        return;

    QWidget *content = getContent();
    if (!content || !content->isVisible()) {
        setVisible(false);
    } else {
        raise();
    }
}
