#include "areainterface.h"
#include <unistd.h>
#include <QDBusConnection>

AreaInterface::AreaInterface()
{
    ukccPanelGsettings = UniversalInterface::self()->ukccPanelGsettings();
    accountInterface   = UniversalInterface::self()->accountUserDbus();
    fcitxInterface     = UniversalInterface::self()->fcitxInputMethodDbus();
    styleGsettings     = UniversalInterface::self()->ukuiStyleGsettings();
    m_calendarGsettings  = UniversalInterface::self()->calendarGsettings();

    initConnect();
}

AreaInterface::~AreaInterface()
{

}

void AreaInterface::initConnect()
{
    connect(ukccPanelGsettings, &QGSettings::changed, this, [=](QString key) {
        if (key == CALENDAR_KEY) {
            Q_EMIT changed("calendar");
        } else if (key == FIRST_DAY_KEY) {
            Q_EMIT changed("firstDay");
        } else if (key == DATE_FORMATE_KEY) {
            Q_EMIT changed("dateFormat");
        } else if (key == TIME_FORMAT_KEY) {
            Q_EMIT changed("timeFormat");
        } else if (key == SHOW_LANGUAGE_KEY) {
            Q_EMIT changed("showLanguageList");
        }
    });

    connect(styleGsettings, &QGSettings::changed, this, [=](QString key) {
        if (key == "iconThemeName") {
            Q_EMIT changed("iconThemeName");
        }
    });
    if (m_calendarGsettings) {
        connect(m_calendarGsettings, &QGSettings::changed, this, [=](QString key) {
            if (key == LUNAR_DATE_KEY) {
                Q_EMIT changed("lunarDate");
            }
        });
    }
}

QString AreaInterface::gsettingCalendarGet(const QString &key) const
{
    if (!m_calendarGsettings) {
        return "";
    }
    if (m_calendarGsettings->keys().contains(key)) {
        return m_calendarGsettings->get(key).toString();
    } else {
        qCritical() << "calendarGsettings not contains the key: " << key;
        return "";
    }
}

QString AreaInterface::gsettingGet(const QString &key) const
{
    if (ukccPanelGsettings->keys().contains(key)) {
        return ukccPanelGsettings->get(key).toString();
    } else {
        qCritical() << "ukccPanelGsettings not contains the key: " << key;
        return "";
    }
}

void AreaInterface::gsettingSet(const QString &key, const QString &value)
{
    if (ukccPanelGsettings->keys().contains(key)) {
        ukccPanelGsettings->set(key, value);
    } else {
        qCritical() << "ukccPanelGsettings not contains the key: " << key;
    }
}

QStringList AreaInterface::getFormatCountryList()
{
    QStringList formatList;
    formatList << QString("en_US.UTF-8") << QString("zh_CN.UTF-8") << QString("bo_CN.UTF-8");
    if (isOpenkylin()) {
        formatList.removeLast();
#ifdef Nile
    formatList << QString("bo_CN.UTF-8") << QString("ug_CN.UTF-8") << QString("ky_KG.UTF-8")
               << QString("zh_HK.UTF-8") << QString("kk_KZ.UTF-8") << QString("mn_MN.UTF-8")
               << QString("de_DE.UTF-8") << QString("es_ES.UTF-8") << QString("fr_FR.UTF-8");
#endif
    }

    return formatList;
}

QStringList AreaInterface::getCalendarList()
{
    QStringList list = {};
    list.append(QString("solarlunar"));
    QString locale = QLocale::system().name();
    if ("zh_CN" == locale) {
        list.append(QString("lunar"));
    }
    return list;
}

QStringList AreaInterface::getFirstDayList()
{
    return QStringList() << QString("monday") << QString("sunday");
}

QStringList AreaInterface::getDateFormatList()
{
    return QStringList() << QString("cn") << QString("en");
}

QStringList AreaInterface::getTimeFormatList()
{
    return QStringList() << QString("12") << QString("24");
}

QStringList AreaInterface::getShowLanguageList()
{
    if (ukccPanelGsettings->keys().contains(SHOW_LANGUAGE_KEY)) {
        return ukccPanelGsettings->get(SHOW_LANGUAGE_KEY).toStringList();;
    } else {
        qCritical() << "ukccPanelGsettings not contains the key: " << SHOW_LANGUAGE_KEY;
    }
    return QStringList();
}

QStringList AreaInterface::getLanguageList()
{
    QStringList formatList;
    formatList << QString("zh_CN") << QString("en") << QString("bo_CN");

    if (isOpenkylin()) {
        formatList.removeLast();
#ifdef Nile
    formatList << QString("bo_CN") << QString("ug_CN") << QString("ky_KG")
               << QString("zh_HK") << QString("kk_KZ") << QString("mn_MN")
               << QString("de_DE") << QString("es_ES") << QString("fr_FR");
    return formatList;
#endif
    }

    return formatList;
}

