package com.liquidnet.service.consumer.order.utils;

import com.alibaba.fastjson.JSON;
import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.HttpUtil;
import com.liquidnet.service.candy.param.BackCouponParam;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketEntitiesVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.dto.vo.returns.KylinOrderListVo;
import com.liquidnet.service.kylin.entity.KylinOrderCoupons;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;

import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class KylinOrderUtils {

    @Value("${liquidnet.service.candy.url}")
    private String candyUrl;
//    @Autowired
//    private RedisUtil redisUtil;
    @Autowired
    private RedisDataSourceUtil redisDataSourceUtil;
    @Autowired
    private MongoTemplate mongoTemplate;

    //--------              TICKET              --------
    /**
     * 根据订单id 获取 订单vo 详情
     *
     * @param orderId
     * @return
     */
    public KylinOrderTicketVo getOrderTicketVo(String orderId) {
        Object obj = redisDataSourceUtil.getRedisKylinUtil().get(KylinRedisConst.ORDER + orderId);
        if (obj!=null) {
            return (KylinOrderTicketVo)obj;
        } else {
            KylinOrderTicketVo ticketData = mongoTemplate.findOne(Query.query(Criteria.where("orderTicketsId").is(orderId)), KylinOrderTicketVo.class, KylinOrderTicketVo.class.getSimpleName());
            List<KylinOrderTicketEntitiesVo> kylinOrderTicketEntitiesVoList = mongoTemplate.find(Query.query(Criteria.where("orderId").is(orderId)), KylinOrderTicketEntitiesVo.class, KylinOrderTicketEntitiesVo.class.getSimpleName());
            ticketData.setEntitiesVoList(kylinOrderTicketEntitiesVoList);
            redisDataSourceUtil.getRedisKylinUtil().set(KylinRedisConst.ORDER + orderId, ticketData);
            return ticketData;
        }
    }

    public void setOrderTicketVo(String orderId, KylinOrderTicketVo vo) {
        String redisKey = KylinRedisConst.ORDER + orderId;
        redisDataSourceUtil.getRedisKylinUtil().set(redisKey, vo);
    }

    /**
     * @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 = new ArrayList<>();
        List<KylinOrderListVo> redisVo = new ArrayList();
        KylinOrderTicketVo data = dataSingle;
        KylinOrderListVo voItem = KylinOrderListVo.getNew().copy(data);
        List<KylinOrderListVo> redisData = (List<KylinOrderListVo>) redisDataSourceUtil.getRedisKylinUtil().get(KylinRedisConst.ORDER_LIST + userId);
        if(redisData==null){
            return false;
        }
        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);
                }
                redisDataSourceUtil.getRedisKylinUtil().set(KylinRedisConst.ORDER_LIST + 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));
                    }
                }
                redisDataSourceUtil.getRedisKylinUtil().set(KylinRedisConst.ORDER_LIST + userId, vo);
                return true;
            default:
                return false;
        }
    }

    /**
     * 限购处理
     * @param userId
     * @param idCard
     * @param performanceId
     * @param ticketId
     * @param buyCount
     */
    public void changeBuyInfo(String userId, String idCard, String performanceId, String ticketId, int buyCount) {
        String redisKeyUid;
        String redisKeyIdCard;
        String performanceIdKeyIdCard="";
        String ticketIdKeyIdCard="";

        int isTrueName = getPerformanceIsTrueName(performanceId);

        redisKeyUid = KylinRedisConst.USERID_BUY_INFO + userId;
        redisKeyIdCard = KylinRedisConst.IDCARD_BUY_INFO + idCard;
        String performanceIdKeyUid = redisKeyUid + ":" + KylinRedisConst.PERFORMANCE_ID + ":" + performanceId;
        String ticketIdKeyUid = redisKeyUid + ":" + KylinRedisConst.TICKET_ID + ":" + ticketId;
        if (isTrueName != 0) {
            performanceIdKeyIdCard = redisKeyIdCard + ":" + KylinRedisConst.PERFORMANCE_ID + ":" + performanceId;
            ticketIdKeyIdCard = redisKeyIdCard + ":" + KylinRedisConst.TICKET_ID + ":" + ticketId;
        }

        if (buyCount > 0) {
            redisDataSourceUtil.getRedisKylinUtil().incr(ticketIdKeyUid, buyCount);
            redisDataSourceUtil.getRedisKylinUtil().incr(performanceIdKeyUid, buyCount);
            if (isTrueName != 0) {
                redisDataSourceUtil.getRedisKylinUtil().incr(ticketIdKeyIdCard, buyCount);
                redisDataSourceUtil.getRedisKylinUtil().incr(performanceIdKeyIdCard, buyCount);
            }
        } else {
            if (isTrueName != 0) {
                redisDataSourceUtil.getRedisKylinUtil().decr(ticketIdKeyIdCard, Math.abs(buyCount));
                redisDataSourceUtil.getRedisKylinUtil().decr(performanceIdKeyIdCard, Math.abs(buyCount));
            }
            redisDataSourceUtil.getRedisKylinUtil().decr(ticketIdKeyUid, Math.abs(buyCount));
            redisDataSourceUtil.getRedisKylinUtil().decr(performanceIdKeyUid, Math.abs(buyCount));
        }
    }

    /**
     * 演出是否实名
     *
     * @param performanceId
     */
    public int getPerformanceIsTrueName(String performanceId) {
        Object obj = redisDataSourceUtil.getRedisKylinUtil().get(KylinRedisConst.PERFORMANCES_TRUE_NAME + performanceId);
        if (obj != null) {
            return (int) obj;
        } else {
            int isTrueName = getPerformanceVo(performanceId).getIsTrueName();
            redisDataSourceUtil.getRedisKylinUtil().set(KylinRedisConst.PERFORMANCES_TRUE_NAME + performanceId, isTrueName);
            return isTrueName;
        }
    }

    /**
     * 根据演出id 获取 演出vo 详情
     *
     * @param performanceId
     * @return
     */
    public KylinPerformanceVo getPerformanceVo(String performanceId) {
        if (redisDataSourceUtil.getRedisKylinUtil().hasKey(KylinRedisConst.PERFORMANCES + performanceId)) {
        } else {
            KylinPerformanceVo performanceData = mongoTemplate.findOne(Query.query(Criteria.where("performancesId").is(performanceId)), KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());
            redisDataSourceUtil.getRedisKylinUtil().set(KylinRedisConst.PERFORMANCES + performanceId, performanceData);
        }
        return (KylinPerformanceVo) redisDataSourceUtil.getRedisKylinUtil().get(KylinRedisConst.PERFORMANCES + performanceId);
    }

    /**
     * 修改普通库存 并 返回修改后的数量
     *
     * @param ticketId       票id
     * @param surplusGeneral 普通库存
     * @return 普通剩余库存
     */
    public int changeSurplusGeneral(String ticketId, int surplusGeneral) {
        if (surplusGeneral > 0) {
            return (int) redisDataSourceUtil.getRedisKylinUtil().incr(KylinRedisConst.PERFORMANCES_INVENTORY + ticketId + ":" + KylinRedisConst.SURPLUS_GENERAL, surplusGeneral);
        } else {
            return (int) redisDataSourceUtil.getRedisKylinUtil().decr(KylinRedisConst.PERFORMANCES_INVENTORY + ticketId + ":" + KylinRedisConst.SURPLUS_GENERAL, Math.abs(surplusGeneral));
        }
    }

    // 获取订单券的使用情况
    public ArrayList<KylinOrderCoupons> getOrderCoupon(String orderId) {
        String redisKey = KylinRedisConst.ORDER_COUPON.concat(orderId);
        Object obj = redisDataSourceUtil.getRedisKylinUtil().get(redisKey);
        if (obj == null) {
            return getKylinOrderCouponsArrayList();
        } else {
            return (ArrayList<KylinOrderCoupons>) obj;
        }
    }

    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);
        }
    }

    private static final ArrayList<KylinOrderCoupons> kylinOrderCouponsArrayList = new ArrayList<>();
    public static ArrayList<KylinOrderCoupons> getKylinOrderCouponsArrayList() {
        return (ArrayList<KylinOrderCoupons>) kylinOrderCouponsArrayList.clone();
    }
}
