package cn.muchinfo.rma.view.base.future.holds

import android.content.Context
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.MutableLiveData
import androidx.recyclerview.widget.RecyclerView
import cn.muchinfo.rma.R
import cn.muchinfo.rma.business.future.adapter.ChannelOrderReqData
import cn.muchinfo.rma.global.GlobalDataCollection
import cn.muchinfo.rma.global.data.futureOrders.DealOrderData
import cn.muchinfo.rma.global.data.futureOrders.FutureHoldData
import cn.muchinfo.rma.netManage.base.InteractiveException
import cn.muchinfo.rma.view.MyApplication
import cn.muchinfo.rma.view.autoWidget.onThrottleFirstClick
import cn.muchinfo.rma.view.autoWidget.utils.NumberUtils
import cn.muchinfo.rma.view.base.BaseViewModel
import cn.muchinfo.rma.view.base.app.FutureConstent
import cn.muchinfo.rma.view.base.future.costs.OrderDetailData
import cn.muchinfo.rma.view.base.future.orderDeatails.OrderDetail
import cn.muchinfo.rma.view.eventbus.EventConstent
import cn.muchinfo.rma.view.eventbus.TradeMessageEvent
import com.blankj.utilcode.util.TimeUtils
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import mtp.polymer.com.autowidget.dialog.createWarningDialog
import mtp.polymer.com.autowidget.utils.TaskUiModel
import org.greenrobot.eventbus.EventBus

/**
 * 持仓的ViewModel
 */
class HoldViewModel : BaseViewModel() {

    val holdLiveData: MutableLiveData<List<FutureHoldData>> = MutableLiveData() // 持仓单

    var list: ArrayList<FutureHoldData>? = null
    var marketID: String? = null
    var futureHoldData: FutureHoldData? = null // 当前选择的item对应的数据

    /**
     * 组装数据
     */
    fun makeCostInfo(data: FutureHoldData): ArrayList<OrderDetailData>? {
        val orderDetailList: ArrayList<OrderDetailData>? = ArrayList()
        val paddingLeft = 400 // 右侧的文字，距离左侧的距离
        val leftTextPadding = 0 // 左侧的文字，距离左侧的距离

        var m = OrderDetailData()
        m.setLeftText(context?.getString(R.string.str_unit_name))
        m.setRightText(data.goodsname)
        m.setRightTextPadding(paddingLeft)
        m.setLeftTextPadding(leftTextPadding)
        orderDetailList?.add(m)

        m = OrderDetailData()
        m.setLeftText(context?.getString(R.string.str_order_all_num))
        m.setRightText(data.curtdposition.toString() + "/" + data.curpositionqty)
        m.setRightTextPadding(paddingLeft)
        m.setLeftTextPadding(leftTextPadding)
        orderDetailList?.add(m)

        m = OrderDetailData()
        m.setLeftText(context?.getString(R.string.str_order_all_available))
        m.setRightText(data.curtdposition.toString() + "/" + data.enableqty)
        m.setRightTextPadding(paddingLeft)
        m.setLeftTextPadding(leftTextPadding)
        orderDetailList?.add(m)

        // 开仓均价
        m = OrderDetailData()
        m.setLeftText(context?.getString(R.string.str_ava_open))
        m.setRightText(data.openaverageprice.toString())
        m.setRightTextPadding(paddingLeft)
        m.setLeftTextPadding(leftTextPadding)
        orderDetailList?.add(m)

        m = OrderDetailData()
        m.setLeftText(context?.getString(R.string.str_ava_price))
        m.setRightText(data.positionaverageprice.toString())
        m.setRightTextPadding(paddingLeft)
        m.setLeftTextPadding(leftTextPadding)
        orderDetailList?.add(m)

        m = OrderDetailData()
        m.setLeftText(context?.getString(R.string.str_open_pl))
        m.setRightText(data.openpl.toString())
        m.setRightTextPadding(paddingLeft)
        m.setLeftTextPadding(leftTextPadding)
        orderDetailList?.add(m)

        m = OrderDetailData()
        m.setLeftText(context?.getString(R.string.str_hold_pl))
        m.setRightText(data.positionpl.toString())
        m.setRightTextPadding(paddingLeft)
        m.setLeftTextPadding(leftTextPadding)
        orderDetailList?.add(m)

//        m = OrderDetailData()
//        m.setLeftText(context?.getString(R.string.str_use_amount))
//        m.setRightText(data.usedmargin.toString())
//        m.setRightTextPadding(paddingLeft)
//        m.setLeftTextPadding(leftTextPadding)
//        orderDetailList?.add(m)

        m = OrderDetailData()
        m.setLeftText(context?.getString(R.string.str_exchange))
        m.setRightText(data.exexchangename)
        m.setRightTextPadding(paddingLeft)
        m.setLeftTextPadding(leftTextPadding)
        orderDetailList?.add(m)

        return orderDetailList
    }

