// SPDX-FileCopyrightText: 2023 by Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later

#include "timeutil.h"

#include <QDebug>
#include <QRegularExpression>
#include <QTimeZone>

#include <KConfigGroup>
#include <KLocalizedString>
#include <KSharedConfig>

#define FORMAT24H "HH:mm:ss"
#define FORMAT12H "h:mm:ss ap"

TimeUtil::TimeUtil(QObject *parent)
    : QObject{parent}
    , m_currentTimeZone{QString::fromUtf8(QTimeZone::systemTimeZoneId())}
    , m_timeZoneModel{new TimeZoneModel{this}}
    , m_filterModel{new TimeZoneFilterProxy{this}}
{
    if (m_currentTimeZone.isEmpty() || !QTimeZone(m_currentTimeZone.toUtf8()).isValid()) {
        m_currentTimeZone = QStringLiteral("UTC");
    }

    m_filterModel->setSourceModel(m_timeZoneModel);

    // retrieve is24HourTime
    auto config = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::SimpleConfig);
    auto group = KConfigGroup(config, "Locale");
    m_is24HourTime = group.readEntry(QStringLiteral("TimeFormat"), FORMAT24H) == FORMAT24H;
}

bool TimeUtil::is24HourTime() const
{
    return m_is24HourTime;
}

void TimeUtil::setIs24HourTime(bool is24HourTime)
{
    if (is24HourTime != m_is24HourTime) {
        auto config = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::SimpleConfig);
        auto group = KConfigGroup(config, "Locale");
        group.writeEntry(QStringLiteral("TimeFormat"), is24HourTime ? FORMAT24H : FORMAT12H, KConfig::Notify);
        config->sync();

        m_is24HourTime = is24HourTime;
        Q_EMIT is24HourTimeChanged();
    }
}

QString TimeUtil::currentTimeZone() const
{
    return m_currentTimeZone;
}

void TimeUtil::setCurrentTimeZone(QString timeZone)
{
    if (timeZone == m_currentTimeZone) {
        return;
    }

    const QTimeZone zone(timeZone.toUtf8());
    if (!zone.isValid()) {
        m_timeZoneStatus = i18n("This time zone is not available.");
        Q_EMIT timeZoneStatusChanged();
        return;
    }

    m_currentTimeZone = timeZone;
    Q_EMIT currentTimeZoneChanged();

    const int exitCode = QProcess::execute(QStringLiteral("timedatectl"), {QStringLiteral("set-timezone"), timeZone});
    const QString status = exitCode == 0 ? QString() : i18n("Selected here, but the system time zone could not be changed.");
    if (status != m_timeZoneStatus) {
        m_timeZoneStatus = status;
        Q_EMIT timeZoneStatusChanged();
    }
}

QString TimeUtil::timeZoneStatus() const
{
    return m_timeZoneStatus;
}

TimeZoneFilterProxy *TimeUtil::timeZones() const
{
    return m_filterModel;
}
