package com.liquidnet.service.order.utils;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.type.TypeReference;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.HttpUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.adam.dto.vo.*;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.candy.param.BackCouponParam;
import com.liquidnet.service.candy.vo.CandyUseResultVo;
import com.liquidnet.service.goblin.constant.SmileRedisConst;
import com.liquidnet.service.goblin.dto.vo.SmileUserVO;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dao.KylinFreightChargeDao;
import com.liquidnet.service.kylin.dto.vo.KylinAgentVo;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinCandyVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketVo;
import com.liquidnet.service.kylin.dto.vo.returns.InnerReturnVo;
import com.liquidnet.service.kylin.dto.vo.returns.KylinOrderListVo;
import com.liquidnet.service.kylin.constant.LimitTargetEnum;
import com.liquidnet.service.kylin.constant.LimitTypeEnum;
import com.liquidnet.service.kylin.dto.vo.LimitErrorResultVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Component
@Slf4j
public class OrderUtils {

    @Autowired
    private DataUtils dataUtils;
    @Value("${liquidnet.adam.url}")
    private String adamUrl;
    @Value("${liquidnet.candy.url}")
    private String candyUrl;
    @Value("${liquidnet.service.smile.url}")
    private String smile;

    public LimitErrorResultVo judgeOrderLimit(
            String userId,
            String idCard,
            String performanceId,
            String ticketId,
            String timeId,
            int performanceLimitCount,
            int performanceMemberLimitCount,
            int performanceLimitIdCard,
            int ticketLimitCount,
            int ticketMemberLimitCount,
            int ticketLimitIdCard,
            int timeRealNameLimit,
            int memberType,
            int isTrueName
    ) {
        Integer[] integers = orderLimit(userId, idCard, performanceId, ticketId, timeId, isTrueName);

        return judgeMemberType(performanceLimitCount, performanceMemberLimitCount, performanceLimitIdCard,
                ticketLimitCount, ticketMemberLimitCount, ticketLimitIdCard, timeRealNameLimit,
                memberType, integers[0], integers[1], integers[2], integers[3], integers[4], isTrueName);
    }

    public Integer[] orderLimit(
            String userId,
            String idCard,
            String performanceId,
            String ticketId,
            String timeId,
            int isTrueName
    ) {
        int performanceBuyCountUid = 0;
        int ticketBuyCountUid = 0;
        int performanceBuyCountIdCard = 0;
        int ticketBuyCountIdCard = 0;
        int timeBuyCountIdCard = 0;

        if (1 == isTrueName) {//实名
            performanceBuyCountIdCard = dataUtils.getIdCardPBuyCount(idCard, performanceId);
            ticketBuyCountIdCard = dataUtils.getIdCardTBuyCount(idCard, ticketId);
            performanceBuyCountUid = dataUtils.getUserPBuyCount(userId, performanceId);
            ticketBuyCountUid = dataUtils.getUserTBuyCount(userId, ticketId);
            timeBuyCountIdCard = dataUtils.getIdCardMBuyCount(idCard, timeId);
        } else {//非实名
            performanceBuyCountUid = dataUtils.getUserPBuyCount(userId, performanceId);
            ticketBuyCountUid = dataUtils.getUserTBuyCount(userId, ticketId);
        }

        Integer[] array = new Integer[5];
        array[0] = performanceBuyCountUid;
        array[1] = ticketBuyCountUid;
        array[2] = performanceBuyCountIdCard;
        array[3] = ticketBuyCountIdCard;
        array[4] = timeBuyCountIdCard;
        return array;
    }

