#include "CustomComboBox.h"

#include <QDebug>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFrame>
#include <QApplication>
#include <QDesktopWidget>
#include <QScroller>

#include "GeneralInterface.h"

CustomComboBox::CustomComboBox(QWidget *parent)
    : QWidget(parent)
{
    // setFixedHeight(40);

    displayLabel = new QLabel(this);
    displayLabel->setText("Please Select...");
    displayLabel->setAlignment(Qt::AlignCenter);
    displayLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    arrowBtn = new QToolButton(this);
    arrowBtn->setIcon(QIcon(":/icons/spread.png"));
    arrowBtn->setIconSize(QSize(32, 32));
    arrowBtn->setAttribute(Qt::WA_TransparentForMouseEvents);

    QHBoxLayout *mainLayout = new QHBoxLayout(this);
    mainLayout->addWidget(displayLabel, 1);
    mainLayout->addWidget(arrowBtn);
    // mainLayout->setContentsMargins(10, 10, 10, 10);
    setLayout(mainLayout);

    // 下拉列表
    listWidget = new QListWidget();
    listWidget->setWindowFlags(Qt::Popup);
    listWidget->setFrameShape(QFrame::Box);
    listWidget->setFrameShadow(QFrame::Plain);
    // listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    QScroller::grabGesture(listWidget,              QScroller::TouchGesture);
    QScroller::grabGesture(listWidget->viewport(),  QScroller::LeftMouseButtonGesture);

    connect(listWidget, &QListWidget::itemClicked, this, &CustomComboBox::onItemClicked);

    qApp->installEventFilter(this);
}

void CustomComboBox::addItem(const QString &text)
{
    QListWidgetItem* item = new QListWidgetItem(text);
    item->setTextAlignment(Qt::AlignCenter);
    listWidget->addItem(item);
    setCurrentIndex();
}

void CustomComboBox::addItems(const QStringList &list)
{
    foreach (const QString& text, list) {
        addItem(text);
    }
}

void CustomComboBox::clear()
{
    listWidget->clear();
    displayLabel->setText(tr("Please Select..."));
    m_currentIndex = -1;
}

QString CustomComboBox::currentText() const
{
    return displayLabel->text();
}

void CustomComboBox::setCurrentIndex(int index)
{
    if (m_currentIndex == index) return;
    m_currentIndex = index;
    listWidget->setCurrentRow(index);
    displayLabel->setText(listWidget->currentItem()->text());
    emit currentIndexChanged(index);
    emit currentTextChanged(listWidget->currentItem()->text());
}

void CustomComboBox::setCurrentText(const QString &text)
{
    auto row = listWidget->count();
    if (text == displayLabel->text()) return;
    for (int index = 0; index < row; index ++) {
        if (text == listWidget->item(index)->text()) {
            m_currentIndex = index;
            listWidget->setCurrentRow(index);
            displayLabel->setText(listWidget->currentItem()->text());
            emit currentIndexChanged(index);
            emit currentTextChanged(text);
            return;
        }
    }
}

int CustomComboBox::currentIndex() const
{
    return m_currentIndex;
}

int CustomComboBox::findText(const QString &text)
{
    for (int row = 0; row < listWidget->count(); row ++) {
        if (text == listWidget->item(row)->text()) {
            return row;
        }
    }

    return -1;
}

int CustomComboBox::count()
{
    return listWidget->count();
}

void CustomComboBox::mousePressEvent(QMouseEvent *event)
{
    QWidget::mousePressEvent(event);

    if (isDisplay) {
        listWidget->hide();
        isDisplay = false;
        arrowBtn->setIcon(QIcon(":/icons/spread.png"));
    } else {
        QPoint pos = mapToGlobal(QPoint(0, height()));
        listWidget->move(pos);
        auto height = (listWidget->count() * 60) > GeneralInterface::getMaxHeight(this) ? GeneralInterface::getMaxHeight(this) : (listWidget->count() * 60);
        listWidget->resize(width(), height);
        listWidget->show();
        isDisplay = true;
        arrowBtn->setIcon(QIcon(":/icons/packup.png"));
    }
}

void CustomComboBox::onItemClicked(QListWidgetItem *item)
{
    if (item->text() != displayLabel->text()) {
        displayLabel->setText(item->text());
        m_currentIndex = listWidget->row(item);
        listWidget->hide();
        isDisplay = false;
        arrowBtn->setIcon(QIcon(":/icons/spread.png"));
        emit currentIndexChanged(m_currentIndex);
        emit currentTextChanged(item->text());
    }
}

bool CustomComboBox::eventFilter(QObject *obj, QEvent *event)
{
    if (isDisplay && event->type() == QEvent::MouseButtonPress) {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        QWidget *widget = QApplication::widgetAt(mouseEvent->globalPos());
        // 如果点击的不是listWidget和不是CustomComboBox本身
        if (widget != listWidget && widget != this && !listWidget->isAncestorOf(widget) && !this->isAncestorOf(widget)) {
            listWidget->hide();
            isDisplay = false;
            arrowBtn->setIcon(QIcon(":/icons/spread.png"));
            return true; // 拦截事件
        }
    }
    return QWidget::eventFilter(obj, event);
}
