//
//  PilotCertificationModels.swift
//  suixinkan
//
//  Created by Codex on 2026/6/25.
//

import Foundation

/// 飞手证件类型。
enum PilotCertType: Int, CaseIterable, Identifiable {
    case idCard = 1
    case caac = 2

    var id: Int { rawValue }

    var title: String {
        switch self {
        case .idCard:
            "身份证"
        case .caac:
            "民用无人机驾驶员执照"
        }
    }
}

/// 飞手认证详情响应。
struct FlyerDetailResponse: Decodable, Equatable {
    let id: Int
    let name: String
    let accountId: String
    let realnameStatus: Int
    let status: Int
    let statusName: String
    let submitTime: String
    let updatedAt: String
    let auditPerson: String
    let auditTime: String
    let auditNote: String
    let certificateType: Int
    let certificateNo: String
    let certificateStartDate: String
    let certificateEndDate: String
    let certificateImage: String
    let droneModel: String
    let droneSn: String
    let contactPhone: String
    let realnameStatusText: String
    let certificationLogs: [FlyerCertificationLogItem]

    enum CodingKeys: String, CodingKey {
        case id
        case name = "flyer_nickname"
        case accountId = "account_id"
        case realnameStatus = "realname_status"
        case status
        case statusName = "status_text"
        case submitTime = "created_at"
        case updatedAt = "updated_at"
        case auditPerson = "reviewer"
        case auditTime = "review_time"
        case auditNote = "reject_reason"
        case certificateType = "certificate_type"
        case certificateNo = "certificate_no"
        case certificateStartDate = "certificate_start_date"
        case certificateEndDate = "certificate_end_date"
        case certificateImage = "certificate_image"
        case droneModel = "drone_model"
        case droneSn = "drone_sn"
        case contactPhone = "contact_phone"
        case realnameStatusText = "realname_status_text"
        case certificationLogs = "flyers_certification_logs"
    }

    init(
        id: Int = 0,
        name: String = "",
        accountId: String = "",
        realnameStatus: Int = 2,
        status: Int = 0,
        statusName: String = "",
        submitTime: String = "",
        updatedAt: String = "",
        auditPerson: String = "",
        auditTime: String = "",
        auditNote: String = "",
        certificateType: Int = 2,
        certificateNo: String = "",
        certificateStartDate: String = "",
        certificateEndDate: String = "",
        certificateImage: String = "",
        droneModel: String = "",
        droneSn: String = "",
        contactPhone: String = "",
        realnameStatusText: String = "",
        certificationLogs: [FlyerCertificationLogItem] = []
    ) {
        self.id = id
        self.name = name
        self.accountId = accountId
        self.realnameStatus = realnameStatus
        self.status = status
        self.statusName = statusName
        self.submitTime = submitTime
        self.updatedAt = updatedAt
        self.auditPerson = auditPerson
        self.auditTime = auditTime
        self.auditNote = auditNote
        self.certificateType = certificateType
        self.certificateNo = certificateNo
        self.certificateStartDate = certificateStartDate
        self.certificateEndDate = certificateEndDate
        self.certificateImage = certificateImage
        self.droneModel = droneModel
        self.droneSn = droneSn
        self.contactPhone = contactPhone
        self.realnameStatusText = realnameStatusText
        self.certificationLogs = certificationLogs
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.pilotDecodeLossyInt(forKey: .id) ?? 0
        name = try container.pilotDecodeLossyString(forKey: .name)
        accountId = try container.pilotDecodeLossyString(forKey: .accountId)
        realnameStatus = try container.pilotDecodeLossyInt(forKey: .realnameStatus) ?? 2
        status = try container.pilotDecodeLossyInt(forKey: .status) ?? 0
        statusName = try container.pilotDecodeLossyString(forKey: .statusName)
        submitTime = try container.pilotDecodeLossyString(forKey: .submitTime)
        updatedAt = try container.pilotDecodeLossyString(forKey: .updatedAt)
        auditPerson = try container.pilotDecodeLossyString(forKey: .auditPerson)
        auditTime = try container.pilotDecodeLossyString(forKey: .auditTime)
        auditNote = try container.pilotDecodeLossyString(forKey: .auditNote)
        certificateType = try container.pilotDecodeLossyInt(forKey: .certificateType) ?? 2
        certificateNo = try container.pilotDecodeLossyString(forKey: .certificateNo)
        certificateStartDate = try container.pilotDecodeLossyString(forKey: .certificateStartDate)
        certificateEndDate = try container.pilotDecodeLossyString(forKey: .certificateEndDate)
        certificateImage = try container.pilotDecodeLossyString(forKey: .certificateImage)
        droneModel = try container.pilotDecodeLossyString(forKey: .droneModel)
        droneSn = try container.pilotDecodeLossyString(forKey: .droneSn)
        contactPhone = try container.pilotDecodeLossyString(forKey: .contactPhone)
        realnameStatusText = try container.pilotDecodeLossyString(forKey: .realnameStatusText)
        certificationLogs = try container.decodeIfPresent([FlyerCertificationLogItem].self, forKey: .certificationLogs) ?? []
    }
}