    public LimitErrorResultVo judgeMemberType(int performanceLimitCount, int performanceMemberLimitCount, int performanceLimitIdCard,
                                  int ticketLimitCount, int ticketMemberLimitCount, int ticketLimitIdCard, int timeRealNameLimit, int memberType,
                                  int performanceBuyCountUid, int ticketBuyCountUid, int performanceBuyCountIdCard, int ticketBuyCountIdCard,
                                  int timeBuyCountIdCard,
                                  int isTrueName) {

        if (isTrueName == 1 && timeRealNameLimit != 0) {
            if (timeBuyCountIdCard > timeRealNameLimit) {
                return LimitErrorResultVo.builder()
                        .limitType(LimitTypeEnum.TIME.getCode())
                        .limitTarget(LimitTargetEnum.IDCARD.getCode())
                        .limitCount(timeRealNameLimit)
                        .currentCount(timeBuyCountIdCard)
//                        .errorMessage("实名制场次限购" + timeRealNameLimit + "张，已超出")
                        .build();
            }
        }

        if (memberType == 1 || memberType == 2) {
            if (isTrueName == 1) {
                if (performanceBuyCountIdCard > performanceMemberLimitCount && performanceMemberLimitCount != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.PERFORMANCE.getCode())
                            .limitTarget(LimitTargetEnum.IDCARD.getCode())
                            .memberType(memberType)
                            .limitCount(performanceMemberLimitCount)
                            .currentCount(performanceBuyCountIdCard)
//                            .errorMessage("实名制演出限购" + performanceMemberLimitCount + "张，已超出")
                            .build();
                }
                if (ticketBuyCountIdCard > ticketMemberLimitCount && ticketMemberLimitCount != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.TICKET.getCode())
                            .limitTarget(LimitTargetEnum.IDCARD.getCode())
                            .memberType(memberType)
                            .limitCount(ticketMemberLimitCount)
                            .currentCount(ticketBuyCountIdCard)
//                            .errorMessage("实名制票种限购" + ticketMemberLimitCount + "张，已超出")
                            .build();
                }
            } else {
                if (performanceBuyCountUid > performanceMemberLimitCount && performanceMemberLimitCount != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.PERFORMANCE.getCode())
                            .limitTarget(LimitTargetEnum.ACCOUNT.getCode())
                            .memberType(memberType)
                            .limitCount(performanceMemberLimitCount)
                            .currentCount(performanceBuyCountUid)
//                            .errorMessage("本场演出限购" + performanceMemberLimitCount + "张，已超出")
                            .build();
                }
                if (ticketBuyCountUid > ticketMemberLimitCount && ticketMemberLimitCount != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.TICKET.getCode())
                            .limitTarget(LimitTargetEnum.ACCOUNT.getCode())
                            .memberType(memberType)
                            .limitCount(ticketMemberLimitCount)
                            .currentCount(ticketBuyCountUid)
//                            .errorMessage("该票种限购" + ticketMemberLimitCount + "张，已超出")
                            .build();
                }
            }
        } else {//非会员区间
            if (isTrueName == 1) {
                if (performanceBuyCountIdCard > performanceLimitIdCard && performanceLimitIdCard != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.PERFORMANCE.getCode())
                            .limitTarget(LimitTargetEnum.IDCARD.getCode())
                            .limitCount(performanceLimitIdCard)
                            .currentCount(performanceBuyCountIdCard)
//                            .errorMessage("实名制演出限购" + performanceLimitIdCard + "张，已超出")
                            .build();
                }
                if (ticketBuyCountIdCard > ticketLimitIdCard && ticketLimitIdCard != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.TICKET.getCode())
                            .limitTarget(LimitTargetEnum.IDCARD.getCode())
                            .limitCount(ticketLimitIdCard)
                            .currentCount(ticketBuyCountIdCard)
//                            .errorMessage("实名制票种限购" + ticketLimitIdCard + "张，已超出")
                            .build();
                }
                if (performanceBuyCountUid > performanceLimitCount && performanceLimitCount != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.PERFORMANCE.getCode())
                            .limitTarget(LimitTargetEnum.ACCOUNT.getCode())
                            .limitCount(performanceLimitCount)
                            .currentCount(performanceBuyCountUid)
//                            .errorMessage("本场演出限购" + performanceLimitCount + "张，已超出")
                            .build();
                }
                if (ticketBuyCountUid > ticketLimitCount && ticketLimitCount != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.TICKET.getCode())
                            .limitTarget(LimitTargetEnum.ACCOUNT.getCode())
                            .limitCount(ticketLimitCount)
                            .currentCount(ticketBuyCountUid)
