package com.liquidnet.service.order.utils;

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IPUtil;
import com.liquidnet.service.adam.dto.vo.AdamEntersVo;
import com.liquidnet.service.candy.constant.CandyRedisConst;
import com.liquidnet.service.candy.dto.CandyUserCouponAssocDto;
import com.liquidnet.service.goblin.constant.SmileRedisConst;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dao.KylinFreightChargeDao;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketTimesVo;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketVo;
import com.liquidnet.service.kylin.dto.vo.mongo.*;
import com.liquidnet.service.kylin.dto.vo.returns.KylinOrderListVo;
import com.liquidnet.service.kylin.dto.vo.returns.KylinOrderRefundsVo;
import com.liquidnet.service.kylin.entity.KylinOrderCoupons;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
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.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Pattern;

@Component
public class DataUtils {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private RedisUtil redisUtil;

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

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


    public void setOrderList(String userId, List<KylinOrderListVo> vo) {
        redisUtil.set(KylinRedisConst.ORDER_LIST + userId, vo);
    }

    public int incrOrderRefundCode(String orderCode) {
       return (int) redisUtil.incr(KylinRedisConst.ORDER_REFUND_TEMP + orderCode,1);
    }

    public List<KylinOrderListVo> getOrderList(String userId) {
        Object obj = redisUtil.get(KylinRedisConst.ORDER_LIST + userId);
        if (obj != null) {
            return (List<KylinOrderListVo>) obj;
        } else {
            List<KylinOrderListVo> voList = mongoTemplate.find(Query.query(Criteria.where("userId").is(userId))
                            .with(Sort.by(Sort.Direction.DESC, "createdAt")).limit(40),
                    KylinOrderListVo.class, KylinOrderTicketVo.class.getSimpleName());
            for (KylinOrderListVo item : voList) {
                item.setStatus(item.getStatus());
            }
            redisUtil.set(KylinRedisConst.ORDER_LIST + userId, voList);
            return voList;
        }
    }