/// 飞手认证审核日志项。
struct FlyerCertificationLogItem: Decodable, Identifiable, Equatable {
    let id: Int
    let flyerId: Int
    let operatorName: String
    let action: Int
    let actionText: String
    let rejectReason: String
    let remark: String
    let createdAt: String

    enum CodingKeys: String, CodingKey {
        case id
        case flyerId = "flyer_id"
        case operatorName = "operator"
        case action
        case actionText = "action_text"
        case rejectReason = "reject_reason"
        case remark
        case createdAt = "created_at"
    }

    init(
        id: Int = 0,
        flyerId: Int = 0,
        operatorName: String = "",
        action: Int = 0,
        actionText: String = "",
        rejectReason: String = "",
        remark: String = "",
        createdAt: String = ""
    ) {
        self.id = id
        self.flyerId = flyerId
        self.operatorName = operatorName
        self.action = action
        self.actionText = actionText
        self.rejectReason = rejectReason
        self.remark = remark
        self.createdAt = createdAt
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.pilotDecodeLossyInt(forKey: .id) ?? 0
        flyerId = try container.pilotDecodeLossyInt(forKey: .flyerId) ?? 0
        operatorName = try container.pilotDecodeLossyString(forKey: .operatorName)
        action = try container.pilotDecodeLossyInt(forKey: .action) ?? 0
        actionText = try container.pilotDecodeLossyString(forKey: .actionText)
        rejectReason = try container.pilotDecodeLossyString(forKey: .rejectReason)
        remark = try container.pilotDecodeLossyString(forKey: .remark)
        createdAt = try container.pilotDecodeLossyString(forKey: .createdAt)
    }
}

/// 飞手认证短信验证码请求。
struct FlyerSendCodeRequest: Encodable, Equatable {
    let phone: String
}

/// 飞手首次认证申请请求。
struct FlyerApplyRequest: Encodable, Equatable {
    let name: String
    let realnameStatus: Int
    let certificateType: Int
    let certificateNo: String
    let certificateStartDate: String
    let certificateEndDate: String
    let certificateImage: String
    let droneModel: String
    let droneSn: String
    let contactPhone: String
    let code: String

    enum CodingKeys: String, CodingKey {
        case name
        case realnameStatus = "realname_status"
        case certificateType = "certificate_type"
        case certificateNo = "certificate_no"
        case certificateStartDate = "certificate_start_date"
        case certificateEndDate = "certificate_end_date"
        case certificateImage = "certificate_image"
        case droneModel = "drone_model"
        case droneSn = "drone_sn"
        case contactPhone = "contact_phone"
        case code
    }
}

/// 飞手认证驳回后编辑请求。
struct FlyerEditRequest: Encodable, Equatable {
    let id: Int
    let name: String
    let realnameStatus: Int
    let certificateType: Int
    let certificateNo: String
    let certificateStartDate: String
    let certificateEndDate: String
    let certificateImage: String
    let droneModel: String
    let droneSn: String
    let contactPhone: String
    let code: String

    enum CodingKeys: String, CodingKey {
        case id
        case name
        case realnameStatus = "realname_status"
        case certificateType = "certificate_type"
        case certificateNo = "certificate_no"
        case certificateStartDate = "certificate_start_date"
        case certificateEndDate = "certificate_end_date"
        case certificateImage = "certificate_image"
        case droneModel = "drone_model"
        case droneSn = "drone_sn"
        case contactPhone = "contact_phone"
        case code
    }
}

/// 飞手认证校验错误。
enum PilotCertificationValidationError: LocalizedError, Equatable {
    case message(String)

    var errorDescription: String? {
        switch self {
        case .message(let message):
            message
        }
    }
}

private extension KeyedDecodingContainer {
    func pilotDecodeLossyString(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 pilotDecodeLossyInt(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
    }
}
