<template>
  <!-- 期货交易、套保交易 -->
  <Drawer class="top dialog-trade" :title="(isSpotContract || isHedgePlan) ? '套保交易' : '期货交易'" placement="right"
    :visible="visible" @cancel="cancel">
    <div class="futures_trade">
      <div class="futures_trade__left">
        <div class="futures_trade__form">
          <a-form class="inlineForm" ref="formRef" :model="formData" :rules="rules">
            <a-form-item label="合同编号" style="margin-bottom:10px" v-if="isSpotContract">
              <span class="white">{{ selectedRow.contractno }}</span>
            </a-form-item>
            <a-form-item label="计划编号" style="margin-bottom:10px" v-if="isHedgePlan">
              <span class="white">{{ selectedRow.hedgeplanno }}</span>
            </a-form-item>
            <template v-if="isSpotContract">
              <a-form-item label="已定价量" style="margin-bottom:10px">
                <span class="white">{{ Number(contractMiddleGoodsCfg.middlegoodspricedqty3).toFixed(2) }}</span>
              </a-form-item>
              <a-form-item label="已关联量" style="margin-bottom:10px">
                <span class="white">{{ contractMiddleGoodsCfg.relatedmiddlegoodsqty }}</span>
              </a-form-item>
              <a-form-item label="待点价量" style="margin-bottom:10px">
                <span class="white">{{ Math.trunc(contractMiddleGoodsCfg.pendingpricedqty) }}({{
                    Math.trunc(contractMiddleGoodsCfg.covertqty)
                }}手)</span>
              </a-form-item>
            </template>
            <a-form-item label="账号" name="AccountID">
              <a-select class="inlineFormSelect" placeholder="请选择账号" v-model:value="formData.AccountID">
                <a-select-option v-for="item in accountList" :value="item.accountid" :key="item.accountid">
                  {{ item.accountid }}/{{ item.accountname }}</a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="合约" name="GoodsID">
              <a-select class="inlineFormSelect" placeholder="请选择合约" :filterOption="filterOption"
                v-model:value="formData.GoodsID" @change="goodsChange" show-search>
                <a-select-option v-for="item in goodsList" :value="item.goodsid" :key="item.goodsid">{{ item.goodsname
                }}</a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="价格类型">
              <a-select class="inlineFormSelect" placeholder="请选择价格类型" v-model:value="selectedPriceType"
                @change="priceTypeChange">
                <a-select-option v-for="item in priceTypeList" :value="item.priceType" :key="item.priceType">{{
                    item.priceName
                }}</a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item class="inputIconBox" label="交易价格" name="OrderPrice">
              <!-- 限价可修改 -->
              <template v-if="selectedPriceType === 3">
                <a-input-number class="commonInput" v-model:value="formData.OrderPrice" style="width:100%" />
                <!-- <MinusOutlined />
                <PlusOutlined /> -->
              </template>
              <template v-else>
                <a-input-number class="commonInput" :value="selectedGoods?.last ?? 0" style="width:100%" disabled />
              </template>
            </a-form-item>
            <a-form-item class="inputIconBox" label="交易数量" name="OrderQty">
              <a-input-number class="commonInput" :precision="0" :min="1" v-model:value="formData.OrderQty"
                style="width:100%" />
              <MinusOutlined @click="minusQty" />
              <PlusOutlined @click="plusQty" />
            </a-form-item>
          </a-form>
        </div>
        <div class="futures_trade__submit">
          <!--现货销售合同、计划采购合同 显示按钮-->
          <a-button class="buy" :loading="loading" @click="submit('buy')"
            v-if="(!isSpotContract && !isHedgePlan) || (isSpotContract && selectedRow.contracttype === -1) || (isHedgePlan && selectedRow.contracttype === 1)">
            <span>{{ buyPrice }}</span>
            <span>买入</span>
          </a-button>
          <!--现货采购合同、计划销售合同 显示按钮-->
          <a-button class="sell" :loading="loading" @click="submit('sell')"
            v-if="(!isSpotContract && !isHedgePlan) || (isSpotContract && selectedRow.contracttype === 1) || (isHedgePlan && selectedRow.contracttype === -1)">
            <span>{{ sellPrice }}</span>
            <span>卖出</span>
          </a-button>
          <a-button class="close" :loading="loading" @click="submit('close')" :disabled="positionList.length === 0">
            <!--根据持仓方向显示平仓价格-->
            <span v-if="selectedPosition">{{ selectedPosition.buyorsell === BuyOrSell.buy ? sellPrice : buyPrice
            }}</span>
            <span>平仓</span>
          </a-button>
        </div>
        <div class="futures_trade__table tableDatas" v-show="positionList.length">
          <a-table class="dialogTable" :columns="getColumns()" :data-source="positionList"
            :rowKey="(record, index) => index" :pagination="false"
            :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type: 'radio' }"></a-table>
        </div>
      </div>
      <div class="futures_trade__right"></div>
    </div>
  </Drawer>
