//
//  LocationReportModels.swift
//  suixinkan
//
//  Created by Codex on 2026/6/24.
//

import Foundation

/// 位置上报类型实体，表示立即上报、标记点上报和在线状态上报。
enum LocationReportType: Int, CaseIterable, Identifiable {
    case all = 0
    case immediate = 1
    case marked = 2
    case onlineStatus = 3

    var id: Int { rawValue }

    /// 上报类型展示标题。
    var title: String {
        switch self {
        case .all: "全部"
        case .immediate: "立即上报"
        case .marked: "标记点"
        case .onlineStatus: "在线状态"
        }
    }
}

/// 位置坐标实体，表示定位或手动选点得到的经纬度。
struct LocationCoordinate: Equatable {
    var latitude: Double
    var longitude: Double
}

/// 位置上报提交响应实体，表示服务端返回的上报人员、过期秒数和状态。
struct LocationReportSubmitResponse: Decodable, Equatable {
    let staffId: String
    let expired: Int
    let status: Int

    enum CodingKeys: String, CodingKey {
        case staffId = "staff_id"
        case expired
        case status
    }

    /// 创建位置上报提交响应，主要用于测试替身返回。
    init(staffId: String, expired: Int, status: Int) {
        self.staffId = staffId
        self.expired = expired
        self.status = status
    }

    /// 宽松解码提交响应字段。
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        staffId = try container.decodeLossyString(forKey: .staffId)
        expired = try container.decodeLossyInt(forKey: .expired) ?? 0
        status = try container.decodeLossyInt(forKey: .status) ?? 0
    }
}

/// 位置上报历史项实体，表示一次历史上报记录。
struct LocationReportHistoryItem: Decodable, Equatable, Identifiable {
    let id: Int
    let staffId: Int
    let type: Int
    let latitude: String
    let longitude: String
    let address: String
    let ip: String
    let remark: String
    let createdAt: String

    enum CodingKeys: String, CodingKey {
        case id
        case staffId = "staff_id"
        case type
        case latitude
        case longitude
        case address
        case ip
        case remark
        case createdAt = "created_at"
    }

    /// 宽松解码历史项字段。
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decodeLossyInt(forKey: .id) ?? 0
        staffId = try container.decodeLossyInt(forKey: .staffId) ?? 0
        type = try container.decodeLossyInt(forKey: .type) ?? 0
        latitude = try container.decodeLossyString(forKey: .latitude)
        longitude = try container.decodeLossyString(forKey: .longitude)
        address = try container.decodeLossyString(forKey: .address)
        ip = try container.decodeLossyString(forKey: .ip)
        remark = try container.decodeLossyString(forKey: .remark)
        createdAt = try container.decodeLossyString(forKey: .createdAt)
    }

    /// 上报类型展示文案。
    var typeTitle: String {
        LocationReportType(rawValue: type)?.title ?? "未知"
    }
}

private extension KeyedDecodingContainer {
    /// 将 String、数字和 Bool 宽松解码为字符串。
    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 ? "1" : "0" }
        return ""
    }

    /// 将 String、Double 和 Int 宽松解码为 Int。
    func decodeLossyInt(forKey key: Key) throws -> Int? {
        if let value = try? decodeIfPresent(Int.self, forKey: key) { return value }
        if let value = try? decodeIfPresent(Double.self, forKey: key) { return Int(value) }
        if let value = try? decodeIfPresent(String.self, forKey: key) {
            return Int(value.trimmingCharacters(in: .whitespacesAndNewlines))
        }
        return nil
    }
}
