// Date & Time.
//
// These belong to the machine rather than to Panama, so nothing here is stored
// in Panama's settings file -- it would be a second answer to a question the
// system already answers. Timezone and network time are read from and written
// to timedatectl directly; the clock's presentation lives on Appearance,
// because that genuinely is a Panama preference.
//
// Changing the timezone or network time needs privilege. timedatectl asks
// polkit, and a canceled dialog surfaces as an error rather than as a value
// that appears to have been accepted.

import QtQuick
import Quickshell
import qs.config
import qs.services
import qs.modules.clipboard

SettingsPage {
    id: root

    title: "Date & Time"
    lede: "Timezone and network time, shared with the whole machine."

    SettingsCard {
        title: "Clock"

        TextRow {
            label: "Current time"
            detail: DateTime.timezone === "" ? "Reading the system clock" : DateTime.timezone
            value: Qt.formatDateTime(clock.date, Settings.use24Hour ? "ddd d MMM  HH:mm" : "ddd d MMM  h:mm AP")
        }
        SettingRow {
            label: "Set automatically"
            detail: DateTime.ntpEnabled
                ? (DateTime.ntpSynchronized ? "Synchronized with a time server" : "Waiting to synchronize")
                : "The clock is set by hand"
            controlWidth: 48
            divider: false

            SettingsToggle {
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                checked: DateTime.ntpEnabled
                enabled: !DateTime.busy
                onToggled: value => DateTime.setNtp(value)
            }
        }
    }

    SettingsCard {
        title: "Timezone"

        PickerRow {
            id: zonePicker

            label: "Time zone"
            detail: DateTime.timezone === ""
                ? "Reading the system clock"
                : DateTime.cityOf(DateTime.timezone) + " — " + DateTime.regionOf(DateTime.timezone)
            value: DateTime.timezone === "" ? "Unknown" : DateTime.cityOf(DateTime.timezone)
            divider: false

            SearchField {
                id: zoneSearch
                width: parent.width
                placeholder: "Search timezones"
            }

            Repeater {
                model: root.matchingZones

                TextRow {
                    required property var modelData
                    required property int index

                    label: DateTime.cityOf(modelData)
                    detail: DateTime.regionOf(modelData)
                    value: modelData === DateTime.timezone ? "Current" : ""
                    controlWidth: 90
                    divider: index < root.matchingZones.length - 1
                    activatable: true
                    onActivated: {
                        DateTime.setTimezone(modelData);
                        zonePicker.collapse();
                    }
                }
            }

            TextRow {
                visible: root.matchingZones.length === 0
                label: "No timezone matches that"
                detail: "Try a city or a region, such as \"Denver\" or \"Europe\""
                divider: false
            }
        }
    }

    SettingsCard {
        visible: DateTime.lastError !== ""
        title: "The system did not accept that"
        subtitle: DateTime.lastError
    }

    // Bounded so a blank search does not try to lay out six hundred rows. The
    // current zone is always included, so the card never looks empty when the
    // field is untouched.
    readonly property var matchingZones: {
        const needle = zoneSearch.text.trim().toLowerCase();
        const all = DateTime.zones;
        if (needle === "") {
            // The zone in effect goes first. Listing a region alphabetically
            // means the current setting is usually off the bottom of the card,
            // which makes the list look like it does not know what is set.
            const current = DateTime.timezone;
            const nearby = all
                .filter(zone => zone !== current && DateTime.regionOf(zone) === DateTime.regionOf(current))
                .slice(0, 11);
            return current === "" ? nearby : [current].concat(nearby);
        }
        return all.filter(zone => zone.toLowerCase().replace(/_/g, " ").indexOf(needle) >= 0).slice(0, 40);
    }

    SystemClock {
        id: clock
        precision: SystemClock.Minutes
    }
}