    /**
     * 获取配置器。
     */
    fun getAdapter(fragment: Fragment): RecyclerView.Adapter<HoldAdapter.HoldHolder> {
        return HoldAdapter(context, fragment)
    }

    /**
     * 持仓汇总相关成交单适配器
     */
    inner class HoldAdapter(context: Context?, fragment: Fragment) :
        RecyclerView.Adapter<HoldAdapter.HoldHolder>() {
        private var list: ArrayList<FutureHoldData>? = null
        private var inflater: LayoutInflater? = null
        private var context: Context? = null
        private var pink: Drawable? = null
        private var green: Drawable? = null
        private var priceRed: Int = 0
        private var priceGreen: Int = 0
        private var priceBlack: Int = 0
        private var fragment: Fragment? = null
        private var refreshByQuote: Boolean = false
        var futureHoldData: FutureHoldData? = null // 当前选择的item对应的数据

        init {
            this.list = GlobalDataCollection.instance?.futureHoldData
            this.inflater = LayoutInflater.from(context)
            this.context = context
            this.fragment = fragment
            pink = context?.getDrawable(R.drawable.rma_red)
            green = context?.getDrawable(R.drawable.rma_green)
            priceGreen = context?.getColor(R.color.p_price_green)!!
            priceRed = context.getColor(R.color.p_price_red)
            priceBlack = context.getColor(R.color.rma_black_33)
        }

        override fun getItemCount(): Int {
            return list?.size ?: 0
        }

        fun update(list: ArrayList<FutureHoldData>?) {
            this.list = list
            notifyDataSetChanged()
        }

        //刷新item是否是由于行情推送
        fun updateByQuote(refreshByQuote: Boolean) {
            this.refreshByQuote = refreshByQuote
        }

        inner class HoldHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!) {
            var idGoodsName = itemView?.findViewById<TextView>(R.id.id_goods_name) // 商品名称
            var idTransDirection = itemView?.findViewById<TextView>(R.id.id_trans_direction) // 方向
            var idAvailable = itemView?.findViewById<TextView>(R.id.id_available) // 可用
            var idHoldTotal = itemView?.findViewById<TextView>(R.id.id_hold_total) // 持仓
            var idOpenAveragePrice =
                itemView?.findViewById<TextView>(R.id.id_open_average_price) // 开仓均价
            var idHoldAveragePrice =
                itemView?.findViewById<TextView>(R.id.id_hold_average_price) // 持仓均价
            var idZPl = itemView?.findViewById<TextView>(R.id.id_zpl) // 盯市浮盈
            var idPlp = itemView?.findViewById<TextView>(R.id.id_plp) // 盈亏比例
            var id_pl = itemView?.findViewById<TextView>(R.id.id_pl)//逐笔浮盈
            var idMargin = itemView?.findViewById<TextView>(R.id.id_margin) // 保证金

            var quick_backhand = itemView?.findViewById<TextView>(R.id.quick_backhand)//快捷反手
            var key_positions = itemView?.findViewById<TextView>(R.id.key_positions)//一键平仓
            var id_chart = itemView?.findViewById<TextView>(R.id.id_chart)//图表
            var id_entrust_detail = itemView?.findViewById<TextView>(R.id.id_entrust_detail)//详情
        }