//                            .errorMessage("该票种限购" + ticketLimitCount + "张，已超出")
                            .build();
                }
            } else {
                if (performanceBuyCountUid > performanceLimitCount && performanceLimitCount != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.PERFORMANCE.getCode())
                            .limitTarget(LimitTargetEnum.ACCOUNT.getCode())
                            .limitCount(performanceLimitCount)
                            .currentCount(performanceBuyCountUid)
//                            .errorMessage("本场演出限购" + performanceLimitCount + "张，已超出")
                            .build();
                }
                if (ticketBuyCountUid > ticketLimitCount && ticketLimitCount != 0) {
                    return LimitErrorResultVo.builder()
                            .limitType(LimitTypeEnum.TICKET.getCode())
                            .limitTarget(LimitTargetEnum.ACCOUNT.getCode())
                            .limitCount(ticketLimitCount)
                            .currentCount(ticketBuyCountUid)
//                            .errorMessage("该票种限购" + ticketLimitCount + "张，已超出")
                            .build();
                }
            }
        }
        return null;
    }


    //判断 操作 普通库存还是兑换库存
    public int changeSurplus(boolean isPay, String ticketId, int number) {
        int surplusGeneral;
        if (isPay) {
            surplusGeneral = dataUtils.changeSurplusGeneral(ticketId, number);
        } else {
            surplusGeneral = dataUtils.changeSurplusExchange(ticketId, number);
        }
        return surplusGeneral;
    }

    public AdamRscPolymer01Vo adamAddressEnterMember(String uid, String enterIds, String addressId) {
        try {
            MultiValueMap<String, String> header = CollectionUtil.linkedMultiValueMapStringString();
            header.add("Accept", "application/json;charset=UTF-8");
            MultiValueMap<String, String> params = CollectionUtil.linkedMultiValueMapStringString();
            params.add("addressId", addressId);
            params.add("entersIds", enterIds);
            params.add("uid", uid);
            String resultData = HttpUtil.post(adamUrl + "/adam/rsc/inquire/of_buy_ticket", params, header);
            ResponseDto<AdamRscPolymer01Vo> vo = JsonUtils.fromJson(resultData, new TypeReference<ResponseDto<AdamRscPolymer01Vo>>() {
            });
            if (null != vo.getData()) {
                return vo.getData();
            } else {
                return null;
            }
        } catch (Exception e) {
            log.error("获取用户信息,e:{}", e);
            e.printStackTrace();
            return null;
        }
    }

    public Integer getMember(String uid) {
        return dataUtils.getMember(uid);
    }

    public List<AdamEntersVo> getEnterList(List<String> enterIdList, String uid) {
        List<AdamEntersVo> list = ObjectUtil.cloneArrayListObject();
        List<String> unExists = ObjectUtil.cloneLinkedListStr();
        for (String enterId : enterIdList) {
            AdamEntersVo entersVo = dataUtils.getEnterVo(enterId);
            if (entersVo == null) {
                unExists.add(enterId);
            } else {
                entersVo.setUid(uid);
                if (entersVo.getUid().equals(uid)) {
                    list.add(entersVo);
                }
            }
        }
        try {
            if (unExists.size() > 0) {
                MultiValueMap<String, String> header = CollectionUtil.linkedMultiValueMapStringString();
                header.add("Accept", "application/json;charset=UTF-8");
                String returnData = HttpUtil.get(adamUrl + "/adam/rsc/inquire/enters?entersIds=" + StringUtils.join(unExists, ",") + "&uid=" + uid, null, header);
                ResponseDto<List<AdamEntersVo>> res = JsonUtils.fromJson(returnData, new TypeReference<ResponseDto<List<AdamEntersVo>>>() {
                });
                List<AdamEntersVo> entersVoList = res.getData();
                for (AdamEntersVo vo : entersVoList) {
                    dataUtils.setEnterVo(vo);
                    list.add(vo);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 使用优惠券
     *
     * @param uCouponId  券id
     * @param content    消费内容
     * @param totalPrice 订单总价
     * @return
     */
    public HashMap<String, Object> useCoupon(String uCouponId, String content, BigDecimal totalPrice, String performanceId, String timesId, String ticketId,int perType) {
        HashMap<String, Object> hashMap = CollectionUtil.mapStringObject();
        try {
            MultiValueMap<String, String> params = CollectionUtil.linkedMultiValueMapStringString();
            params.add("uCouponId", uCouponId);
            params.add("content", content);
            params.add("totalPrice", totalPrice.toString());
            params.add("goodId", "-1");
            params.add("performanceId", performanceId);
            params.add("timeId", timesId);
            params.add("ticketId", ticketId);
            params.add("perType", perType+"");
            MultiValueMap<String, String> header = CollectionUtil.linkedMultiValueMapStringString();
            header.add("Authorization", "Bearer " + CurrentUtil.getToken());
            String returnData = HttpUtil.post(candyUrl + "/candy-coupon/use", params, header);
            InnerReturnVo<CandyUseResultVo> innerReturnVo = JsonUtils.fromJson(returnData, new TypeReference<InnerReturnVo<CandyUseResultVo>>() {
            });
            CandyUseResultVo candyUseResultVo = innerReturnVo.getData();
            Integer type = candyUseResultVo.getCouType();
            String couponId = candyUseResultVo.getCouponId();
            BigDecimal value = candyUseResultVo.getValue();
            BigDecimal voucher = BigDecimal.ZERO;
            switch (type) {
                case -1:
                    voucher = BigDecimal.valueOf(-1);
                    break;
                case 1:
                    voucher = voucher.add(value);
                    break;
                case 2:
                    voucher = voucher.add(value);
                    break;
                case 3:
                    voucher = voucher.add(totalPrice);
                    break;
                case 4:
                    voucher = totalPrice.subtract(totalPrice.multiply(value));
                    break;
                default:
                    voucher = BigDecimal.ZERO;
                    break;
            }
            hashMap.put("couponId", couponId);
            hashMap.put("type", type);
            hashMap.put("voucher", voucher.setScale(2, BigDecimal.ROUND_HALF_UP));
            return hashMap;
        } catch (Exception e) {
            log.error("用券ERROR:{}", e);
//            hashMap.put("type", -1);
//            hashMap.put("voucher", -1);
//            return hashMap;
            return null;
        }
    }

    //判断是不是适用于巡演
    public boolean judgeRoadShowCanUse(String couponId, String roadShowId) {
        List<String> roadShowIds = dataUtils.getCouponRoad(couponId);
        if (roadShowIds.size() == 0 || roadShowIds.contains(roadShowId)) {
            return true;
        }
        return false;
    }

    public void backAdvanceCoupon(String advanceCode, String uid) {
        if (advanceCode != null) {
            backCoupon(advanceCode, uid);
        }
    }

    public void backCoupon(String uCouponId, String uid) {
        try {
            BackCouponParam param = BackCouponParam.getNew();
            param.setuCouponIds(uCouponId);
            param.setUid(uid);

            MultiValueMap<String, String> header = CollectionUtil.linkedMultiValueMapStringString();
            header.add("Authorization", "Bearer " + CurrentUtil.getToken());

            ArrayList<BackCouponParam> params = new ArrayList();
            params.add(param);
            String jsonString = JSON.toJSONString(params);
            String returnData = HttpUtil.postRaw(candyUrl + "/candy-coupon/useBack", jsonString, header);
        } catch (Exception e) {
            log.error("回退券ERROR:{}", e);
        }
    }

    public BigDecimal getExpressPrice(String adCode, String productCode) {
        try {
            return dataUtils.getExpressPrice(adCode, productCode);
        } catch (Exception e) {
            log.error("获取快递费失败:{}", e);
            return BigDecimal.valueOf(23);
        }
    }

    /**
     * @param userId  用户id
     * @param type    1新增 2修改
     * @param orderId 订单id [需要新增或者修改的订单id]
     */
    public Boolean resetOrderListVo(String userId, Integer type, String orderId, KylinOrderTicketVo dataSingle) {
        List<KylinOrderListVo> vo = ObjectUtil.cloneArrayKylinOrderListVo();
        List<KylinOrderListVo> redisVo = ObjectUtil.cloneArrayKylinOrderListVo();
        KylinOrderListVo voItem = KylinOrderListVo.getNew();
        KylinOrderTicketVo data;
        if (dataSingle == null) {
            data = dataUtils.getOrderTicketVo(orderId);
        } else {
            data = dataSingle;
        }
        BeanUtils.copyProperties(data, voItem);
        List<KylinOrderListVo> redisData = dataUtils.getOrderList(userId);
        if (type == 1) {
            redisVo.add(voItem);
            if (redisData.size() > 0) {
                if (redisData.get(0).getOrderTicketsId().equals(orderId)) {
                    redisData.remove(0);
                }
            }
        }

        redisVo.addAll(redisData);

        switch (type) {
            case 1:
                for (int i = 0; i < redisVo.size(); i++) {
                    if (i == 40) {
                        break;
                    }
                    if (i == 0) {
                        vo.add(voItem);
                    } else {
                        vo.add(redisVo.get(i));
                    }
                }
                if (redisVo.size() == 0) {
                    vo.add(voItem);
                }
                dataUtils.setOrderList(userId, vo);
                return true;
            case 2:
                for (int i = 0; i < redisVo.size(); i++) {
                    if (i == 40) {
                        break;
                    }
                    if (redisVo.get(i).getOrderTicketsId().equals(orderId)) {
                        vo.add(voItem);
                    } else {
                        vo.add(redisVo.get(i));
                    }
                }
                dataUtils.setOrderList(userId, vo);
                return true;
            default:
                return false;
        }
    }

    //获取代理信息
    public KylinAgentVo checkAgent(String agentId, String performanceId, KylinTicketVo ticketData) {
//        agentId = "953190108752281604111893";
//        performanceId = "11";
//        ticketData.setTicketsId("22");
        try {
            if (agentId.equals("0")) {
                return null;
            } else {
                boolean isAgent = ticketData.getIsAgent() == 1;
                if (isAgent) {
                    MultiValueMap<String, String> header = CollectionUtil.linkedMultiValueMapStringString();
                    header.add("Accept", "application/json;charset=UTF-8");
                    MultiValueMap<String, String> params = CollectionUtil.linkedMultiValueMapStringString();
                    params.add("performanceId", performanceId);
                    params.add("ticketId", ticketData.getTicketsId());
                    params.add("userId", agentId);
                    String returnData = HttpUtil.post(smile + "/smile/frontNoLogin/getUser", params, header);
                    log.debug("Smile = " + returnData);
                    ResponseDto<SmileUserVO> res = JsonUtils.fromJson(returnData, new TypeReference<ResponseDto<SmileUserVO>>() {
                    });
                    SmileUserVO vo = res.getData();
                    int identity = vo.getType();//代理类型（0：未审核，1：总代，2：普代，3：未认证）
                    int isBlack = vo.getState() == null ? 0 : vo.getState();//0正常/1黑名单
                    String masterId = vo.getAgentId();//总代id
                    BigDecimal totalCarry = vo.getSmileAgentVo().getTotalCarry();//总代票提
                    BigDecimal ordCarry = vo.getSmileAgentVo().getOrdCarry();//普代票提
                    KylinAgentVo agentVo = KylinAgentVo.getNew();
                    agentVo.setIdentity(identity);
                    agentVo.setIsBlack(isBlack);
                    agentVo.setAgentId(agentId);
                    /*if (isBlack == 1) {
                        agentVo.setAgentMasterId("0");
                        agentVo.setCarry(BigDecimal.ZERO);
                        agentVo.setExCarry(BigDecimal.ZERO);
                        agentVo.setAgentId("0");
                    } else {
                        if (agentId.equals(masterId)) {
                            agentVo.setAgentMasterId("0");
                            agentVo.setCarry(totalCarry);
                            agentVo.setExCarry(BigDecimal.ZERO);
                        } else {
                            agentVo.setAgentMasterId(masterId);
                            agentVo.setCarry(ordCarry);
                            agentVo.setExCarry(totalCarry.subtract(ordCarry));
                        }
                    }*/
                    if (agentId.equals(masterId)) {
                        agentVo.setAgentMasterId("0");
                        agentVo.setCarry(totalCarry);
                        agentVo.setExCarry(BigDecimal.ZERO);
                    } else {
                        agentVo.setAgentMasterId(masterId);
                        agentVo.setCarry(ordCarry);
                        agentVo.setExCarry(totalCarry.subtract(ordCarry));
                    }
                    return agentVo;
                } else {
                    return null;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
