//
//  AppLocationStore.swift
//  suixinkan
//

import Foundation

/// 管理当前账号的位置上报会话与提醒偏好。
final class AppLocationStore {

    private enum Key: String, CaseIterable {
        case onlineStatus = "key_online_status"
        case lastReportTime = "key_last_location_report_time"
        case reminderMinutes = "key_location_reminder_minutes"
    }

    private let defaults: UserDefaults
    private let session: AppSessionStore

    /// 使用指定持久化容器和会话创建位置存储。
    init(defaults: UserDefaults, session: AppSessionStore) {
        self.defaults = defaults
        self.session = session
    }

    /// 是否处于位置上报在线状态。
    var onlineStatus: Bool {
        get {
            guard let key = scopedKey(.onlineStatus) else { return false }
            return defaults.bool(forKey: key)
        }
        set {
            guard let key = scopedKey(.onlineStatus) else { return }
            defaults.set(newValue, forKey: key)
        }
    }

    /// 上次位置上报时间戳，单位为毫秒。
    var lastReportTime: Int64 {
        get {
            guard let key = scopedKey(.lastReportTime) else { return 0 }
            return Int64(defaults.integer(forKey: key))
        }
        set {
            guard let key = scopedKey(.lastReportTime) else { return }
            defaults.set(Int(newValue), forKey: key)
        }
    }

    /// 位置超时提前提醒分钟数，0 表示不提醒。
    var reminderMinutes: Int {
        get {
            guard let key = scopedKey(.reminderMinutes) else { return 0 }
            return defaults.integer(forKey: key)
        }
        set {
            guard let key = scopedKey(.reminderMinutes) else { return }
            defaults.set(newValue, forKey: key)
        }
    }

    /// 清除上次位置上报时间。
    func clearLastReportTime() {
        guard let key = scopedKey(.lastReportTime) else { return }
        defaults.removeObject(forKey: key)
    }

    /// 清除当前账号的位置上报状态和偏好。
    func clear(accountScope: String) {
        guard !accountScope.isEmpty else { return }
        Key.allCases.forEach { defaults.removeObject(forKey: "\(accountScope)_\($0.rawValue)") }
    }

    private func scopedKey(_ key: Key) -> String? {
        session.accountScopedKey(key.rawValue)
    }
}