        override fun onBindViewHolder(holder: HoldHolder, position: Int) {
            holder.itemView.tag = list?.get(position)
            val itemData = list?.get(position)
            holder.idGoodsName?.text = itemData?.goodsname
            holder.idAvailable?.text = itemData?.enableqty.toString() // 可用（总仓可用）
            holder.idHoldTotal?.text = itemData?.curpositionqty.toString() // 持仓（总仓数量, 期末头寸）
            holder.idOpenAveragePrice?.text =
                itemData?.openaverageprice.toString()//开仓均价【头寸变化更新】 = 开仓成本 / 期末头寸 / 合约单位
            holder.idHoldAveragePrice?.text =
                itemData?.positionaverageprice.toString()//持仓均价【头寸变化更新】= 持仓成本 / 期末头寸 / 合约单位
            holder.idMargin?.text = itemData?.usedmargin.toString()//占用保证金

            if (refreshByQuote) {//行情下发的推送则自己算一遍
                /**
                 * 获取基本信息(主要计算持仓浮动盈亏和平仓浮动盈亏)
                 * 盯市浮盈【实时行情更新】（MTP：浮动盈亏、持仓盈亏） 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位；卖方向 = (持仓均价 - 最新价) * 卖期末头寸 * 合约单位
                 * 逐笔浮盈【实时行情更新】（MTP：开仓盈亏、平仓盈亏） 买方向 = (最新价 - 开仓均价) * 买期末头寸 * 合约单位；卖方向 = (开仓均价 - 最新价) * 卖期末头寸 * 合约单位
                 */
                val quoteData =
                    GlobalDataCollection.instance?.goodsInfoAndQuotesList?.find { itemData?.outgoodscode == it.outgoodscode }
                if (quoteData != null) {
                    itemData?.calculate()
                    holder.idZPl?.text =
                        NumberUtils.roundNum(itemData?.positionpl.toString(), 2)
                    holder.idPlp?.text =
                        itemData?.positionplrate?.times(100.0)
                            ?.let { NumberUtils.roundNum(it, 2) + "%" }
                    holder.id_pl?.text =
                        NumberUtils.roundNum(itemData?.openpl.toString(), 2)
                } else {
                    holder.idZPl?.text =
                        NumberUtils.roundNum(itemData?.positionpl.toString(), 2)
                    holder.idPlp?.text = itemData?.positionplrate?.times(100.0)
                        ?.let { NumberUtils.roundNum(it, 2) + "%" }
                    holder.id_pl?.text =
                        NumberUtils.roundNum(itemData?.openpl.toString(), 2)
                }
            } else {//第一次请求则直接拿go服务给的值
                holder.idZPl?.text =
                    NumberUtils.roundNum(itemData?.positionpl.toString(), 2)
                holder.idPlp?.text = itemData?.positionplrate?.times(100.0)
                    ?.let { NumberUtils.roundNum(it, 2) + "%" }
                holder.id_pl?.text =
                    NumberUtils.roundNum(itemData?.openpl.toString(), 2)
            }

            if (itemData?.positionpl == 0.0) {
                holder.idZPl?.setTextColor(priceBlack)
                holder.idPlp?.setTextColor(priceBlack)
                holder.id_pl?.setTextColor(priceBlack)
            } else if (itemData?.positionpl ?: 0.0 > 0) {
                holder.idZPl?.setTextColor(priceRed)
                holder.idPlp?.setTextColor(priceRed)
                holder.id_pl?.setTextColor(priceRed)
            } else if (itemData?.positionpl ?: 0.0 < 0) {
                holder.idZPl?.setTextColor(priceGreen)
                holder.idPlp?.setTextColor(priceGreen)
                holder.id_pl?.setTextColor(priceGreen)
            }

            if (list?.get(position)?.buyorsell == 0) {
                holder.idTransDirection?.text = context?.resources?.getString(R.string.str_buy)
                holder.idTransDirection?.setTextColor(priceRed)
            } else {
                holder.idTransDirection?.text = context?.resources?.getString(R.string.str_sell)
                holder.idTransDirection?.setTextColor(priceGreen)
            }

            /** 快捷反手 */
            holder.quick_backhand?.onThrottleFirstClick {
                fragment?.createWarningDialog {
                    setTitle("快捷反手确认")
                    setMessage("确认将该合约的所有持仓进行快捷反手操作？")
                    addAction("取消") { dialog, _ -> dialog.dismiss() }
                    addAction("确定") { dialog, _ ->
                        commitDealData(true, true)
                        dialog.dismiss()
                    }
                }?.show()
            }

            /** 一键平仓 **/
            holder.key_positions?.onThrottleFirstClick {
                fragment?.createWarningDialog {
                    setTitle("快捷反手确认")
                    setMessage("确认将该合约的所有持仓进行快捷反手操作？")
                    addAction("取消") { dialog, _ -> dialog.dismiss() }
                    addAction("确定") { dialog, _ ->
                        commitDealData(false, true)
                        dialog.dismiss()
                    }
                }?.show()

            }

            /** 图表 **/
            holder.id_chart?.onThrottleFirstClick {

            }

            /** 详情 **/
            holder.id_entrust_detail?.tag = itemData
            holder.id_entrust_detail?.onThrottleFirstClick {
                val tagData = it?.tag as FutureHoldData
                val data = makeCostInfo(tagData)
                OrderDetail.start(
                    context!!,
                    data,
                    context?.resources?.getString(R.string.str_order_detail_head),
                    tagData.goodsid,
                    tagData.buyorsell
                )
            }

            if (list?.get(position)?.selected == true) {
                holder.quick_backhand?.visibility = View.VISIBLE
                holder.key_positions?.visibility = View.VISIBLE
                holder.id_chart?.visibility = View.VISIBLE
                holder.id_entrust_detail?.visibility = View.VISIBLE
            } else if (list?.get(position)?.selected == false) {
                holder.quick_backhand?.visibility = View.GONE
                holder.key_positions?.visibility = View.GONE
                holder.id_chart?.visibility = View.GONE
                holder.id_entrust_detail?.visibility = View.GONE
            }

            holder.itemView.onThrottleFirstClick {
                clickItem(it!!)
                val data = list?.get(position)
                EventBus.getDefault().post(
                    TradeMessageEvent(
                        messageType = EventConstent.TRADEGOODSID,
                        goodsId = data?.goodsid.toString(),
                        buyOrSell = data?.buyorsell ?: 0,
                        outGoodsCode = data?.outgoodscode ?: ""
                    )
                )
            }

        }

