// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "ScaleWidget.h"
#include "ddlog.h"
#include <QDebug>

#include <QHBoxLayout>
#include <QLineEdit>
#include <QKeyEvent>
#include <QEvent>
#include <DApplication>
#include <DFontSizeManager>

#define LineEditSpacing 24
#define NormalModeArrowBtnSize 32   //普通模式按钮大小
#define CompactModeArrowBtnSize 20  //紧凑模式按钮大小

ScaleWidget::ScaleWidget(DWidget *parent)
    : DWidget(parent)
{
    qCDebug(appLog) << "ScaleWidget created, parent:" << parent;
    initWidget();
}

ScaleWidget::~ScaleWidget()
{
    // qCDebug(appLog) << "ScaleWidget destroyed";
}

void ScaleWidget::initWidget()
{
    qCDebug(appLog) << "ScaleWidget::initWidget start";
    QHBoxLayout *m_layout = new QHBoxLayout();
    m_layout->setContentsMargins(0, 0, 0, 0);
    m_layout->setSpacing(10);
    setLayout(m_layout);

    m_lineEdit = new DLineEdit(this);
    m_lineEdit->setObjectName("scaleEdit_P");
    m_lineEdit->lineEdit()->setObjectName("scaleEdit");
    Dtk::Widget::DFontSizeManager::instance()->bind(m_lineEdit->lineEdit(), Dtk::Widget::DFontSizeManager::T6, true);

    connect(dynamic_cast<QGuiApplication *>(DApplication::instance()), &DApplication::fontChanged,
            this, &ScaleWidget::onEditFinished);

    m_lineEdit->setFixedSize(120, 36);

    m_arrowBtn = new DIconButton(QStyle::SP_ArrowDown, m_lineEdit);
    m_arrowBtn->setObjectName("editArrowBtn");
    //添加显示比例值默认值
    m_arrowBtn->setFixedSize(NormalModeArrowBtnSize, NormalModeArrowBtnSize);
    m_arrowBtn->move(m_lineEdit->width() - m_arrowBtn->width() - 2, m_lineEdit->height() / 2 - m_arrowBtn->height() / 2);
#ifdef DTKWIDGET_CLASS_DSizeMode
    qCInfo(appLog) << "Compact mode support!!!";
    onSizeModeChanged(DGuiApplicationHelper::instance()->sizeMode());
    connect(DGuiApplicationHelper::instance(), SIGNAL(sizeModeChanged(DGuiApplicationHelper::SizeMode)), this, SLOT(onSizeModeChanged(DGuiApplicationHelper::SizeMode)));
#else
    qCInfo(appLog) << "Compact mode is not supported!!!";
#endif
    m_lineEdit->lineEdit()->setTextMargins(0, 0, m_arrowBtn->width(), 0);
    m_lineEdit->setClearButtonEnabled(false);

    connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(onReturnPressed()));
    connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(onEditFinished()));
    connect(m_arrowBtn, SIGNAL(clicked()), SLOT(onArrowBtnlicked()));
    m_lineEdit->lineEdit()->installEventFilter(this);

    DIconButton *pPreBtn = new DIconButton(DStyle::SP_DecreaseElement, this);
    pPreBtn->setObjectName("SP_DecreaseElement");
    DStyle::setFrameRadius(pPreBtn, 12);
    pPreBtn->setFixedSize(24, 24);
    connect(pPreBtn, SIGNAL(clicked()), SLOT(onPrevScale()));

    DIconButton *pNextBtn = new DIconButton(this/*DStyle::SP_IncreaseElement*/);
    pNextBtn->setIcon(QIcon::fromTheme("dr_button_add"));
    pNextBtn->setObjectName("SP_IncreaseElement");
    DStyle::setFrameRadius(pNextBtn, 12);
    pNextBtn->setFixedSize(24, 24);
    connect(pNextBtn, SIGNAL(clicked()), SLOT(onNextScale()));

    m_layout->addWidget(pPreBtn);
    m_layout->addWidget(m_lineEdit);
    m_layout->addWidget(pNextBtn);
    qCDebug(appLog) << "ScaleWidget::initWidget end";
}

