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 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 String judgeOrderLimit(
            String userId,
            String idCard,
            String performanceId,
            String ticketId,
            int performanceLimitCount,
            int performanceMemberLimitCount,
            int performanceLimitIdCard,
            int ticketLimitCount,
            int ticketMemberLimitCount,
            int ticketLimitIdCard,
            int memberType,
            int isTrueName
    ) {
        Integer[] integers = orderLimit(userId, idCard, performanceId, ticketId, isTrueName);
        return judgeMemberType(performanceLimitCount, performanceMemberLimitCount, performanceLimitIdCard,
                ticketLimitCount, ticketMemberLimitCount, ticketLimitIdCard,
                memberType, integers[0], integers[1], integers[2], integers[3], isTrueName);
    }

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

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

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

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

        if (memberType == 1 || memberType == 2) {
            if (isTrueName == 1) {
                if (performanceBuyCountIdCard > performanceMemberLimitCount && performanceMemberLimitCount != 0) {
                    return "实名制演出限购" + performanceMemberLimitCount + "张，已超出";//超过演出维度购买量
                }
                if (ticketBuyCountIdCard > ticketMemberLimitCount && ticketMemberLimitCount != 0) {
                    return "实名制票种限购" + ticketMemberLimitCount + "张，已超出";//超过票维度购买量
                }
            } else {
                if (performanceBuyCountUid > performanceMemberLimitCount && performanceMemberLimitCount != 0) {
                    return "本场演出限购" + performanceMemberLimitCount + "张，已超出";//超过演出维度购买量
                }
                if (ticketBuyCountUid > ticketMemberLimitCount && ticketMemberLimitCount != 0) {
                    return "该票种限购" + ticketMemberLimitCount + "张，已超出";//超过票维度购买量
                }
            }
        } else {//非会员区间
            if (isTrueName == 1) {
                if (performanceBuyCountIdCard > performanceLimitIdCard && performanceLimitIdCard != 0) {
                    return "实名制演出限购" + performanceLimitIdCard + "张，已超出";//超过演出维度购买量
                }
                if (ticketBuyCountIdCard > ticketLimitIdCard && ticketLimitIdCard != 0) {
                    return "实名制票种限购" + ticketLimitIdCard + "张，已超出";//超过演出维度购买量
                }
                if (performanceBuyCountUid > performanceLimitCount && performanceLimitCount != 0) {
                    return "本场演出限购" + performanceLimitCount + "张，已超出";//超过演出维度购买量
                }
                if (ticketBuyCountUid > ticketLimitCount && ticketLimitCount != 0) {
                    return "该票种限购" + ticketLimitCount + "张，已超出";//超过演出维度购买量
                }
            } else {
                if (performanceBuyCountUid > performanceLimitCount && performanceLimitCount != 0) {
                    return "本场演出限购" + performanceLimitCount + "张，已超出";//超过演出维度购买量
                }
                if (ticketBuyCountUid > ticketLimitCount && ticketLimitCount != 0) {
                    return "该票种限购" + ticketLimitCount + "张，已超出";//超过演出维度购买量
                }
            }
        }
        return "";
    }


    //判断 操作 普通库存还是兑换库存
    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;
        }
    }
}