    /**
     * 根据订单id 获取 订单vo 详情
     *
     * @param orderId
     * @return
     */
    public KylinOrderTicketVo getOrderTicketVo(String orderId) {
        Object obj = redisUtil.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);
            redisUtil.set(KylinRedisConst.ORDER + orderId, ticketData);
            return ticketData;
        }
    }

    /**
     * 删除订单redis
     *
     * @param orderId
     */
    public void delOrderTicketRedis(String orderId) {
        redisUtil.del(KylinRedisConst.ORDER + orderId);
    }


    /**
     * @param performanceId 演出id
     * @param ticketId      票种id
     * @param buyCount      购买数量 大于 0 增加 小于 0 减少 对应 支付 退款表
     */
    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) {
            redisUtil.incr(ticketIdKeyUid, buyCount);
            redisUtil.incr(performanceIdKeyUid, buyCount);
            if (isTrueName != 0) {
                redisUtil.incr(ticketIdKeyIdCard, buyCount);
                redisUtil.incr(performanceIdKeyIdCard, buyCount);
            }
        } else {
            if (isTrueName != 0) {
                redisUtil.decr(ticketIdKeyIdCard, Math.abs(buyCount));
                redisUtil.decr(performanceIdKeyIdCard, Math.abs(buyCount));
            }
            redisUtil.decr(ticketIdKeyUid, Math.abs(buyCount));
            redisUtil.decr(performanceIdKeyUid, Math.abs(buyCount));
        }

    }


    // 获取 用户维度 演出购买数量
    public int getUserPBuyCount(String userId, String performanceId) {
        try {
            return (int) redisUtil.get(KylinRedisConst.USERID_BUY_INFO + userId + ":" + KylinRedisConst.PERFORMANCE_ID + ":" + performanceId);
        } catch (Exception e) {
            return 0;
        }
    }

    // 获取 用户维度 票种购买数量
    public int getUserTBuyCount(String userId, String ticketId) {
        try {
            return (int) redisUtil.get(KylinRedisConst.USERID_BUY_INFO + userId + ":" + KylinRedisConst.TICKET_ID + ":" + ticketId);
        } catch (Exception e) {
            return 0;
        }
    }

    // 获取 证件维度 演出购买数量
    public int getIdCardPBuyCount(String idCard, String performanceId) {
        try {
            return (int) redisUtil.get(KylinRedisConst.IDCARD_BUY_INFO + idCard + ":" + KylinRedisConst.PERFORMANCE_ID + ":" + performanceId);
        } catch (Exception e) {
            return 0;
        }
    }

    // 获取 证件维度 票种购买数量
    public int getIdCardTBuyCount(String idCard, String ticketId) {
        try {
            return (int) redisUtil.get(KylinRedisConst.IDCARD_BUY_INFO + idCard + ":" + KylinRedisConst.TICKET_ID + ":" + ticketId);
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * 删除订单redis
     *
     * @param orderEntitiesId
     */
    public void delOrderTicketEntitiesRedis(String orderEntitiesId) {
        redisUtil.del(KylinRedisConst.ORDER_ENTITIES + orderEntitiesId);
    }

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

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

    public void setOrderCoupon(String orderId, List<KylinOrderCoupons> bean) {
        String redisKey = KylinRedisConst.ORDER_COUPON.concat(orderId);
        redisUtil.set(redisKey, bean);
    }

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

    public KylinIpAreaVo getKylinIpAreaVo(String ipAddress) {
//        List<KylinIpAreaVo> data = mongoTemplate.find(Query.query(Criteria.where("ipBeginLong").lte(IPUtil.ipToLong(ipAddress))
//                .and("ipEndLong").gte(IPUtil.ipToLong(ipAddress))), KylinIpAreaVo.class, KylinIpAreaVo.class.getSimpleName());
//        if(data==null || data.size()==0){
        KylinIpAreaVo data0 = KylinIpAreaVo.getNew();
        data0.setArea("未知");
        data0.setCity("未知");
        data0.setCounty("未知");
        data0.setProvince("未知");
        return data0;
//        }else{
//            return data.get(0);
//        }
    }

    public void setEnterVo(AdamEntersVo vo) {
        String redisKey = KylinRedisConst.ADAM_ENTER_VO.concat(vo.getEntersId());
        Object obj = redisUtil.set(redisKey, vo, 60 * 60 * 24 * 90);
    }

    public AdamEntersVo getEnterVo(String enterId) {
        String redisKey = KylinRedisConst.ADAM_ENTER_VO.concat(enterId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (AdamEntersVo) obj;
        }
    }

    // 1普通会员 2老会员
    public Integer getMember(String uid) {
        String redisKey = KylinRedisConst.ADAM_IS_MEMBER
                .concat(uid);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (Integer) obj;
        }
    }

    // 获取快递价格
    public BigDecimal getExpressPrice(String adCode, String productCode) {
        BigDecimal price;
        Object obj = redisUtil.get(KylinRedisConst.RETURN_ADDRESS_CODE + adCode + KylinRedisConst.EXPRESS_TYPE + productCode);
        if (obj != null) {
            KylinFreightChargeDao k = (KylinFreightChargeDao) obj;
            //运费为0元时返23元
            if (k.getPrice().equals("0.00")) {
                price = new BigDecimal("23.00");
            }
            price = new BigDecimal(k.getPrice());
        } else {
            //查询不到运费数据时返回23元
            price = new BigDecimal("23.00");
        }
        return price;
    }

    public String getTicketPayTxt(String ticketId) {
        String rdsKey = KylinRedisConst.TICKET_PAY_TXT.concat(ticketId);
        Object obj = redisUtil.get(rdsKey);
        if (obj == null) {
            return "";
        } else {
            return (String) obj;
        }
    }

    //根据 券id 获取 可用巡演id数组
    public List<String> getCouponRoad(String couponId) {
        String rdk = KylinRedisConst.COUPON_ROADSHOWS.concat(couponId);
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    public int incrUseCouponCount(String uid, String performanceId) {
        String rdk = KylinRedisConst.COUPON_COUNT.concat(uid).concat(":").concat(performanceId);
        return (int) redisUtil.incr(rdk, 1);
    }

    public int decrUseCouponCount(String uid, String performanceId) {
        String rdk = KylinRedisConst.COUPON_COUNT.concat(uid).concat(":").concat(performanceId);
        return (int) redisUtil.decr(rdk, 1);
    }

    public int incrUseMemberCount(String uid, String performanceId) {
        String rdk = KylinRedisConst.MEMBER_COUNT.concat(uid).concat(":").concat(performanceId);
        return (int) redisUtil.incr(rdk, 1);
    }

    public int decrUseMemberCount(String uid, String performanceId) {
        String rdk = KylinRedisConst.MEMBER_COUNT.concat(uid).concat(":").concat(performanceId);
        return (int) redisUtil.decr(rdk, 1);
    }

//    public int getUseCouponCount(String uid,String performanceId){
//        String rdk = KylinRedisConst.COUPON_COUNT.concat(uid).concat(":").concat(performanceId);
//        Object obj = redisUtil.get(rdk);
//        if(obj==null){
//            return 0;
//        }else{
//            return (int) obj;
//        }
//    }

    public int getUseCouponCount(String uid, String performanceId) {
        String rdk = KylinRedisConst.COUPON_COUNT.concat(uid).concat(":").concat(performanceId);
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return 0;
        } else {
            return (int) obj;
        }
    }

    /**
     * 保存演出ids smile 小家伙可分销演出
     */
    /**
     * 获取演出ids
     */
    public List<String> getShowIds() {
        String rdk = SmileRedisConst.SMILE_SHOW;
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    /**
     * 根据券id查询适用人证件信息
     * @param ucouponId
     * @return
     */
    public CandyUserCouponAssocDto getGoblinPlatformCoupon(String ucouponId) {
        String rdk = CandyRedisConst.BASIC_USER_COUPON_ASSOC.concat(ucouponId);
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return null;
        } else {
            return (CandyUserCouponAssocDto) obj;
        }
    }
}