        private fun clickItem(view: View) {
            futureHoldData = view.tag as FutureHoldData? // 临时存储当前点击item

            // 选择i
            list?.forEach { itemValue ->
                if (itemValue.goodsid == futureHoldData?.goodsid) {
                    if (itemValue.buyorsell == futureHoldData?.buyorsell) {
                        itemValue.selected = !itemValue.selected
                    } else {
                        itemValue.selected = false
                    }
                } else {
                    itemValue.selected = false
                }
            }
            // 刷新数据
            notifyDataSetChanged()
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HoldHolder {
            return HoldHolder(inflater?.inflate(R.layout.hold_item, parent, false))
        }

        /**
         * 操作请求
         * @param isClose Boolean 是否是平仓单
         */
        fun commitDealData(isBackHand: Boolean, isClose: Boolean) {
            (fragment as HoldFragment).loadingDialogStatus.postValue(TaskUiModel.inFlight())
            var tradePrice = 0.0 //交易价格
            var itemData: FutureHoldData
            if (isClose) {
                itemData = futureHoldData ?: FutureHoldData()
            } else {
                itemData = GlobalDataCollection.instance?.itemData ?: FutureHoldData()
            }
            val datas = ChannelOrderReqData()
            datas.setAccountID(GlobalDataCollection.instance?.accountId ?: 0) // 交易账号
            val goodsQuote = GlobalDataCollection.instance?.goodsInfoAndQuotesList?.find {
                it.outgoodscode == itemData.outgoodscode
            }
            if (isClose) {
                if (itemData.buyorsell == 0) {
                    //平仓---平买单，方向是卖
                    datas.setBuyOrSell(1)
                } else {
                    //平仓---平卖单，方向是买
                    datas.setBuyOrSell(0)
                }
            } else {
                if (itemData.buyorsell == 0) {
                    //平仓---平买单，方向是卖
                    datas.setBuyOrSell(1)
                } else {
                    //平仓---平卖单，方向是买
                    datas.setBuyOrSell(0)
                }
            }
            //在fragment内设置一个变量用来控制是否在平仓后再进行建仓/且把用来反手建仓的数据暂存在数据中心
            if (isBackHand) {
                GlobalDataCollection.instance?.setItemData(itemData)
                (fragment as HoldFragment).isBackhandByLose = 1
            } else {
                (fragment as HoldFragment).isBackhandByLose = 0
            }
            datas.clientOrderTime = TimeUtils.getNowString() // 客户端委托时间  当前时间
            datas.clientType = 3 // 客户端类型: 1客户端  3 手机端 android
            datas.goodsID = itemData.goodsid ?: 0//商品id
            datas.loginID = GlobalDataCollection.instance?.loginRsp?.loginID ?: 0 //登录账号

            datas.marketID = itemData.marketid ?: 0
            datas.validType = 1 // 有效类型-1当日有效
            datas.channelOperateType =
                FutureConstent.ChannelOperateType_ORDER // 操作类型  1:正常类型  默认写死？？？
            datas.channelOrderSrc = 1 // 单据来源委托来源-1:客户端  //默认写死？
            datas.hedgeFlag = 0 // 投机套保标志-0:无
            if (goodsQuote?.quoteDayData != null) {
                val decial = goodsQuote.goodsInfo.decimalplace
                val setp: Double
                setp = goodsQuote.goodsInfo.quoteminunit * Math.pow(
                    10.0,
                    -decial.toDouble()
                )
                val askLimitPrice: String =
                    NumberUtils.roundNum(goodsQuote.quoteDayData.ask + setp /*limitStep*/, decial)
                val bidLimitPrice: String = NumberUtils.roundNum(
                    goodsQuote.quoteDayData.bid - setp /*limitStep*/, decial
                )
                if (itemData.buyorsell == 0) {
                    tradePrice = bidLimitPrice.toDouble()
                } else {
                    tradePrice = askLimitPrice.toDouble()
                }
            }
            datas.orderPrice = tradePrice
            datas.orderQty = itemData.enableqty?.toLong() ?: 0

            if (isClose) {
                // 平仓
                datas.closeType = 2
                datas.channelBuildType = FutureConstent.eChannelBuildType_CLOSE // 下单类型  建仓还是平仓
            } else {
                // 买卖建仓
                datas.closeType = 1
                datas.channelBuildType = FutureConstent.eChannelBuildType_OPEN // 下单类型  建仓还是平仓
            }
            datas.priceMode = FutureConstent.PriceMode_PRICEMODE_LIMIT // 限价
            datas.setTimeValidType(FutureConstent.ValidTypeEnum_VALIDTYPE_DR) // 时间有效类型   默认写死当日有效
            datas.setRelatedID(0) // 关联单号 默认写死
            datas.setServiceTime("") //服务端时间string
            datas.setValidtime("") // 有效时间string

            GlobalScope.launch {
                MyApplication.getInstance()?.futureManager?.tradeRequest(data = datas) { isCompleted, err ->
                    if (isCompleted) {
                        if ((fragment as HoldFragment).isBackhandByLose == 1) {
                            commitDealData(false, false)
                        } else {
                            (fragment as HoldFragment).loadingDialogStatus.postValue(
                                TaskUiModel.success(
                                    msg = "请求成功"
                                )
                            )
                            (fragment as HoldFragment).onRefresh()
                        }
                    } else {
                        (fragment as HoldFragment).loadingDialogStatus.postValue(
                            TaskUiModel.failed(
                                InteractiveException(errorMessage = err?.message!!)
                            )
                        )
                    }
                }
            }
        }


    }

    /**
     * 查询持仓单
     */
    fun queryHold() {
        val params = mutableMapOf<String, String>()
        params["accountID"] = GlobalDataCollection.instance?.accountId.toString()
//        if (marketID != null) {
//            params["marketID"] = marketID!!
//        }
        MyApplication.getInstance()?.futureManager?.queryErmcpTradePosition(params) { isSuccess, respData, _ ->
            if (isSuccess && !respData!!.isNullOrEmpty()) {
                list = respData as ArrayList<FutureHoldData>
                holdLiveData.value = list
            } else {
                // 没有数据或者接口返回错误的时候，通知界面没有获取到数据

            }
        }
    }

}