package com.lukouguoji.module_base.bean

import androidx.databinding.ObservableBoolean
import java.io.Serializable
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

/**
 * 国际出港主单数据模型
 * 对应接口：/IntExpSearch/pageQuery 返回的列表项
 */
data class GjcMaWb(
    // ==================== 主键与基础信息 ====================
    var maWbId: Long? = null,      // 主单主键ID
    var wbNo: String? = null,      // 11位运单号
    var prefix: String? = null,    // 运单号前缀（3位）
    var no: String? = null,        // 运单号主体（8位）
    var oldPrefix: String? = null, // 旧运单前缀
    var oldNo: String? = null,     // 旧运单号

    // ==================== 航班信息 ====================
    var fid: Long? = null,                     // 航班主键id
    var fno: String? = null,                   // 航班号
    var fdate: Date? = null,                   // 航班日期
    var flight: String? = null,                // 航班: 航班日期/航班号
    var fclose: String? = null,                  // 航班关闭时间
    var scheduledTackOff: Date? = null,        // 计划起飞时间
    var scheduledArrival: Date? = null,        // 预计到达时间

    // ==================== 目的地信息 ====================
    var dep: String? = null,       // 始发站
    var dest: String? = null,      // 最终目的站
    var dest1: String? = null,     // 第一目的站
    var dest2: String? = null,     // 第二目的站
    var range: String? = null,     // 航程

    // ==================== 代理与承运人 ====================
    var agentCode: String? = null,    // 代理人code
    var agentName: String? = null,    // 代理人名称
    var customsLib: String? = null,   // 代理人lib
    var by0: String? = null,          // 第一承运人
    var by1: String? = null,          // 第二承运人
    var by2: String? = null,          // 第三承运人

    // ==================== 货物信息 ====================
    var pc: Long? = null,              // 预配件数
    var weight: Double? = null,        // 预配重量（KG）
    var volume: Double? = null,        // 预配体积（CBM）
    var goods: String? = null,         // 品名（英）
    var goodsCn: String? = null,       // 品名（中）
    var packageType: String? = null,   // 包装类型
    var cargoType: String? = null,     // 货物类型
    var origin: String? = null,        // 货源地

    // ==================== 运抵信息 ====================
    var arrivePc: Long? = null,            // 运抵件数
    var arriveWeight: Double? = null,      // 运抵重量
    var arriveVolume: Double? = null,      // 运抵体积
    var arriveFlag: String? = null,        // 运抵状态（0：正常运抵，1：提前运抵）

    // ==================== 特码与收货人 ====================
    var spCode: String? = null,        // 特码
    var subCode: String? = null,       // 子码
    var consignee: String? = null,     // 收货人
    var cneeTel: String? = null,       // 收货人电话

    // ==================== 运单类型 ====================
    var awbType: String? = null,           // 运单类型code
    var awbName: String? = null,           // 运单类型名称（中）
    var businessType: String? = null,      // 业务类型code
    var businessName: String? = null,      // 业务类型名称（中）

    // ==================== 车辆信息 ====================
    var carId: String? = null,         // 平板车号
    var carNumber: String? = null,     // 车牌号
    var passageWay: String? = null,    // 通道号
    var passageWayId: String? = null,
    var palletNumber: String? = null,  // 托盘数量（5.5寸手机版开始计重页，后端暂无该入参，见接口问题清单）
    var carWeight: String? = null,     // 托盘自重（5.5寸手机版手输，后端暂无该入参，见接口问题清单）

    // ==================== 状态信息 ====================
    var checkIn: String? = null,           // 收运状态。0：待收运，1：已收运，2：收运中
    var declareStatus: String? = null,     // 申报状态
    var reviewStatus: String? = null,      // 审核状态（0：未审核；1：通过；2：退回）
    var tranFlag: String? = null,          // 转运标志
    var clearNormal: String? = null,       // 清仓正常（0：否，1：是）

    // ==================== 操作信息 ====================
    var opDate: String? = null,          // 操作时间（入库时间）
    var inDate: String? = null,          // 入库时间
    var opId: String? = null,          // 操作员id
    var paperTime: Date? = null,       // 单证时间

    // ==================== 备注与其他 ====================
    var remark: String? = null,        // 备注
    var ffmMemo: String? = null,       // ffm备注
    var mftMemo: String? = null,       // mft备注
    var unNumber: String? = null,      // UN编号
    var billsNo: String? = null,       // 提单号
    var recheckCount: Long? = null,    // 复核次数

    // ==================== 地区信息 ====================
    var proName: String? = null,       // 省份名称
    var cityName: String? = null,      // 城市名称
    var areaName: String? = null,      // 区域名称

    // ==================== 关联数据统计 ====================
    var haWbNumber: Int? = null,           // 分单数
    var storageUseNumber: Int? = null,     // 库位使用数

    // ==================== 活动标识 ====================
    var activeId: Long? = null,        // 有效值

    // ==================== 关联列表（非数据库字段，用于展示） ====================
    var haWbList: List<GjcHaWb>? = null,               // 分单列表
    var storageUseList: List<GjcStorageUse>? = null,   // 库位使用列表
    @Transient
    var attachList: List<ComAttach>? = null            // 附件列表
) {
    // ==================== UI扩展字段 ====================
    @Transient
    val checked: ObservableBoolean = ObservableBoolean(false)  // 选中状态
    @Transient
    val showMore: ObservableBoolean = ObservableBoolean(false) // 展开状态
    @Transient
    val actionMenuVisible: ObservableBoolean = ObservableBoolean(false) // 5.5寸手机版：卡片长按操作浮层显隐

    // 兼容现有API的isSelected属性
    var isSelected: Boolean
        get() = checked.get()
        set(value) = checked.set(value)

    /**
     * 5.5寸手机版：是否处于「待运抵」Tab（申报状态为空）。
     * 接口无按申报状态区分的查询参数，Tab 由客户端对已加载数据拆分。
     */
    val isPending: Boolean
        get() = declareStatus.isNullOrEmpty()

    /**
     * 5.5寸手机版：申报状态三色标签的着色分类（01=绿/W=靛蓝/其余非空=琥珀）。
     */
    val declareTagColor: String
        get() = when (declareStatus) {
            "01" -> "green"
            "W" -> "indigo"
            else -> if (declareStatus.isNullOrEmpty()) "" else "amber"
        }

    /**
     * 5.5寸手机版-出港查询：卡片状态标签。
     * 已离港 = 航班关闭时间（fclose）非空；已入库 = 入库时间（opDate）非空；都为空 = 未入库（灰）。
     * 接口无独立状态出参，此判定为前端推断（与卡片「入库时间/离港时间」两列同源）。
     */
    val isQueryDeparted: Boolean
        get() = !fclose.isNullOrEmpty()

    val isQueryStored: Boolean
        get() = !opDate.isNullOrEmpty()

    /** 5.5寸手机版：空值统一占位 "--"（空串与 null 都兜底，布局绑定用） */
    fun orDash(value: String?): String = if (value.isNullOrEmpty()) "--" else value

    /**
     * 5.5寸手机版：代理人展示值（名称优先，空则回退代码）。
     * 不能在 XML 里用 `??` 兜底——转换器会把 JSON null 归一成空串，`??` 只判 null 不判空串。
     */
    val agentDisplay: String?
        get() = if (agentName.isNullOrEmpty()) agentCode else agentName

    /**
     * 5.5寸手机版-出港仓库：卡片状态标签（已清仓=绿 / 未清仓=橙，clearNormal 为空视作未清仓）。
     * 已清仓时卡片「清仓」按钮置灰不可点。
     */
    val isCleared: Boolean
        get() = clearNormal == "1"

    // ==================== 状态转换扩展属性 ====================
    /**
     * 计重状态中文
     * 0-待收运，1-已计重，2-计重中
     */
    val checkInText: String
        get() = when (checkIn) {
            "0" -> "待收运"
            "1" -> "已计重"
            "2" -> "计重中"
            else -> checkIn ?: ""
        }

    /**
     * 运抵状态中文
     * 0-正常运抵，1-提前运抵
     */
    val arriveFlagText: String
        get() = when (arriveFlag) {
            "0" -> "正常运抵"
            "1" -> "提前运抵"
            else -> arriveFlag ?: ""
        }

    /**
     * 航班信息（格式化后）
     * 格式: yyyyMMdd/航班号
     * 示例: 20260108/MU2025
     */
    val flightInfo: String
        get() {
            val dateFormat = SimpleDateFormat("yyyyMMdd", Locale.getDefault())
            val formattedDate = fdate?.let { dateFormat.format(it) } ?: ""
            val flightNo = fno ?: ""
            return if (formattedDate.isNotEmpty() && flightNo.isNotEmpty()) {
                "$formattedDate/$flightNo"
            } else {
                flight ?: "" // 如果无法格式化，回退到原始flight字段
            }
        }

    /**
     * 航程
     * 优先取 range；为空时用 始发站-目的站 拼接
     */
    val rangeText: String
        get() {
            if (!range.isNullOrBlank()) return range!!
            val d1 = dep?.takeIf { it.isNotBlank() } ?: ""
            val d2 = dest?.takeIf { it.isNotBlank() } ?: ""
            return if (d1.isNotEmpty() && d2.isNotEmpty()) "$d1-$d2" else d1 + d2
        }

    /**
     * 航班日期（格式化）
     * 格式: yyyy-MM-dd
     */
    val flightDateText: String
        get() = fdate?.let { SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(it) } ?: ""

    /**
     * 清仓正常状态中文
     * 0-否，1-是
     */
    val clearNormalText: String
        get() = when (clearNormal) {
            "0" -> "否"
            "1" -> "是"
            else -> clearNormal ?: ""
        }
}

