/*
 * Copyright (C) 2023, KylinSoft Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
**/
#include "timezonechooser.h"

#include <QDesktopWidget>
#include <QApplication>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QTimer>
#include <QTimeZone>
#include <QCompleter>
#include <QDebug>
#include <QHBoxLayout>
#include <QPainter>
#include <QPainterPath>
#include <QGraphicsDropShadowEffect>
#include <QtCore/qmath.h>
#include <QDialog>
#include <QGSettings>
#include "imageutil.h"

const QString kcnBj = "北京";
const QString kenBj = "Asia/Beijing";

extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);


TimeZoneChooser::TimeZoneChooser(QWidget *parent) : QDialog(parent)
{
    this->setFocusPolicy(Qt::StrongFocus);
    m_map = new TimezoneMap(this);
//    m_map->show();
    m_zoneinfo = new ZoneInfo;
    m_searchInput = new KSearchLineEdit(this);
    m_searchInput->setPlaceholderText(tr("Search Timezone"));
    m_cancelBtn = new QPushButton(tr("Cancel"));
    m_confirmBtn = new QPushButton(tr("Confirm"));

    this->setObjectName("MapFrame");
    this->setWindowTitle(tr("Change Timezone"));
    this->installEventFilter(this);

    m_searchInput->setFixedSize(240,36);
    m_searchInput->setFocusPolicy(Qt::ClickFocus);
    m_searchInput->setTextMargins(30, 1, 0, 1);
    m_searchInput->installEventFilter(this);
    m_searchInput->setFocusPolicy(Qt::ClickFocus);
    m_searchInput->setContextMenuPolicy(Qt::NoContextMenu);

    initSize();

    QHBoxLayout *btnlayout = new QHBoxLayout;
    btnlayout->addStretch();
    btnlayout->addWidget(m_cancelBtn);
    btnlayout->addSpacing(5);
    btnlayout->addWidget(m_confirmBtn);
    btnlayout->addSpacing(36);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setContentsMargins(0,0,0,0);
    layout->setAlignment(Qt::AlignTop);

    QLabel *mTipLabel = new QLabel(this);
    mTipLabel->setText(tr("To select a time zone, please click where near you on the map and select a city from the nearest city"));
    mTipLabel->setStyleSheet("background:transparent;color:#626c6e;");
    mTipLabel->setAlignment(Qt::AlignHCenter);

    layout->addWidget(m_searchInput, 0, Qt::AlignHCenter);
    layout->addWidget(mTipLabel,Qt::AlignHCenter);
    layout->addSpacing(32);
    layout->addWidget(m_map, 0, Qt::AlignHCenter);
    layout->addSpacing(32);
    layout->addLayout(btnlayout);
    layout->addSpacing(32);

    setLayout(layout);

    connect(m_confirmBtn, &QPushButton::clicked,[this]{
        QString timezone = m_map->getTimezone();
        hide();
        emit this->confirmed(timezone, windowTitle());
    });

    connect(m_cancelBtn, &QPushButton::clicked, this, [this]{
        hide();
        emit this->cancelled();
    });

    connect(m_map, &TimezoneMap::timezoneSelected, this, [this]{
        if (m_searchInput->hasFocus() || !m_searchInput->text().isEmpty()) {
            m_searchInput->setText("");
            m_searchInput->setFocus();
            m_searchInput->clearFocus();
        }
    });

    connect(m_searchInput, &QLineEdit::editingFinished, [this]{
        QString timezone = m_searchInput->text();
        timezone = m_zoneCompletion.value(timezone,timezone);
        m_map->setTimezone(timezone);
    });

    QTimer::singleShot(0, [this] {
        QStringList completions;
        const QString locale = QLocale::system().name();
//        completions << kenBj;
//        completions << kcnBj;
//        m_zoneCompletion[kcnBj] = kenBj;
        QString zoneBeiJing = "Asia/Beijing";
        QString localizedTimezoneBeiJing = m_zoneinfo->getLocalTimezoneName(zoneBeiJing, locale);
        completions << localizedTimezoneBeiJing;

        m_zoneCompletion[localizedTimezoneBeiJing] = zoneBeiJing;
        for (QString timezone : QTimeZone::availableTimeZoneIds()) {
//            if ("Asia/Shanghai" == timezone) {
//                continue;
//            }
            completions << timezone;
            QString localizedTimezone = m_zoneinfo->getLocalTimezoneName(timezone, locale);
            completions << localizedTimezone;
            m_zoneCompletion[localizedTimezone] = timezone;
        }
        if (!completions.contains(zoneBeiJing)) {
            completions << zoneBeiJing;
        }

        QCompleter *completer = new QCompleter(completions, m_searchInput);
        completer->popup()->setAttribute(Qt::WA_InputMethodEnabled);
        completer->setCompletionMode(QCompleter::PopupCompletion);
        completer->setCaseSensitivity(Qt::CaseInsensitive);
        completer->setFilterMode(Qt::MatchContains);
        m_searchInput->reloadStyle();

        m_searchInput->setCompleter(completer);

#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0)
        connect(completer, static_cast<void(QCompleter::*)(const QString &)>(&QCompleter::activated),
                [=](const QString &text){
#else
        //鼠标点击后直接页面跳转(https://doc.qt.io/qt-5/qcompleter.html#activated-1)
        connect(completer, QOverload<const QString &>::of(&QCompleter::activated),
                [=](const QString &text) {
#endif
            Q_UNUSED(text);
            QString timezone = m_searchInput->text();
            timezone = m_zoneCompletion.value(timezone,timezone);
            m_map->setTimezone(timezone);
        });

        m_popup = completer->popup();
    });
}

void TimeZoneChooser::setTitle(QString title) {
    this->setWindowTitle(title);
}

void TimeZoneChooser::setMarkedTimeZoneSlot(QString timezone) {
    m_map->setTimezone(timezone);
}

void TimeZoneChooser::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Escape) {
        this->hide();
    } else if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
        emit m_confirmBtn->clicked();
    } else {
        QDialog::keyPressEvent(event);
    }
    return;
}