bool AreaInterface::isOpenkylin()
{
    QString systemName = QString(QLatin1String(kdk_system_get_systemName()));
    if (systemName.compare("openkylin", Qt::CaseInsensitive) == 0) {
        return true;
    }
    return false;
}

QString AreaInterface::getFormatCountry()
{
    return accountInterface->property("FormatsLocale").toString();;
}

QString AreaInterface::getCalendar()
{
    return gsettingGet(CALENDAR_KEY);;
}

QString AreaInterface::getFirstDay()
{
    return gsettingGet(FIRST_DAY_KEY);;
}

QString AreaInterface::getDateFormat()
{
    return gsettingGet(DATE_FORMATE_KEY);;
}

QString AreaInterface::getTimeFormat()
{
    return gsettingGet(TIME_FORMAT_KEY);;
}

QString AreaInterface::getLunarDate()
{
    return gsettingCalendarGet(LUNAR_DATE_KEY);;
}

QString AreaInterface::getLanguage()
{
    return accountInterface->property("Language").toString();;
}

void AreaInterface::setFormatCountry(const QString &formatCountry)
{
    if (getFormatCountryList().contains(formatCountry)) {
        accountInterface->call("SetFormatsLocale", formatCountry);
        Q_EMIT changed("formatCountry");
    }
}

// Gsetting设置会触发changed(key)信号，因此无需Q_EMIT changed，避免重复触发信号。
void AreaInterface::setCalendar(const QString &calendar)
{
    if (getCalendarList().contains(calendar)) {
        gsettingSet(CALENDAR_KEY, calendar);
    }
}

void AreaInterface::setFirstDay(const QString &firstDay)
{
    if (getFirstDayList().contains(firstDay)) {
        gsettingSet(FIRST_DAY_KEY, firstDay);
    };
}

void AreaInterface::setDateFormat(const QString &dateFormat)
{
    if (getDateFormatList().contains(dateFormat)) {
        gsettingSet(DATE_FORMATE_KEY, dateFormat);
    }
}

void AreaInterface::setTimeFormat(const QString &timeFormat)
{
    if (getTimeFormatList().contains(timeFormat)) {
        gsettingSet(TIME_FORMAT_KEY, timeFormat);
    }
}

void AreaInterface::setShowLanguageList(const QStringList &languageList)
{
    bool flag = true;
    for (QString s: languageList) {
        if (!getLanguageList().contains(s)) {
           flag = false;
           break;
        }
    }
    if (flag) {
        if (ukccPanelGsettings->keys().contains(SHOW_LANGUAGE_KEY)) {
            ukccPanelGsettings->set(SHOW_LANGUAGE_KEY, languageList);
        } else {
            qCritical() << "ukccPanelGsettings not contains the key: " << SHOW_LANGUAGE_KEY;
        }
    }
}

void AreaInterface::setLanguage(const QString &languageCode)
{
    if (getLanguageList().contains(languageCode)) {
        accountInterface->call("SetLanguage", languageCode);
        Q_EMIT changed("language");
    }
}

void AreaInterface::reloadInputMethodConfig()
{
    fcitxInterface->call("ReloadConfig");
}

void AreaInterface::changeInputMethod(const QString &inputMethod, const bool &add)
{
    QString fileTextString;
    QFile configFile(FCITX_CONFIG_FILE);
    if (configFile.open(QIODevice::ReadWrite | QIODevice::Text)) {
        //把文件所有信息读出来
        QTextStream stream(&configFile);
        fileTextString = stream.readAll();

        if (!fileTextString.contains(inputMethod)) {
            return ;
        }
        QString addString    = inputMethod  + ":True";
        QString removeString =  inputMethod + ":False";
        if (add) {
            fileTextString.replace(removeString, addString);
        } else {
            fileTextString.replace(addString, removeString);
        }
        stream << fileTextString;
        configFile.close();
        reloadInputMethodConfig();
    }
}

bool AreaInterface::isAddedInputMethod(const QString &inputMethod)
{
    QString fileTextString;
    QFile mFile(FCITX_CONFIG_FILE);
    if (mFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QTextStream stream(&mFile);
        fileTextString = stream.readAll();
        QString string = inputMethod  + ":True";
        if (fileTextString.contains(string)) {
           return true;
        } else {
            return false;
        }
    }
    qCritical()<<"open "<<FCITX_CONFIG_FILE<<" error.";
    return false;
}
