package com.liquidnet.service.kylin.service.impl;

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.constant.RedisKeyExpireConst;
import com.liquidnet.service.kylin.constant.GroupBuyStatusConst;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dto.vo.groupbuy.KylinGroupBuyActivityVo;
import com.liquidnet.service.kylin.dto.vo.groupbuy.KylinGroupBuyDiscountVo;
import com.liquidnet.service.kylin.dto.vo.groupbuy.KylinGroupBuyPriceVo;
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.KylinPerformanceVo;
import com.liquidnet.service.kylin.service.IKylinGroupBuyActivityService;
import com.liquidnet.service.kylin.utils.DataUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.Service;

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

@Service
@Slf4j
public class KylinGroupBuyActivityServiceImpl implements IKylinGroupBuyActivityService {

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

    @Override
    public ResponseDto<List<KylinGroupBuyActivityVo>> activities(String performanceId) {
        Query query = Query.query(Criteria.where("performanceId").is(performanceId)
                .and("status").is(GroupBuyStatusConst.ActivityStatus.ACTIVE));
        List<KylinGroupBuyActivityVo> list = mongoTemplate.find(query,
                KylinGroupBuyActivityVo.class, KylinGroupBuyActivityVo.class.getSimpleName());
        return ResponseDto.success(list);
    }

    @Override
    public ResponseDto<KylinGroupBuyPriceVo> price(String activityId, String timeId, String ticketId) {
        KylinGroupBuyActivityVo activity = getActiveActivity(activityId);
        if (activity == null) {
            return ResponseDto.failure("拼团活动不存在或未进行中");
        }
        KylinGroupBuyDiscountVo discount = findDiscount(activity, timeId, ticketId);
        if (discount == null) {
            return ResponseDto.failure("该票档不支持拼团");
        }
        BigDecimal originalPrice = getOriginalPrice(activity.getPerformanceId(), timeId, ticketId);
        if (originalPrice == null) {
            return ResponseDto.failure(ErrorMapping.get("20004"));
        }
        KylinGroupBuyPriceVo vo = new KylinGroupBuyPriceVo();
        vo.setActivityId(activityId);
        vo.setTimeId(timeId);
        vo.setTicketId(ticketId);
        vo.setOriginalPrice(originalPrice);
        vo.setDiscountType(discount.getDiscountType());
        vo.setDiscountValue(discount.getDiscountValue());
        vo.setGroupBuyPrice(discount.getDiscountValue());
        return ResponseDto.success(vo);
    }

    public KylinGroupBuyActivityVo getActiveActivity(String activityId) {
        if (activityId == null) {
            return null;
        }
        String redisKey = KylinRedisConst.GROUP_BUY_ACTIVITY.concat(activityId);
        Object obj = redisUtil.get(redisKey);
        if (obj != null) {
            KylinGroupBuyActivityVo activity = (KylinGroupBuyActivityVo) obj;
            return GroupBuyStatusConst.ActivityStatus.ACTIVE.equals(activity.getStatus()) ? activity : null;
        }
        Query query = Query.query(Criteria.where("activityId").is(activityId)
                .and("status").is(GroupBuyStatusConst.ActivityStatus.ACTIVE));
        KylinGroupBuyActivityVo activity = mongoTemplate.findOne(query, KylinGroupBuyActivityVo.class,
                KylinGroupBuyActivityVo.class.getSimpleName());
        if (activity != null) {
            redisUtil.set(redisKey, activity, RedisKeyExpireConst.KYLIN_GROUP_BUY_EXPIRE);
        }
        return activity;
    }

    public KylinGroupBuyDiscountVo findDiscount(KylinGroupBuyActivityVo activity, String timeId, String ticketId) {
        if (activity == null || activity.getDiscounts() == null) {
            return null;
        }
        for (KylinGroupBuyDiscountVo discount : activity.getDiscounts()) {
            if (timeId.equals(discount.getTimeId()) && ticketId.equals(discount.getTicketId())) {
                return discount;
            }
        }
        return null;
    }

    public BigDecimal getOriginalPrice(String performanceId, String timeId, String ticketId) {
        KylinPerformanceVo performanceVo = dataUtils.getPerformanceVo(performanceId);
        if (performanceVo == null || performanceVo.getTicketTimeList() == null) {
            return null;
        }
        for (KylinTicketTimesVo timeVo : performanceVo.getTicketTimeList()) {
            if (!timeId.equals(timeVo.getTimeId()) || timeVo.getTicketList() == null) {
                continue;
            }
            for (KylinTicketVo ticketVo : timeVo.getTicketList()) {
                if (ticketId.equals(ticketVo.getTicketsId())) {
                    return ticketVo.getPrice();
                }
            }
        }
        return null;
    }

}
