package cn.muchinfo.rma.business.contract.adapter

import cn.muchinfo.rma.business.contract.SpotContractInfo
import cn.muchinfo.rma.business.global.MessageHeadModel
import cn.muchinfo.rma.global.ErrorMessageUtils
import cn.muchinfo.rma.global.GlobalDataCollection
import cn.muchinfo.rma.netcore.packet.Packet50
import cn.muchinfo.rma.protobuf.funcode.FunCode
import cn.muchinfo.rma.protobuf.protoclasses.ErmcpMI1
import com.google.protobuf.ByteString
import java.io.ByteArrayOutputStream
import java.lang.Exception
import java.util.*

/**
 * 现货合同相关装解箱
 */
object ContractAdapter {


    /**
     * 获取新增采购合同报文
     * @param contractInfo SpotContractInfo 新增合同信息
     * @param OperateType String 操作类型-1:保存草稿2:提交申请3:审核通过4:审核拒绝5:撤回6:正常完结7:异常终止
     * @param Remark String 备注
     * @param SpotContractID String 现货合同ID(602+Unix秒时间戳(10位)+xxxxxx)
     * @return Packet50 采购合同报文
     */
    fun getContractReqInfo(
        contractInfo: SpotContractInfo = SpotContractInfo(),
        OperateType: String,
        Remark: String = "",
        SpotContractID: String = ""
    ): Packet50 {
        val builder = ErmcpMI1.SpotContractOperateReq.newBuilder()
        val contractInfobuilder = ErmcpMI1.SpotContractInfo.newBuilder()
        contractInfo.let {
            if (it.ContractNo.isNotEmpty()) {
                contractInfobuilder.contractNo = it.ContractNo
            }
            if (it.Amount != 0.0) {
                contractInfobuilder.amount = it.Amount
            }
            if (it.BrandID.isNotEmpty()) {
                contractInfobuilder.brandID = it.BrandID
            }
            if (it.BuyUserID != 0) {
                contractInfobuilder.buyUserID = it.BuyUserID
            }
            if (it.SellUserID != 0) {
                contractInfobuilder.sellUserID = it.SellUserID
            }
            if (it.UserID != 0) {
                contractInfobuilder.userID = it.UserID
            }
            if (it.ContractAttachment.isNotEmpty()) {
                contractInfobuilder.contractAttachment =
                    ByteString.copyFrom(it.ContractAttachment.toByteArray())
            }
            if (it.WrStandardID != 0) {
                contractInfobuilder.wrStandardID = it.WrStandardID
            }
            if (it.ContractMargin != 0.0) {
                contractInfobuilder.contractMargin = it.ContractMargin
            }
            if (it.ContractType != 0) {
                contractInfobuilder.contractType = it.ContractType
            }
            if (it.SpotGoodsDesc.isNotEmpty()) {
                contractInfobuilder.spotGoodsDescBytes =
                    ByteString.copyFrom(it.SpotGoodsDesc.toByteArray())
            }
            if (it.ConvertFactor != 0.0) {
                contractInfobuilder.convertFactor = it.ConvertFactor
            }
            if (it.DeliveryDesc.isNotEmpty()) {
                contractInfobuilder.deliveryDesc = it.DeliveryDesc
            }
            if (it.DeliveryEndDate.isNotEmpty()) {
                contractInfobuilder.deliveryEndDate = it.DeliveryEndDate
            }
            if (it.DeliveryGoodsID != 0) {
                contractInfobuilder.deliveryGoodsID = it.DeliveryGoodsID
            }
            if (it.DeliveryStartDate.isNotEmpty()) {
                contractInfobuilder.deliveryStartDate = it.DeliveryStartDate
            }
            if (it.EndDate.isNotEmpty()) {
                contractInfobuilder.endDate = it.EndDate
            }
            if (it.GoodsID != 0) {
                contractInfobuilder.goodsID = it.GoodsID
            }
            if (it.MerUserID != 0) {
                contractInfobuilder.merUserID = it.MerUserID
            }
            if (it.PointDesc.isNotEmpty()) {
                contractInfobuilder.pointDesc = it.PointDesc
            }
            if (it.Price != 0.0) {
                contractInfobuilder.price = it.Price
            }
            if (it.PriceMove != 0.0) {
                contractInfobuilder.priceMove = it.PriceMove
            }
            if (it.PriceType != 0) {
                contractInfobuilder.priceType = it.PriceType
            }
            if (it.PricedAmount != 0.0) {
                contractInfobuilder.pricedAmount = it.PricedAmount
            }
            if (it.PricedQty != 0.0) {
                contractInfobuilder.pricedQty = it.PricedQty
            }
            if (it.ProductType != 0) {
                contractInfobuilder.productType = it.ProductType
            }
            if (it.Qty != 0.0) {
                contractInfobuilder.qty = it.Qty
            }

        }

        val loginInfo = GlobalDataCollection.instance?.loginRsp!!
        // FIXME: - 250000000005
        builder.setHeader(
            MessageHeadModel.getHead(
                FunCode.SpotContractOperateReq,
                loginInfo.userID,
                GlobalDataCollection.instance?.accountId ?: 0,
                0,
                18
            )
        )
        builder.setClientTicket(UUID.randomUUID().toString().replace("-", ""))
        builder.operateType = OperateType.toInt()
        if (OperateType == "1" || OperateType == "2") {
            builder.info = contractInfobuilder.build()
        }
        builder.userID = loginInfo.loginID
        builder.remark = Remark
        builder.operateSrc = 2
        if (SpotContractID.isNotEmpty()) {
            builder.spotContractID = SpotContractID.toLong()
        }
        val arrayOutputStream = ByteArrayOutputStream();
        builder.build().writeTo(arrayOutputStream)
        return Packet50(FunCode.SpotContractOperateReq, arrayOutputStream.toByteArray())

    }