bool ScaleWidget::eventFilter(QObject *obj, QEvent *event)
{
    // 缩放框获得焦点时，Up/Down 调整缩放比，且不能让事件穿透到 Central 的窗口级
    // 快捷键(文档滚动)。必须同时处理 ShortcutOverride(抑制快捷键)和 KeyPress(执行缩放)。
    if (m_lineEdit && obj == m_lineEdit->lineEdit()
            && (event->type() == QEvent::ShortcutOverride || event->type() == QEvent::KeyPress)) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        if (keyEvent->key() == Qt::Key_Up) {
            if (event->type() == QEvent::KeyPress)
                onNextScale();   // Up = 放大
            event->accept();
            return true;
        } else if (keyEvent->key() == Qt::Key_Down) {
            if (event->type() == QEvent::KeyPress)
                onPrevScale();  // Down = 缩小
            event->accept();
            return true;
        }
    }
    return DWidget::eventFilter(obj, event);
}

void ScaleWidget::onPrevScale()
{
    qCDebug(appLog) << "Zoom out requested";
    if (m_sheet.isNull())
        return;

    m_sheet->zoomout();
}

void ScaleWidget::onNextScale()
{
    qCDebug(appLog) << "Zoom in requested";
    if (m_sheet.isNull())
        return;

    m_sheet->zoomin();
}

void ScaleWidget::onReturnPressed()
{
    qCDebug(appLog) << "Scale value entered:" << m_lineEdit->text();
    if (m_sheet.isNull())
        return;

    qreal value = m_lineEdit->text().replace("%", "").toDouble() / 100.00;
    value = qBound(0.1, value, m_sheet->maxScaleFactor());
    m_sheet->setScaleFactor(value);
}

void ScaleWidget::onArrowBtnlicked()
{
    qCDebug(appLog) << "Scale menu button clicked";
    m_lineEdit->lineEdit()->setFocus(Qt::MouseFocusReason);

    ScaleMenu scaleMenu;
    QPoint point = m_lineEdit->mapToGlobal(QPoint(0, m_lineEdit->height() + 2));
    scaleMenu.readCurDocParam(m_sheet.data());
    scaleMenu.exec(point);
}

#ifdef DTKWIDGET_CLASS_DSizeMode
void ScaleWidget::onSizeModeChanged(DGuiApplicationHelper::SizeMode sizeMode)
{
    qCDebug(appLog) << "ScaleWidget::onSizeModeChanged start - sizeMode:" << sizeMode;
    if (sizeMode == DGuiApplicationHelper::SizeMode::CompactMode) {
        qCInfo(appLog) << "Size Mode Changed! Current SizeMode is CompactMode";
        m_arrowBtn->setFixedSize(CompactModeArrowBtnSize, CompactModeArrowBtnSize);
    } else {
        qCInfo(appLog) << "Size Mode Changed! Current SizeMode is " << sizeMode;
        m_arrowBtn->setFixedSize(NormalModeArrowBtnSize, NormalModeArrowBtnSize);
    }
    m_arrowBtn->move(m_lineEdit->width() - m_arrowBtn->width() - 2, m_lineEdit->height() / 2 - m_arrowBtn->height() / 2);
    qCDebug(appLog) << "ScaleWidget::onSizeModeChanged end";
}
#endif

void ScaleWidget::onEditFinished()
{
    qCDebug(appLog) << "Scale edit finished, current scale:" << m_sheet->operation().scaleFactor;
    if (nullptr == m_sheet)
        return;

    QString text = QString::number(QString::number(m_sheet->operation().scaleFactor * 100, 'f', 2).toDouble()) + "%";
    m_lineEdit->setText(m_lineEdit->fontMetrics().elidedText(text, Qt::ElideRight, m_lineEdit->width() - m_arrowBtn->width() - 2 - LineEditSpacing));
}

void ScaleWidget::setSheet(DocSheet *sheet)
{
    qCDebug(appLog) << "Setting document sheet:" << (sheet ? "valid" : "null");
    m_sheet = sheet;
    if (nullptr == sheet)
        return;
    else if (!sheet->opened()) {
        clear();
        return;
    }

    m_lineEdit->clear();
    QString text = QString::number(QString::number(m_sheet->operation().scaleFactor * 100, 'f', 2).toDouble()) + "%";
    m_lineEdit->setText(m_lineEdit->fontMetrics().elidedText(text, Qt::ElideRight, m_lineEdit->width() - m_arrowBtn->width() - 2 - LineEditSpacing));
    m_lineEdit->lineEdit()->setCursorPosition(0);
    qCDebug(appLog) << "ScaleWidget::setSheet end";
}

void ScaleWidget::clear()
{
    // qCDebug(appLog) << "Clearing scale widget";
    m_lineEdit->clear();
}
