//
//  SettingModels.swift
//  suixinkan
//

import Foundation

/// 最新版本响应实体，对齐 Android `VersionResponse`。
struct VersionResponse: Decodable, Equatable {
    let id: Int
    let type: Int
    let version: String
    let operatorName: String
    let description: String
    let status: Int
    let createdAt: String
    let updatedAt: String
    let deletedAt: String?
    let versionCode: Int
    let apkURL: String
    let isForceUpdate: Int
    let approveNotes: String

    enum CodingKeys: String, CodingKey {
        case id
        case type
        case version
        case operatorName = "operator"
        case description
        case status
        case createdAt = "created_at"
        case updatedAt = "updated_at"
        case deletedAt = "deleted_at"
        case versionCode = "version_code"
        case apkURL = "apk_url"
        case isForceUpdate = "is_force_update"
        case approveNotes = "approve_notes"
    }

    init(
        id: Int = 0,
        type: Int = 0,
        version: String = "",
        operatorName: String = "",
        description: String = "",
        status: Int = 0,
        createdAt: String = "",
        updatedAt: String = "",
        deletedAt: String? = nil,
        versionCode: Int = 0,
        apkURL: String = "",
        isForceUpdate: Int = 0,
        approveNotes: String = ""
    ) {
        self.id = id
        self.type = type
        self.version = version
        self.operatorName = operatorName
        self.description = description
        self.status = status
        self.createdAt = createdAt
        self.updatedAt = updatedAt
        self.deletedAt = deletedAt
        self.versionCode = versionCode
        self.apkURL = apkURL
        self.isForceUpdate = isForceUpdate
        self.approveNotes = approveNotes
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decodeLossyInt(forKey: .id) ?? 0
        type = try container.decodeLossyInt(forKey: .type) ?? 0
        version = try container.decodeLossyString(forKey: .version)
        operatorName = try container.decodeLossyString(forKey: .operatorName)
        description = try container.decodeLossyString(forKey: .description)
        status = try container.decodeLossyInt(forKey: .status) ?? 0
        createdAt = try container.decodeLossyString(forKey: .createdAt)
        updatedAt = try container.decodeLossyString(forKey: .updatedAt)
        deletedAt = try container.decodeIfPresent(String.self, forKey: .deletedAt)
        versionCode = try container.decodeLossyInt(forKey: .versionCode) ?? 0
        apkURL = try container.decodeLossyString(forKey: .apkURL)
        isForceUpdate = try container.decodeLossyInt(forKey: .isForceUpdate) ?? 0
        approveNotes = try container.decodeLossyString(forKey: .approveNotes)
    }
}

/// 设置页协议入口实体，表示标题和对应 H5 地址。
struct SettingAgreementDestination: Equatable {
    let title: String
    let url: URL
}

/// 设置页协议类型。
enum SettingAgreementKind: CaseIterable {
    case aboutUs
    case userAgreement
    case privacyPolicy
}

private extension KeyedDecodingContainer {
    func decodeLossyString(forKey key: Key) throws -> String {
        if let value = try? decodeIfPresent(String.self, forKey: key) {
            return value
        }
        if let value = try? decodeIfPresent(Int.self, forKey: key) {
            return String(value)
        }
        if let value = try? decodeIfPresent(Double.self, forKey: key) {
            return String(value)
        }
        if let value = try? decodeIfPresent(Bool.self, forKey: key) {
            return value ? "true" : "false"
        }
        return ""
    }

    func decodeLossyInt(forKey key: Key) throws -> Int? {
        if let value = try? decodeIfPresent(Int.self, forKey: key) {
            return value
        }
        if let value = try? decodeIfPresent(String.self, forKey: key) {
            let text = value.trimmingCharacters(in: .whitespacesAndNewlines)
            if let intValue = Int(text) {
                return intValue
            }
            if let doubleValue = Double(text) {
                return Int(doubleValue)
            }
        }
        if let value = try? decodeIfPresent(Double.self, forKey: key) {
            return Int(value)
        }
        return nil
    }
}