</template>

<script lang="ts">
import APP from '@/services';
import { Systemparam } from '@/services/go/useInfo/interface';
import { Des } from '@/common/components/commonDes';
import Drawer from '@/common/components/drawer/index.vue';
import { _closeModal } from '@/common/setup/modal/modal';
import { MinusOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { defineComponent, ref, computed, PropType } from 'vue';
import { handleForm, getColumns } from './setup';
import { channelOrderReq } from '@/services/proto/futures';
import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
import { BuyOrSell, BuildType, PriceType } from '@/common/constants/enumCommon';
import { validateAction } from '@/common/setup/form';
import { GoodsQuote } from '@/services/go/ermcp/goodsInfo/interface';
import { QueryErmcpTradePositionRsp } from '@/services/go/ermcp/futures/interface';
import { Ermcp3SellBuyContract } from '@/services/go/ermcp/purchase/interface';
import { getGoodsQuoteList } from '@/services/bus/goods';
import { useTradeAccount } from '@/hooks/account';
import { message } from 'ant-design-vue';
import { ErmcpRealExposureModel } from '@/services/go/ermcp/exposure/interface';
import { queryExposureGoods } from '@/services/go/ermcp/exposure'
import { Ermcp3HedgePlan } from '@/services/go/ermcp/plan/interface';
import { GetDeliveryGoodsDetail } from "@/services/go/ermcp/goodsInfo";
import { queryErmcp3ContractMiddleGoodsCfg } from '@/services/go/ermcp/spot-contract'
import { QueryErmcp3ContractMiddleGoodsCfgRsp } from '@/services/go/ermcp/spot-contract/interface';
import { queryRelatedTaAccount } from '@/services/go/TaAccount';
import { QueryRelatedTaAccountRsp } from "@/services/go/TaAccount/interface";
import { Ermcp2HedgedItemRsp } from '@/services/go/ermcp/hedgedItem/interface'

export default defineComponent({
  emits: ['cancel', 'update'],
  name: 'trader',
  components: { Des, Drawer, PlusOutlined, MinusOutlined },
  props: {
    selectedRow: {
      type: Object as PropType<GoodsQuote & QueryErmcpTradePositionRsp & Ermcp3SellBuyContract & Ermcp3HedgePlan & ErmcpRealExposureModel & Ermcp2HedgedItemRsp>,
      default: () => ({}),
    },
  },
  setup(props, context) {
    const { visible, cancel } = _closeModal(context);
    const { tradeuserid, goodsid, spotcontractid, hedgeplanid, deliverygoodsid, wrstandardid, goodsgroupid, MiddleGoodsID, hedgeditemid } = props.selectedRow;
    const { rules, formData } = handleForm();
    const formRef = ref();
    const loading = ref<boolean>(false);

    // 现货合同期现配置信息
    const contractMiddleGoodsCfg = ref<QueryErmcp3ContractMiddleGoodsCfgRsp>({
      middlegoodspricedqty3: '0',
      relatedmiddlegoodsqty: '0',
      pendingpricedqty: '0',
      covertqty: 0
    });
    const relatedTaAccountList = ref<QueryRelatedTaAccountRsp[]>([]);
    // 合约列表
    const goodsList = ref(getGoodsQuoteList());
    // 当前选中的商品合约
    const selectedGoods = ref<GoodsQuote>();
    // 是否现货合同 (根据参数 spotcontractid 来判断)
    const isSpotContract = Boolean(spotcontractid);
    // 是否购销计划 (根据参数 hedgeplanid 来判断)
    const isHedgePlan = Boolean(hedgeplanid);
    // 是否实时敞口 (根据参数 MiddleGoodsID 来判断)
    const isExposure = Boolean(MiddleGoodsID);
    // 是否套期项目 (根据参数 hedgeditemid 来判断)
    const isHedgedItem = Boolean(hedgeditemid);

    // 现货合同
    if (isSpotContract) {
      goodsList.value = goodsList.value.filter((e) => e.goodsgroupid === goodsgroupid);

      queryErmcp3ContractMiddleGoodsCfg({ spotcontractid }).then((res) => {
        contractMiddleGoodsCfg.value = res[0];
      })

      queryRelatedTaAccount({ relateduserid: tradeuserid }).then((res) => {
        relatedTaAccountList.value = res;
      })
    }

    // 实时敞口
    if (isExposure) {
      queryExposureGoods({ middlegoodsid: MiddleGoodsID }).then((res) => {
        const ids = res.map((e) => e.goodsid);
        goodsList.value = goodsList.value.filter((e) => ids.includes(e.goodsid));

        if (goodsList.value.length) {
          formData.GoodsID = goodsList.value[0].goodsid;
          goodsChange(formData.GoodsID); // 默认选中第一个
        }
      }).catch(() => {
        goodsList.value = [];
      })
    } else {
      // 购销计划、套期项目
      if (isHedgePlan || isHedgedItem) {
        if (deliverygoodsid) {
          GetDeliveryGoodsDetail(deliverygoodsid).then((res) => {
            const ids: number[] = [];
            const deliveryGoodsList = res.filter((e) => e.isvalid);

            deliveryGoodsList.forEach((dg) => {
              const wd = dg.wdlst.find((e) => e.wrstandardid === wrstandardid);
              if (wd) {
                wd.mglst.forEach((mg) => {
                  mg.GPLST.forEach((gp) => {
                    ids.push(...gp.GDLST.map((e) => e.goodsid));
                  })
                })
              }
            })

            const tmpList = goodsList.value.filter((e) => ids.includes(e.goodsid));
            if (tmpList.length) {
              goodsList.value = tmpList;
              formData.GoodsID = tmpList[0].goodsid;
              goodsChange(formData.GoodsID); // 默认选中第一个
            }
          })
        }
      } else {
        const item = goodsList.value.find((e) => e.goodsid === goodsid);
        if (!item) {
          message.error('合约不存在，不能交易！');
          cancel();
        } else {
          selectedGoods.value = item;
          formData.GoodsID = item.goodsid;
          formData.MarketID = item.marketid;
        }
      }
    }

    const { futuresAccountList, tradeAccountList } = useTradeAccount();
    // 表格选中的 rowKey 数据 :rowKey="(record,index)=>index"
    const selectedRowKeys = ref<number[]>([]);
    // 当前选择的持仓单据
    const selectedPosition = ref<QueryErmcpTradePositionRsp>();
    // 选择持仓
    const onSelectChange = (keys: number[], record: QueryErmcpTradePositionRsp[]) => {
      selectedRowKeys.value = keys;
      selectedPosition.value = record[0];
      const { enableqty, positionaverageprice } = record[0];
      // 更新价格和数量
      formData.OrderPrice = positionaverageprice;
      formData.OrderQty = enableqty;
    };

    // 账户列表
    const accountList = computed(() => {
      if (isSpotContract) {
        const tmpList = futuresAccountList.value.filter((e) => relatedTaAccountList.value.some((a) => a.accountid === e.accountid));
        if (tmpList.length) {
          formData.AccountID = tmpList[0].accountid;
        } else {
          formData.AccountID = undefined;
        }
        return tmpList;
      }
      return futuresAccountList.value;
    })

    // 选中的账户
    const selectedAccount = computed(() => tradeAccountList.find((e) => e.accountid === formData.AccountID));

    // 持仓列表
    const positionList = computed(() => {
      const positionList = selectedAccount.value?.positionList;

      if (positionList && selectedGoods.value) {
        const { goodscode, goodsid } = selectedGoods.value;
        // 判断是否现货合同交易
        if (isSpotContract) {
          // 买卖方向，根据合同类型判断
          const buyorsell = props.selectedRow.contracttype === 1 ? BuyOrSell.buy : BuyOrSell.sell;
          const index = positionList.findIndex((item) => item.goodscode === goodscode && item.goodsid === goodsid && item.buyorsell === buyorsell);
          if (index > -1) {
            const result = [positionList[index]];
            onSelectChange([0], result);
            return result;
          }
        } else {
          // 过滤出当前商品的持仓单据
          const result = positionList.filter((item) => item.goodsid === goodsid);
          // 查找选中的持仓单据
          const index = result.findIndex((item) => item.goodscode === goodscode && item.buyorsell === props.selectedRow.buyorsell);
          if (index > -1) {
            onSelectChange([index], [result[index]])
          }
          return result;
        }
      }
      return [];
    });
    // 选中的价格类型
    const selectedPriceType = ref(1);
    // 价格类型列表
    const priceTypeList = [
      // {
      //     priceType: 0,
      //     priceName: '最新价',
      // },
      {
        priceType: 1,
        priceName: '市价',
      },
      // {
      //     priceType: 2,
      //     priceName: '对手价',
      // },
      {
        priceType: 3,
        priceName: '限价',
      },
      // {
      //     priceType: 4,
      //     priceName: '超价',
      // },
    ];

    // 买价
    const buyPrice = computed(() => getPrice(BuyOrSell.buy));
    // 卖价
    const sellPrice = computed(() => getPrice(BuyOrSell.sell));
    // 根据买卖方向返回价格
    function getPrice(direction: BuyOrSell): number {
      if (selectedGoods.value) {
        const { last, bid, ask, decimalplace, quoteminunit } = selectedGoods.value;
        switch (selectedPriceType.value) {
          // 最新价
          case 0: {
            return last;
          }
          // 市价
          case 1: {
            return direction === BuyOrSell.buy ? ask : bid;
          }
          // 对手价
          case 2: {
            return direction === BuyOrSell.buy ? ask : bid;
          }
          // 限价
          case 3: {
            return formData.OrderPrice;
          }
          // 超价
          case 4: {
            if (ask && bid) {
              // 系统参数
              const paramValue = APP.get('systemParams').find((el: Systemparam) => el.paramcode === '148')?.paramvalue ?? '0';
              // 点数
              const point = decimalplace > 0 ? -decimalplace * quoteminunit * Number(paramValue) : 1;
              const num = Math.pow(10, point);
              return direction === BuyOrSell.buy ? ask + num : bid - num;
            }
            return 0;
          }
          default: {
            return 0;
          }
        }
      }
      return 0;
    }

    // 搜索商品合约
    function filterOption(input: string, option: any) {
      return option.children[0].children.includes(input);
    }

    // 选择商品合约
    function goodsChange(id: number) {
      const item = goodsList.value.find((e) => e.goodsid === id)!;
      formData.OrderPrice = 0;
      formData.OrderQty = 1;
      formData.MarketID = item.marketid;
      selectedRowKeys.value = [];
      selectedPosition.value = undefined;
      selectedGoods.value = item;
    }

    // 选择价格类型
    function priceTypeChange(priceType: number) {
      // 除了市价，其它价格类型都属于限价
      if (priceType === 1) {
        formData.PriceMode = PriceType.market;
        formRef.value.clearValidate('OrderPrice');
      } else {
        formData.PriceMode = PriceType.limit;
      }
    }

    // 减少交易数量
    function minusQty() {
      if (formData.OrderQty > 1) {
        formData.OrderQty--;
      }
    }

    // 增加交易数量
    function plusQty() {
      formData.OrderQty++;
    }

    function submit(submitType: 'buy' | 'sell' | 'close') {
      let successMsg = '成功';
      let failMsg = '失败';

      // 判断是否现货合同交易
      if (isSpotContract) {
        const { saleuserid, bizsubjectid } = props.selectedRow;
        formData.HedgeFlag = 4;
        formData.SaleUserID = saleuserid;
        formData.SpotContractID = spotcontractid;
        formData.BizSubjectID = bizsubjectid;
      }

      // 判断是否购销计划交易，任务 #3645
      if (isHedgePlan) {
        formData.HedgeFlag = 9;
        formData.SpotContractID = hedgeplanid;
      }

      // 判断是否套期项目
      if (isHedgedItem) {
        formData.HedgeFlag = 13;
        formData.SpotContractID = hedgeditemid;
      }

      // 按钮提交类型
      switch (submitType) {
        case 'buy': {
          successMsg = '买入委托成功';
          failMsg = '买入委托失败';
          formData.BuyOrSell = BuyOrSell.buy;
          formData.ChannelBuildType = BuildType.open;
          formData.OrderPrice = buyPrice.value;
          break;
        }
        case 'sell': {
          successMsg = '卖出委托成功';
          failMsg = '卖出委托失败';
          formData.BuyOrSell = BuyOrSell.sell;
          formData.ChannelBuildType = BuildType.open;
          formData.OrderPrice = sellPrice.value;
          break;
        }
        case 'close': {
          successMsg = '平仓委托成功';
          failMsg = '平仓委托失败';

          if (!selectedPosition.value) {
            message.error('请选择需要平仓的单据');
            return;
          }

          // 选中的单据数据
          const { curpositionqty, curtdpositionenabled, buyorsell } = selectedPosition.value;

          // 判断平仓数量
          if (formData.OrderQty > curpositionqty) {
            message.error('交易数量不能大于持仓可用数量');
            return;
          }

          formData.BuyOrSell = buyorsell === BuyOrSell.buy ? BuyOrSell.sell : BuyOrSell.buy; // 根据持仓方向选择平仓方向
          formData.OrderPrice = buyorsell === BuyOrSell.buy ? sellPrice.value : buyPrice.value; // 根据持仓方向选择平仓价格
          formData.ChannelBuildType = BuildType.close;

          // 判断是否母账号
          if (selectedAccount.value?.ismain) {
            if (selectedGoods.value?.outerdealmode === 3 && curtdpositionenabled > 0) {
              formData.CloseTodayQty = curtdpositionenabled;
            }
          }
          break;
        }
      }
      // 表单验证
      validateAction(formRef, formData).then((res) => {
        requestResultLoadingAndInfo(channelOrderReq, res, loading, [successMsg, failMsg]).then(() => {
          window.setTimeout(() => {
            loading.value = true;
            cancel(true);
          }, 1000)
        })
      })
    }

    return {
      submit,
      cancel,
      loading,
      visible,
      accountList,
      positionList,
      contractMiddleGoodsCfg,
      rules,
      formRef,
      formData,
      isSpotContract,
      isHedgePlan,
      goodsList,
      buyPrice,
      sellPrice,
      selectedGoods,
      goodsChange,
      selectedRowKeys,
      selectedPosition,
      priceTypeList,
      PriceType,
      selectedPriceType,
      filterOption,
      priceTypeChange,
      getColumns,
      onSelectChange,
      minusQty,
      plusQty,
      BuyOrSell,
    }
  }
})
</script>

<style lang="less">
@import './index.less';
</style>