package com.muchinfo.mtp3century.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import com.muchinfo.mtp.proto.Common;
import com.muchinfo.mtp.proto.QuoteMI1;
import com.muchinfo.mtp3century.service.ICommonService;
import com.muchinfo.mtp3century.service.ITradingMarketService;
import com.muchinfo.mtp3century.utils.AjaxResult;
import com.muchinfo.mtp3century.utils.RedisServiceUtil;
import com.muchinfo.mtp3common.enumtype.*;
import com.muchinfo.mtp3common.utils.DateTimeUtils;
import com.muchinfo.mtp3common.utils.SerialNumberUtils;
import com.muchinfo.mtp3common.vo.Calculator;
import com.muchinfo.mtp3common.vo.PageResult;
import com.muchinfo.mtp3common.vo.ProtoHelper;
import com.muchinfo.mtp3interface.mapper.*;
import com.muchinfo.mtp3pojos.entity.*;
import com.muchinfo.mtp3pojos.vo.GoodsQuoterDto;
import com.muchinfo.mtp3pojos.vo.common.OrganSelectResult;
import com.muchinfo.mtp3pojos.vo.tradingmarket.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

@Service
public class TradingMarketServiceImpl implements ITradingMarketService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    private ICommonService iCommonService;
    @Resource
    private ISystemmanagerMapper iSystemmanagerMapper;
    @Resource
    private IQuoterMapper iQuoterMapper;
    @Resource
    private IArearoleMapper iArearoleMapper;
    @Resource
    private IUseraccountMapper iUseraccountMapper;
    @Resource
    private ITaaccountMapper iTaaccountMapper;
    @Resource
    private ICustomertypeareadetailMapper iCustomertypeareadetailMapper;
    @Resource
    private IRoleuserMapper iRoleuserMapper;
    @Resource
    private IGoodsquoterMapper iGoodsquoterMapper;
    @Resource
    private IGoodsMapper iGoodsMapper;
    @Resource
    private IOptionQuotedetailMapper iOptionQuotedetailMapper;
    @Resource
    private IMmrelation1Mapper iMmrelation1Mapper;
    @Resource
    private IMmrelation2Mapper iMmrelation2Mapper;
    @Resource
    private SystemmanagerServiceImpl systemmanagerService;
    @Resource
    private RedisServiceUtil redisServiceUtil;
    @Resource
    private IMarketMapper iMarketMapper;
    @Resource
    private ITradepositionMapper iTradepositionMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private IMarketrunMapper iMarketrunMapper;

    @Override
    public PageResult<Quoter> queryquoter(TradingMarketQuoterParam param, HttpServletRequest request) {
        PageResult<Quoter> pageResult = new PageResult<>();
        IPage<Quoter> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<Quoter> resultIPage = iQuoterMapper.selectPage(page, new QueryWrapper<Quoter>()
                .like(StringUtils.isNotBlank(param.getQuotername()), "quotername", param.getQuotername())
                .eq(param.getQuoterstatus() != null, "quoterstatus", param.getQuotername()));
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(resultIPage.getPages());
        pageResult.setCurrent(resultIPage.getCurrent());
        pageResult.setTotal(resultIPage.getTotal());
        pageResult.setPageSize(resultIPage.getSize());
        pageResult.setData(resultIPage.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult quoteradd(TradingMarketQuoterAddParam param, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        List<Quoter> list = iQuoterMapper.selectList(new QueryWrapper<Quoter>().eq("quotername", param.getQuotername()));
        if (CollectionUtils.isNotEmpty(list)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM038.getCode(), request.getHeader("Accept-Language"));
        }

        boolean isMarketer = false;
        if (param.getTradeproperty() == 2) {
            Arearole ar = iArearoleMapper.selectOne(new QueryWrapper<Arearole>()
                    .eq("userid", param.getAreauserid())
                    .eq("roletype", SysEnums.OrganRole.marketer.getCode()));
            if (ar == null) {
                String sysparm = iCommonService.getSysparmById(SysConstants.SSYPAMAM_CODE_MARKET_QUOTE);
                if ("1".equals(sysparm)) {
                    //添加做市角色
                    Useraccount ua = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>()
                            .eq("userid", param.getAreauserid()));
                    if (ua.getReckonaccountid() == null)
                        return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM039.getCode(), request.getHeader("Accept-Language"));

                    isMarketer = true;
                    Taaccount ta = iTaaccountMapper.selectOne(new QueryWrapper<Taaccount>()
                            .eq("accountid", ua.getReckonaccountid()));
                    ta.setIsmarketaccount(1);
                    iTaaccountMapper.update(ta, new QueryWrapper<Taaccount>().eq("accountid", ua.getReckonaccountid()));

                    Customertypeareadetail ca = new Customertypeareadetail();
                    ca.setArearoleid(SysEnums.OrganRole.marketer.getCode());
                    ca.setCustomertype(1);
                    ca.setUserid(param.getAreauserid());
                    iCustomertypeareadetailMapper.insert(ca);


                    iArearoleMapper.delete(new QueryWrapper<Arearole>()
                            .eq("userid", param.getAreauserid())
                            .eq("roletype", SysEnums.OrganRole.marketer.getCode()));

                    Arearole or = new Arearole();
                    or.setCreatetime(new Date());
                    or.setCreatorid(systemmanager.getAutoid());
                    or.setUserid(param.getAreauserid());
                    or.setRoletype(SysEnums.OrganRole.marketer.getCode());
                    or.setTradeaccountid(ua.getReckonaccountid());
                    or.setModifierid(systemmanager.getAutoid());
                    or.setModifytime(new Date());
                    iArearoleMapper.insert(or);
                } else
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM040.getCode(), request.getHeader("Accept-Language"));
            }
        }
        Quoter qt = new Quoter();
        qt.setAreauserid(param.getAreauserid());
        qt.setDefaultmakerid(param.getTradeproperty() == 1 ? param.getDefaultmakerid() : param.getAreauserid());
        qt.setQuotername(param.getQuotername());
        qt.setModifytime(new Date());
        qt.setModifierid(systemmanager.getAutoid());
        qt.setQuoterstatus(1);
        qt.setTradeproperty(param.getTradeproperty());
        if (param.getMatchmode() == null) {
            qt.setMatchmode(2);
        } else {
            qt.setMatchmode(param.getMatchmode());
        }

        iQuoterMapper.insert(qt);

        Systemmanager user = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>()
                .eq("areauserid", qt.getAreauserid())
                .eq("isdefault", 1));
        if (user != null) {
            Roleuser ur = new Roleuser();
            ur.setRoleid(13L);
            ur.setManagerid(user.getAutoid());
            ur.setRoletype(3);
            iRoleuserMapper.insert(ur);
            if (isMarketer) {
                Roleuser ur1 = new Roleuser();
                ur1.setRoleid(8L);
                ur1.setManagerid(user.getAutoid());
                ur1.setRoletype(3);
                iRoleuserMapper.insert(ur1);
            }
        }

        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public AjaxResult delquoter(Long quoterid, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        Quoter qt = iQuoterMapper.selectOne(new QueryWrapper<Quoter>().eq("quoterid", quoterid));
        //注销
        List<Goodsquoter> quoter = iGoodsquoterMapper.selectList(new QueryWrapper<Goodsquoter>().eq("quoterid", quoterid));
        if (quoter != null && !quoter.isEmpty()) {
            List<Long> mids = new ArrayList<>();
            quoter.forEach(p -> {
                mids.add(p.getGoodsid());
            });

            List<Integer> st = new ArrayList<>();
            st.add(2);
            st.add(3);
            st.add(7);
            List<Goods> gds = iGoodsMapper.selectList(new QueryWrapper<Goods>()
                    .in("goodsid", mids)
                    .in("goodsstatus", st));
            if (CollectionUtils.isNotEmpty(gds)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM041.getCode(), request.getHeader("Accept-Language"));
            }
        }

        List<OptionQuotedetail> op = iOptionQuotedetailMapper.selectList(new QueryWrapper<OptionQuotedetail>().eq("quoterid", quoterid));
        if (CollectionUtils.isNotEmpty(op)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM042.getCode(), request.getHeader("Accept-Language"));
        }

        //删除一级对手关系
        iMmrelation1Mapper.delete(new QueryWrapper<Mmrelation1>().eq("quoterid", quoterid));
        //删除报价商
        Long areaid = qt.getAreauserid();
        iQuoterMapper.delete(new QueryWrapper<Quoter>().eq("quoterid", quoterid));
        //如果机构没有报价商，该机构报价商角色
        List<Quoter> list = iQuoterMapper.selectList(new QueryWrapper<Quoter>().eq("areauserid", areaid));
        if (list == null || list.isEmpty()) {
            Systemmanager user_ = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("isdefault", 1));
            if (systemmanager != null) {
                iRoleuserMapper.delete(new QueryWrapper<Roleuser>()
                        .eq("roleid", 13L)
                        .eq("managerid", user_.getAutoid()));
            }
        }

        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public PageResult<Mmrelation1> queryFirstRelation(Long quoterid, Integer pageSize, Integer pageNum, HttpServletRequest request) {
        PageResult<Mmrelation1> pageResult = new PageResult<>();
        IPage<Mmrelation1> page = new Page<>(pageNum, pageSize);
        IPage<Mmrelation1> resultIPage = iMmrelation1Mapper.selectPage(page, new QueryWrapper<Mmrelation1>()
                .eq(quoterid != null, "quoterid", quoterid)
                .orderByDesc("modifytime"));
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(resultIPage.getPages());
        pageResult.setCurrent(resultIPage.getCurrent());
        pageResult.setTotal(resultIPage.getTotal());
        pageResult.setPageSize(resultIPage.getSize());
        pageResult.setData(resultIPage.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult<TradingMarketQuoterFirstResult> getQuoterOrgan(Long quoterid, Long matchuserid, HttpServletRequest request) {
        TradingMarketQuoterFirstResult result = new TradingMarketQuoterFirstResult();
        List<Useraccount> list = iQuoterMapper.getUserListExistsFirstByQuoter(quoterid, matchuserid);
        List<Useraccount> accounts = iQuoterMapper.getUserListNotExistsFirstByQuoter(quoterid, matchuserid);
        result.setChoose(list);
        result.setNoChoose(accounts);
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), result);
    }

    @Override
    public AjaxResult quoteraddFir(TradingMarketQuoterFirstAddParam param, HttpServletRequest request) {
        Systemmanager user = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        iMmrelation1Mapper.delete(new QueryWrapper<Mmrelation1>()
                .eq("quoterid", param.getQuoterid())
                .eq("matchuserid", param.getMatchuserid()));
        if (StringUtils.isNotBlank(param.getChoose())) {
            String[] ids = param.getChoose().split(",");
            for (String id : ids) {
                Mmrelation1 mm = new Mmrelation1();
                mm.setQuoterid(param.getQuoterid());
                mm.setMemberuserid(Long.valueOf(id));
                mm.setMatchuserid(param.getMatchuserid());
                mm.setModifierid(user.getAutoid());
                mm.setModifytime(new Date());
                iMmrelation1Mapper.insert(mm);
            }
        }
        systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ_BJ, "新增对手关系{\"quoterid\":\"" + param.getQuoterid() + "\"}", user, "新增一级对手关系", null, null);

        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public AjaxResult quotereditFir(TradingMarketQuoterFirstAddParam param, HttpServletRequest request) {
        Systemmanager user = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        Mmrelation1 temp = iMmrelation1Mapper.selectOne(new QueryWrapper<Mmrelation1>()
                .eq("memberuserid", param.getMemberuserid())
                .eq("quoterid", param.getQuoterid()));
        if (temp != null) {
            temp.setMatchuserid(param.getMatchuserid());
            temp.setModifytime(new Date());
            temp.setModifierid(user.getAutoid());
            iMmrelation1Mapper.update(temp, new QueryWrapper<Mmrelation1>()
                    .eq("memberuserid", param.getMemberuserid())
                    .eq("quoterid", param.getQuoterid()));
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public AjaxResult quoterisvalid(Long memberuserid, Long quoterid, HttpServletRequest request) {
        iMmrelation1Mapper.delete(new QueryWrapper<Mmrelation1>()
                .eq("memberuserid", memberuserid)
                .eq("quoterid", quoterid));
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public PageResult<TradingManualQuoterResult> manualQuoter(TradingManualQuoterParam param, HttpServletRequest request) {
        Systemmanager user = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        param.setAreauserid(user.getAreauserid());

        Object sys1018 = redisServiceUtil.getCacheMapValue(Constants.REDIS_HEADER_SYSPARAM, "1018");
        if (sys1018 != null && !Strings.isNullOrEmpty(sys1018.toString())) {
            param.setTrademodes(sys1018.toString().split(","));
        }

        PageResult<TradingManualQuoterResult> pageResult = new PageResult<>();
        IPage<TradingManualQuoterResult> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<TradingManualQuoterResult> resultIPage = iQuoterMapper.queryGoodsQuoterPage(page, param);
        try {
            for (TradingManualQuoterResult record : resultIPage.getRecords()) {
                if (record != null && (record.getTrademode().equals(99))) {
                    byte[] valuebts = redisServiceUtil.getBytes("QUOTE:" + record.getGoodscode());
                    if (valuebts != null) {
                        QuoteMI1.RealtimeQuote goodsQuote = QuoteMI1.RealtimeQuote.parseFrom(valuebts);
                        BigDecimal pow = BigDecimal.TEN.pow(goodsQuote.getDecimalPlace());
                        if (goodsQuote != null) {
                            BigDecimal bidPrice = BigDecimal.ZERO;
                            BigDecimal askPrice = BigDecimal.ZERO;
                            if (goodsQuote.getBidPriceArray(0) > 0) {
                                bidPrice = new BigDecimal(goodsQuote.getBidPriceArray(0)).divide(pow);
                            }
                            if (goodsQuote.getAskPriceArray(0) > 0) {
                                askPrice = new BigDecimal(goodsQuote.getAskPriceArray(0)).divide(pow);
                            }
                            record.setBid(bidPrice);
                            record.setAsk(askPrice);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("计算价格失败，失败原因：" + e.getMessage());
        }

        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(resultIPage.getPages());
        pageResult.setCurrent(resultIPage.getCurrent());
        pageResult.setTotal(resultIPage.getTotal());
        pageResult.setPageSize(resultIPage.getSize());
        pageResult.setData(resultIPage.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult<TradingManualQuoterViewResult> manualQuoterView(Long goodsid, HttpServletRequest request) {
        TradingManualQuoterViewResult result = new TradingManualQuoterViewResult();
        Systemmanager user = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        //判断手工报价是否显示最高买入价和最低卖出价
        String sysparam = iCommonService.getSysparmById(SysConstants.SYSPARAM_CODE_OFFER_QUOTE);
        if ("1".equals(sysparam)) {
            result.setIsOfferQuoter(Integer.valueOf(sysparam));
        }
        String sp = iCommonService.getSysparmById(SysConstants.SSYPAMAM_CODE_DEALER_QUOTE);
        List<Arearole> ars = iArearoleMapper.selectList(new QueryWrapper<Arearole>().eq("userid", user.getAreauserid()));
        for (Arearole arr : ars) {
            //判断该用户是否是产业会员是否隐藏报买
            if ("1".equals(sp) && arr.getRoletype() == 9) {
                result.setIsDealerQuoter(Integer.valueOf(sp));
            }
        }

        Goods goods = iGoodsMapper.selectOne(new QueryWrapper<Goods>().eq("goodsid", goodsid));
        if (goods == null) {
            log.error("商品数据缺失，缺失商品id：" + goodsid);
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM002.getCode(), request.getHeader("Accept-Language"));
        }
        result.setDecimalPlace(goods.getDecimalplace());
        Market market = iMarketMapper.selectOne(new QueryWrapper<Market>().eq("marketid", goods.getMarketid()));
        result.setTradeMode(market.getTrademode());
        result.setTradeProperty(market.getTradeproperty());
        //挂牌点选
        if (market.getTrademode() == 16) {
            Double pow = Math.pow(10, goods.getDecimalplace());
            BigDecimal quoteMinUnit = new BigDecimal(goods.getQuoteminunit().toString()).divide(new BigDecimal(pow.toString()));
            result.setQuoteMinUnit(quoteMinUnit);
        }
        GoodsQuoterDto quoteParam = iQuoterMapper.getParamByMap(goodsid, user.getAreauserid());
        //如果是期权交易,先这么判断 , 挂牌期权 期权报价列表是不会显示挂牌期权商品的。
        if (market.getTrademode() == 18) {
            result.setQuoteParam(quoteParam);
            //开盘价
            double open = getRealtimeQuoteOpen(goods.getGoodscode());
            if (quoteParam.getDecimalplace() == null || quoteParam.getDecimalplace() == 0) {
                result.setOpen(open);
            } else {
                StringBuilder strUnit = new StringBuilder("1");
                for (int i = 0; i < quoteParam.getDecimalplace(); i++) {
                    strUnit.append("0");
                }
                double openvalue = open / Double.parseDouble(strUnit.toString());
                result.setOpen(openvalue);
            }
            result.setOpen(open);
        } else {
            //非期权交易报价
            //买
            //临时处理办法,用getParamNewByMap会查出2条数据
            GoodsQuoterDto buy = iQuoterMapper.getParamNewByMap(goodsid, user.getAreauserid(), 0);
            long qtydecimalplace = goods.getQtydecimalplace() == null ? 0 : Double.valueOf(goods.getQtydecimalplace()).longValue(); //报量小数位
            BigDecimal decimalplace = BigDecimal.valueOf(Math.pow(10, Double.valueOf(goods.getDecimalplace()))); //报价小数位
            if (buy != null) {
                quoteParam.setBid(buy.getPrice());
                if (qtydecimalplace != 0) {
                    quoteParam.setBuyqty(buy.getQty() != null ? buy.getQty() / qtydecimalplace : buy.getQty());
                    quoteParam.setBuycurqty(buy.getCurqty() != null ? buy.getCurqty() / qtydecimalplace : buy.getCurqty());
                } else {
                    quoteParam.setBuyqty(buy.getQty());
                    quoteParam.setBuycurqty(buy.getCurqty());
                }

                quoteParam.setTopBid(buy.getLimitprice() != null ? buy.getLimitprice().divide(decimalplace) : buy.getLimitprice());
                quoteParam.setBidMove(buy.getMove() / decimalplace.longValue());
                quoteParam.setBuyqtytype(buy.getQtytype());
                quoteParam.setBuypricetype(buy.getPricetype());
            } else if (quoteParam != null) {
                quoteParam.setBid(null);
                quoteParam.setBuyqty(null);
                quoteParam.setBuycurqty(null);
                quoteParam.setTopBid(null);
                quoteParam.setBidMove(null);
                quoteParam.setBuyqtytype(null);
                quoteParam.setBuypricetype(null);
            }

            //卖
            GoodsQuoterDto sell = iQuoterMapper.getParamNewByMap(goodsid, user.getAreauserid(), 1);
            if (sell != null) {
                quoteParam.setAsk(sell.getPrice());
                if (qtydecimalplace != 0) {
                    quoteParam.setSellqty(sell.getQty() != null ? sell.getQty() / qtydecimalplace : sell.getQty());
                    quoteParam.setSellcurqty(sell.getCurqty() != null ? sell.getCurqty() / qtydecimalplace : sell.getCurqty());
                    quoteParam.setAskMove(sell.getMove() / decimalplace.longValue());
                } else {
                    quoteParam.setSellqty(sell.getQty());
                    quoteParam.setSellcurqty(sell.getCurqty());
                    quoteParam.setAskMove(sell.getMove());
                }
                quoteParam.setBottomAsk(sell.getLimitprice() != null ? sell.getLimitprice().divide(decimalplace) : sell.getLimitprice());
                quoteParam.setSellqtytype(sell.getQtytype());
                quoteParam.setSellpricetype(sell.getPricetype());
            } else {
                quoteParam.setAsk(null);
                quoteParam.setSellqty(null);
                quoteParam.setSellcurqty(null);
                quoteParam.setBottomAsk(null);
                quoteParam.setAskMove(null);
                quoteParam.setSellqtytype(null);
                quoteParam.setSellpricetype(null);
            }
            result.setQuoteParam(quoteParam);

            //最大可卖出量
            Long maxsellqty = getNewMaxSellQty(quoteParam.getGoodsid(), quoteParam.getQuoterid());
            result.setMaxsellqty(maxsellqty);
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), result);
    }

    @Override
    public AjaxResult newquote(TradingManualNewQuoterParam param, HttpServletRequest request) {
        if (param.getTrademode().equals(99)) {
            // 99 模式发送实时行情(QuotePrice收)
            return realNewQuoter(param, request);
        } else {
            // 其它模式发送交易行情
            return manualNewQuoter(param, request);
        }
    }

    @Override
    public PageResult<TradingQuerySecRelationResult> querySecRelation(Long memberuserid, Integer pageSize, Integer pageNum, HttpServletRequest request) {
        PageResult<TradingQuerySecRelationResult> pageResult = new PageResult<>();
        IPage<TradingQuerySecRelationResult> page = new Page<>(pageNum, pageSize);
        IPage<TradingQuerySecRelationResult> resultIPage = iQuoterMapper.querySecRelation(page, memberuserid);
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(resultIPage.getPages());
        pageResult.setCurrent(resultIPage.getCurrent());
        pageResult.setTotal(resultIPage.getTotal());
        pageResult.setPageSize(resultIPage.getSize());
        pageResult.setData(resultIPage.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult<OrganSelectResult> selectOrgan(String searchcode, HttpServletRequest request) {
        OrganSelectResult result = iQuoterMapper.getUserListNotExistsSec(searchcode);
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), result);
    }

    @Override
    public AjaxResult<TradingMarketSecRelationResult> getMarketing(Long memberuserid, HttpServletRequest request) {
        TradingMarketSecRelationResult result = new TradingMarketSecRelationResult();
        List<MmRelationResult> list = iQuoterMapper.getExistsSecUserById(memberuserid);
        List<Long> ids = new ArrayList<>();
        ids.add(memberuserid);
        for (MmRelationResult rela : list) {
            ids.add(rela.getMatchuserid());
        }
        List<OrganSelectResult> accounts = iQuoterMapper.getNotExistsSecUserById(ids);
        result.setChoose(list);
        result.setNoChoose(accounts);
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), result);
    }

    @Override
    public AjaxResult modifySec(TradigModifySecAddParam param, HttpServletRequest request) {
        Systemmanager user = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        iMmrelation2Mapper.delete(new QueryWrapper<Mmrelation2>().eq("memberuserid", param.getMemberuserid()));
        if (StringUtils.isNotBlank(param.getChoose())) {
            String[] ids = param.getChoose().split(",");
            for (int i = 0; i < ids.length; i++) {
                Mmrelation2 mm = new Mmrelation2();
                mm.setMemberuserid(param.getMemberuserid());
                mm.setMatchuserid(Long.valueOf(ids[i]));
                mm.setMatchseq((long) (i + 1));
                mm.setModifierid(user.getAutoid());
                mm.setModifytime(new Date());
                iMmrelation2Mapper.insert(mm);
            }
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public AjaxResult isvalid2(Long memberuserid, Long matchuserid , HttpServletRequest request) {
        iMmrelation2Mapper.delete(new QueryWrapper<Mmrelation2>()
                .eq("memberuserid", memberuserid)
                .eq("matchuserid", matchuserid));
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    private AjaxResult manualNewQuoter(TradingManualNewQuoterParam param, HttpServletRequest request) {
        boolean isbuyprice = true; //是否报买价
        boolean issellprice = true; //是否报卖价
        AjaxResult ajaxResult = null;
        if (param.getTradeproperty() == 2) {
            //当卖量不为0时
            if (null != param.getSellqty() && param.getSellqty().intValue() != 0) {
                Tradeposition tp = iTradepositionMapper.getTradePosition(param.getGoodsid(), param.getQuoterid());
                GoodsQuoterDto gqdo = iQuoterMapper.getNewSellCurQty(param.getGoodsid(), param.getQuoterid());
                //买头寸可用手数 = 买当前持仓总数量  - 买持仓冻结数量 - 买持仓其他冻结数量  + 当前卖量
                //买头寸可用手数 = 买当前持仓总数量  - 买持仓冻结数量 - 买持仓其他冻结数量  + 当前卖量
                Long num = 0L;
                if (null != tp) {
                    num = tp.getBuycurpositionqty() - tp.getBuyfrozenqty() - tp.getBuyotherfrozenqty();
                    if (null != gqdo && null != gqdo.getSellcurqty()) {
                        if (gqdo.getSellisvalid() != null) {
                            if (gqdo.getSellisvalid() == 1) {//1撤销，0未撤销

                            } else {
                                num += gqdo.getSellcurqty();
                            }
                        }
                    }
                }
                if (param.getSellqty().longValue() > num.longValue()) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM047.getCode(), request.getHeader("Accept-Language"));
                }
            }
        }

        //返回结果
        Goods goods = iGoodsMapper.selectOne(new QueryWrapper<Goods>().eq("goodsid", param.getGoodsid()));
        BigDecimal qtydecimalplace = BigDecimal.ONE;
        if (goods != null && goods.getQtydecimalplace() != null) {
            qtydecimalplace = BigDecimal.TEN.pow(goods.getQtydecimalplace()); //成交量小数位
        }

        // 20250701 53，54模式默认不报买价
        if (param.getTrademode() == 53 ||
                param.getTrademode() == 54 ||
                (param.getBidSelect() == 2 && param.getBid() != null && param.getBid().equals(new BigDecimal(0)))) {
            //没报买价
            isbuyprice = false;
        } else {
            // 报买价
            //ajaxResult = quoteBid(param, qtydecimalplace);
        }

        if (param.getAskSelect() == 2 && param.getAsk() != null
                && param.getAsk().equals(new BigDecimal(0))) {
            //没报卖价
            issellprice = false;
        } else {
            // 报卖价
            //ajaxResult = quoteSell(param, qtydecimalplace);
        }

        if (isbuyprice == false && issellprice == false) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM048.getCode(), request.getHeader("Accept-Language"));
        }

        return ajaxResult;
    }

    private AjaxResult realNewQuoter(TradingManualNewQuoterParam param, HttpServletRequest request) {
        // 99发送实时行情  FunCode_Trade_RealtimeQuote = 18022401;   // 原始实时行情
        BigDecimal ask = param.getAsk(); //卖价
        BigDecimal bid = param.getBid(); //买价
        BigDecimal pow = BigDecimal.TEN.pow(param.getDecimalplace());//行权价还是按原来的报价小数位
        if (null != ask && ask.compareTo(BigDecimal.ZERO) != 0) {
            //除了挂牌点选市场，其他模式市场卖价必须高于买价
            if (param.getTrademode() != 16) {
                if (null != bid && bid.compareTo(ask) >= 0) { //compareTo比较结果：-1 小于，0 等于，1 大于
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM043.getCode(), request.getHeader("Accept-Language"));
                }
            }
        }
        if (null == bid || bid.equals(0)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM044.getCode(), request.getHeader("Accept-Language"));
        }

        if (null == ask || ask.equals(0)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM045.getCode(), request.getHeader("Accept-Language"));
        }

        Goods goods = iGoodsMapper.selectOne(new QueryWrapper<Goods>().eq("goodsid", param.getGoodsid()));
        if (goods == null) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM046.getCode(), request.getHeader("Accept-Language"));
        }

        // 使用系统的交易日
        Marketrun marketRun = iMarketrunMapper.selectOne(new QueryWrapper<Marketrun>().eq("marketid", 0L));

        Map<String, Object> result = new HashMap<String, Object>();
        QuoteMI1.RealtimeQuote.Builder builder = QuoteMI1.RealtimeQuote.newBuilder();

        Long uuid = SerialNumberUtils.getNewSerialNumber(SerialNumberUtils.prefix_quote);
        Common.MessageHead.Builder hd = Common.MessageHead.newBuilder();
        hd.setFunCode(FunCodeConstants.FunCode_Trade_RealtimeQuote);
        hd.setUUID(uuid.toString());
        hd.setMarketID(param.getMarketid().intValue());
        builder.setHeader(hd);

        builder.setGoodsID(param.getGoodsid().intValue());
        builder.setGoodsCode(goods.getGoodscode());
        builder.setDecimalPlace(param.getDecimalplace());
        builder.setTradeDate(marketRun.getTradedate());
        builder.setDateTime(DateTimeUtils.getDateTime("yyyyMMdd HHmmss")); //报价时间

        // 买价
        long bidQutePrice = bid.multiply(pow).longValue();
        builder.addBidPriceArray(bidQutePrice);
        builder.addBidVolumeArray(0L);
        builder.setLast(bidQutePrice); // 买价做为现价下发
        builder.setReckonPrice(bidQutePrice); // 买价做为结算价下发

        // 卖价
        builder.addAskPriceArray(ask.multiply(pow).longValue());
        builder.addAskVolumeArray(0L);
        // 交易模式
        builder.setQuoteType(param.getTrademode());

        Calculator ca = new Calculator(uuid);
        SerialNumberUtils.lockMap.put(uuid, ca);
        byte[] body = ProtoHelper.getNTAS(builder.build().toByteArray(), FunCodeConstants.FunCode_Trade_RealtimeQuote);
        rabbitTemplate.send(SysConstants.RabbitQuoteRealReq, new Message(body, new MessageProperties()));
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    private Long getNewMaxSellQty(Long goodsid, Long quoterid) {
        Tradeposition tp = iTradepositionMapper.getTradePosition(goodsid, quoterid);
        GoodsQuoterDto gqd = iQuoterMapper.getNewSellCurQty(goodsid, quoterid);
        //买头寸可用手数 = 买当前持仓总数量  - 买持仓冻结数量 - 买持仓其他冻结数量  + 当前卖量
        Long num = 0L;
        if (null != tp) {
            num = tp.getBuycurpositionqty() - tp.getBuyfrozenqty() - tp.getBuyotherfrozenqty();
            if (null != gqd && null != gqd.getSellcurqty()) {
                //1撤销，0未撤销
                if (gqd.getSellisvalid() != 1) {
                    num += gqd.getSellcurqty();
                }
            }
        }
        return num;
    }

    private double getRealtimeQuoteOpen(String goodscode) {
        byte[] valuebts = redisServiceUtil.getBytes("QUOTE:" + goodscode);
        QuoteMI1.RealtimeQuote quoteProto = null;
        double open = 0.0;
        if (null != valuebts) {
            try {
                quoteProto = QuoteMI1.RealtimeQuote.parseFrom(valuebts);
                open = quoteProto.getOpen();
            } catch (Exception e) {
                log.error("获取交收价异常", e);
            }
        }
        return open;
    }
}