    /**
     * 新增采购合同报文解析
     * @param packet50 Packet50
     * @return Triple<Boolean, Error?, ErmcpMI1.SpotContractOperateRsp?>
     */
    fun analysisContractRsq(packet50: Packet50): Triple<Boolean, Error?, ErmcpMI1.SpotContractOperateRsp?> {
        return try {
            val loginRsp = ErmcpMI1.SpotContractOperateRsp.parseFrom(packet50.content)
            if (loginRsp.retCode == 0) {
                // 操作成功
                Triple(true, null, loginRsp)
            } else {
                // 操作失败
                Triple(false, Error(ErrorMessageUtils.getErrorString(loginRsp.retCode)), null)
            }
        } catch (e: Exception) {
            // 操作失败
            Triple(false, Error("装箱失败"), null)
        }
    }

    /**
     * 合同操作报文装箱
     * @param info ContractOperateApplyInfo
     * @param operateType Int
     * @param remark String
     * @param operateApplyID Long
     * @return Packet50
     */
    fun getPerationContractReqInfo(
        info: ErmcpMI1.ContractOperateApplyInfo,
        operateType: Int = 0,
        remark: String = "",
        operateApplyID: Long = 0
    ): Packet50 {
        val builder = ErmcpMI1.ContractOperateApplyReq.newBuilder()
        val loginInfo = GlobalDataCollection.instance?.loginRsp!!
        builder.setHeader(
            MessageHeadModel.getHead(
                FunCode.ContractOperateApplyReq,
                loginInfo.userID,
                GlobalDataCollection.instance?.accountId ?: 0,
                0,
                18
            )
        )
        builder.userID = loginInfo.loginID
        builder.remark = remark
        builder.operateType = operateType
        builder.setClientTicket(UUID.randomUUID().toString().replace("-", ""))
        builder.operateApplyID = operateApplyID
        builder.operateSrc = 2
        builder.info = info
        val arrayOutputStream = ByteArrayOutputStream()
        builder.build().writeTo(arrayOutputStream)
        return Packet50(FunCode.ContractOperateApplyReq, arrayOutputStream.toByteArray())
    }


    /**
     * 合同操作报文解析
     * @param packet50 Packet50
     * @return Triple<Boolean, Error?, ErmcpMI1.ContractOperateApplyRsp?>
     */
    fun analysisPerationContractRsq(packet50: Packet50) : Triple<Boolean, Error?, ErmcpMI1.ContractOperateApplyRsp?> {

        return try {
            val loginRsp = ErmcpMI1.ContractOperateApplyRsp.parseFrom(packet50.content)
            if (loginRsp.retCode == 0) {
                // 操作成功
                Triple(true, null, loginRsp)
            } else {
                // 操作失败
                Triple(false, Error(ErrorMessageUtils.getErrorString(loginRsp.retCode)), null)
            }
        } catch (e: Exception) {
            // 操作失败
            Triple(false, Error("装箱失败"), null)
        }
    }

}