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

import Foundation

/// 可关联订单实体，表示任务、排班等业务表单中可选择的订单。
struct AvailableOrderResponse: Decodable, Identifiable, Hashable {
    var id: String { orderNumber }
    let projectName: String
    let orderNumber: String
    let orderStatus: Int
    let orderStatusLabel: String
    let payTime: String
    let userPhone: String

    /// 可关联订单字段映射，兼容后端下划线命名。
    enum CodingKeys: String, CodingKey {
        case projectName = "project_name"
        case orderNumber = "order_number"
        case orderStatus = "order_status"
        case orderStatusLabel = "order_status_label"
        case payTime = "pay_time"
        case userPhone = "user_phone"
    }

    /// 宽松解码可关联订单字段。
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        projectName = try container.decodeSharedLossyString(forKey: .projectName)
        orderNumber = try container.decodeSharedLossyString(forKey: .orderNumber)
        orderStatus = try container.decodeSharedLossyInt(forKey: .orderStatus) ?? 0
        orderStatusLabel = try container.decodeSharedLossyString(forKey: .orderStatusLabel)
        payTime = try container.decodeSharedLossyString(forKey: .payTime)
        userPhone = try container.decodeSharedLossyString(forKey: .userPhone)
    }
}

/// 摄影项目列表项实体，表示项目管理列表和样片上传时可关联的项目。
struct PhotographerProjectItem: Decodable, Identifiable, Hashable {
    let id: Int
    let type: Int
    let typeName: String
    let status: Int
    let statusName: String
    let name: String
    let coverProject: String
    let coverVideo: String
    let price: String
    let otPrice: String
    let priceDeposit: String
    let attrLabel: [String]
    let label: String

    /// 创建摄影项目列表项，主要用于详情页摘要和测试替身。
    init(
        id: Int,
        type: Int = 0,
        typeName: String = "",
        status: Int = 0,
        statusName: String = "",
        name: String,
        coverProject: String = "",
        coverVideo: String = "",
        price: String = "",
        otPrice: String = "",
        priceDeposit: String = "",
        attrLabel: [String] = [],
        label: String = ""
    ) {
        self.id = id
        self.type = type
        self.typeName = typeName
        self.status = status
        self.statusName = statusName
        self.name = name
        self.coverProject = coverProject
        self.coverVideo = coverVideo
        self.price = price
        self.otPrice = otPrice
        self.priceDeposit = priceDeposit
        self.attrLabel = attrLabel
        self.label = label
    }

    /// 字段映射，兼容后端下划线命名。
    enum CodingKeys: String, CodingKey {
        case id
        case type
        case typeName = "type_name"
        case status
        case statusName = "status_name"
        case name
        case coverProject = "cover_project"
        case coverVideo = "cover_video"
        case price
        case otPrice = "ot_price"
        case priceDeposit = "price_deposit"
        case attrLabel = "attr_label"
        case label
    }

    /// 宽松解码项目列表项。
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decodeSharedLossyInt(forKey: .id) ?? 0
        type = try container.decodeSharedLossyInt(forKey: .type) ?? 0
        typeName = try container.decodeSharedLossyString(forKey: .typeName)
        status = try container.decodeSharedLossyInt(forKey: .status) ?? 0
        statusName = try container.decodeSharedLossyString(forKey: .statusName)
        name = try container.decodeSharedLossyString(forKey: .name)
        coverProject = try container.decodeSharedLossyString(forKey: .coverProject)
        coverVideo = try container.decodeSharedLossyString(forKey: .coverVideo)
        price = try container.decodeSharedLossyString(forKey: .price)
        otPrice = try container.decodeSharedLossyString(forKey: .otPrice)
        priceDeposit = try container.decodeSharedLossyString(forKey: .priceDeposit)
        label = try container.decodeSharedLossyString(forKey: .label)
        if let labels = try? container.decodeIfPresent([String].self, forKey: .attrLabel) {
            attrLabel = labels
        } else if let text = try? container.decodeIfPresent(String.self, forKey: .attrLabel) {
            attrLabel = text
                .components(separatedBy: CharacterSet(charactersIn: ",，"))
                .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
                .filter { !$0.isEmpty }
        } else {
            attrLabel = []
        }
    }
}

private extension KeyedDecodingContainer {
    /// 将 String、数字和 Bool 宽松解码为字符串。
    func decodeSharedLossyString(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 decodeSharedLossyInt(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) {
            let text = value.trimmingCharacters(in: .whitespacesAndNewlines)
            return Int(text) ?? Double(text).map(Int.init)
        }
        return nil
    }
}