void TimeZoneChooser::keyRealeaseEvent(QKeyEvent *event) {
    if (event->matches(QKeySequence::Cancel)) {
        hide();
        emit this->cancelled();
    }
}

//获取适合屏幕的地图大小
QSize TimeZoneChooser::getFitSize(){
    // const QDesktopWidget *desktop = QApplication::desktop();
    // const QRect primaryRect = desktop->availableGeometry(desktop->primaryScreen());

    // double width = primaryRect.width() - 360/* dcc */ - 20 * 2;
    // double height = primaryRect.height() - 70/* dock */ - 20 * 2;

    return QSize(960, 602);
}


void TimeZoneChooser::initSize(){

    double MapPixWidth = 900.0;
    double MapPixHeight = 500.0;
    double MapPictureWidth = 978.0;
    double MapPictureHeight = 500.0;

    const QSize fitSize = getFitSize();
   setFixedSize(fitSize.width(), fitSize.height());

    const float mapWidth = qMin(MapPixWidth, fitSize.width() - 20 * 2.0);
    //搜索时区36,取消 确定按钮36, mTipLabel 36
    const float mapHeight = qMin(MapPixHeight, fitSize.height() - 36.0 * 3 - 32.0 * 3);
    const double widthScale = MapPictureWidth / mapWidth;
    const double heightScale = MapPictureHeight / mapHeight;
    const double scale = qMax(widthScale, heightScale);

    m_map->setFixedSize(MapPictureWidth / scale, MapPictureHeight / scale);

    m_cancelBtn->setFixedWidth(120);
    m_confirmBtn->setFixedWidth(120);
}

void TimeZoneChooser::hide()
{
    m_searchInput->setText("");
    m_searchInput->setFocus();
    m_searchInput->clearFocus();
    QDialog::hide();
    return;
}

void TimeZoneChooser::closeEvent(QCloseEvent *e)
{
    hide();
    emit cancelled();
}