/**
 * 国际出港分单数据模型
 */
data class GjcHaWb(
    var haWbId: Long? = null,          // 主键ID
    var fid: Long? = null,             // 航班主键
    var prefix: String? = null,        // 前缀
    var no: String? = null,            // 编号
    var hno: String? = null,           // H编号
    var pc: Long? = null,              // PC数量
    var weight: Double? = null,        // 重量
    var volume: Double? = null,        // 体积
    var hpc: Long? = null,             // 分单数量
    var hweight: Double? = null,       // 分单重量
    var hvolume: Double? = null,       // 分单体积
    var goods: String? = null,         // 货物英文
    var goodsCn: String? = null,       // 货物中文
    var billsNo: String? = null,       // 提单号
    var opDate: Date? = null,          // 操作日期
    var opId: String? = null,          // 操作人ID
    var remark: String? = null,        // 备注
    // 发货人信息
    var consignorName: String? = null,         // 发货人名称
    var consignorCode: String? = null,         // 发货人代码
    var consignorAddress: String? = null,      // 发货人地址
    var consignorCountryCode: String? = null,  // 发货人国家代码
    var consignorComType: String? = null,      // 发货人公司类型
    var consignorPnum: String? = null,         // 发货人电话号码
    // 收货人信息
    var consigneeName: String? = null,         // 收货人名称
    var consigneeCode: String? = null,         // 收货人代码
    var consigneeAddress: String? = null,      // 收货人地址
    var consigneeCountryCode: String? = null,  // 收货人国家代码
    var consigneeComType: String? = null,      // 收货人公司类型
    var consigneePnum: String? = null,         // 收货人电话号码
    // 特殊收货人信息
    var speConsigneeName: String? = null,      // 特殊收货人名称
    var speConsigneeComType: String? = null,   // 特殊收货人公司类型
    var speConsigneePnum: String? = null,      // 特殊收货人电话号码
    // 申报状态
    var mftStatus: String? = null,             // 预配状态
    var mftMsgId: String? = null,              // 预配消息ID
    var arrivalStatus: String? = null,         // 运抵状态
    var arrMsgId: String? = null,              // 运抵消息ID
    var tallyStatus: String? = null,           // 理货状态
    var tallyMsgId: String? = null,            // 理货消息ID
    var transferStatus: String? = null,        // 传输状态
    var tranMsgId: String? = null,             // 传输消息ID
    var cmdStatus: String? = null,             // 命令状态
    var response: String? = null,              // 响应
    // 最后状态
    var lastMftStatus: String? = null,         // 最后预配状态
    var lastMftMsgId: String? = null,          // 最后预配消息ID
    var lastArrStatus: String? = null,         // 最后运抵状态
    var lastArrMsgId: String? = null,          // 最后运抵消息ID
    var lastTallyStatus: String? = null,       // 最后理货状态
    var lastTallyMsgId: String? = null,        // 最后理货消息ID
    // 费率计次
    var mftSRate: Double? = null,              // 预配申报费率
    var mftSCount: Double? = null,             // 预配申报计次
    var mftDRate: Double? = null,              // 预配删除费率
    var mftDCount: Double? = null,             // 预配删除计次
    var arrivalSRate: Double? = null,          // 运抵申报费率
    var arrivalSCount: Double? = null,         // 运抵申报计次
    var arrivalDRate: Double? = null,          // 运抵删除费率
    var arrivalDCount: Double? = null,         // 运抵删除计次
    var tallySRate: Double? = null,            // 出港理货申报费率
    var tallySCount: Double? = null,           // 出港理货申报计次
    var tallyDRate: Double? = null,            // 出港理货删除费率
    var tallyDCount: Double? = null,           // 出港理货删除计次
    // 操作信息
    var arrivalOpDate: Date? = null,           // 运抵操作日期
    var arrivalOpId: String? = null,           // 运抵操作人ID
    var tallyOpDate: Date? = null,             // 理货操作日期
    var tallyOpId: String? = null,             // 理货操作人ID
    var declareCount: Long? = null,            // 申报次数
    var activeId: Long? = null                 // 活动ID
) : Serializable {
    // ==================== UI扩展字段 ====================
    @Transient
    val checked: ObservableBoolean = ObservableBoolean(false)  // 选中状态
    @Transient
    val actionMenuVisible: ObservableBoolean = ObservableBoolean(false) // 5.5寸手机版：卡片长按操作浮层显隐

    // 兼容现有API的isSelected属性
    var isSelected: Boolean
        get() = checked.get()
        set(value) = checked.set(value)

    /**
     * 5.5寸手机版：申报状态三色标签的着色分类（01=绿/W=靛蓝/其余非空=琥珀）。
     * 与 GjcMaWb.declareTagColor 同源逻辑，作用于分单自身的 arrivalStatus。
     */
    val haWbTagColor: String
        get() = when (arrivalStatus) {
            "01" -> "green"
            "W" -> "indigo"
            else -> if (arrivalStatus.isNullOrEmpty()) "" else "amber"
        }

    /**
     * 5.5寸手机版「回执」页：运抵操作时间（格式化）。
     */
    val arrivalOpDateText: String
        get() = arrivalOpDate?.let {
            SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(it)
        } ?: ""
}

/**
 * 库位使用记录
 */
data class GjcStorageUse(
    var id: Long? = null,              // 主键
    var maWbId: Long? = null,          // 运单id
    var prefix: String? = null,        // 运单前缀
    var no: String? = null,            // 运单号
    var location: String? = null,      // 库位号
    var locationId: Long? = null,      // 库位id
    var storageCode: String? = null,   // 库位号(兼容字段)
    var uld: String? = null,           // 板箱号
    var inDate: String? = null,        // 入库时间
    var inOpId: String? = null,        // 入库人
    var inId: String? = null,          // 入库人(兼容字段)
    var outDate: String? = null,       // 出库时间
    var outOpId: String? = null,       // 出库人
    var outId: String? = null,         // 出库人(兼容字段)
    var cargoStatus: String? = null    // 货物状态
) {
    // ==================== UI扩展字段 ====================
    @Transient
    val checked: ObservableBoolean = ObservableBoolean(false)  // 选中状态

    // 兼容现有API的isSelected属性
    var isSelected: Boolean
        get() = checked.get()
        set(value) = checked.set(value)
}
