package com.kym.service.impl;


import com.github.pagehelper.PageHelper;
import com.kym.common.utils.CommUtil;
import com.kym.common.utils.IDGenerator;
import com.kym.entity.*;
import com.kym.entity.queryParams.ActivityQueryParam;
import com.kym.entity.vo.ActivityVo;
import com.kym.entity.common.PageBean;
import com.kym.entity.common.RedisKeys;
import com.kym.mapper.ActivityMapper;
import com.kym.service.*;
import com.kym.service.mybatisplus.MyBaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;

import static com.kym.entity.Activity.*;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author skyline
 * @since 2023-10-18
 */
@Service
@Slf4j
public class ActivityServiceImpl extends MyBaseServiceImpl<ActivityMapper, Activity> implements ActivityService {

    private final ActivityStationService activityStationService;
    private final BannerService bannerService;
    private final CouponService couponService;

    private final RedisTemplate<String, String> redisTemplate;


    public ActivityServiceImpl(ActivityStationService activityStationService,
                               BannerService bannerService, CouponService couponService, RedisTemplate<String, String> redisTemplate) {
        this.activityStationService = activityStationService;
        this.bannerService = bannerService;
        this.couponService = couponService;
        this.redisTemplate = redisTemplate;
    }

    /**
     * 新增活动
     *
     * @param activityVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createActivity(ActivityVo activityVo) {
        // 新增activity
        var activity = new Activity();
        BeanUtils.copyProperties(activityVo, activity);
        activity.setId(IDGenerator.INS().nextId());
        save(activity);

        // 新增activityStation 活动-站点关联
        if (activityVo.getApplyStation() == APPLY_STATION_部分站点 && !CommUtil.isEmptyOrNull(activityVo.getStationIds())) {
            var activityStationList = activityVo.getStationIds().stream().map(stationId -> new ActivityStation().setActivityId(activity.getId()).setStationId(stationId)).toList();
            activityStationService.saveBatch(activityStationList);
        }


        // 新增优惠券活动
        if (activityVo.getDiscountType().equals(Activity.DISCOUNT_TYPE_优惠券) && !CommUtil.isEmptyOrNull(activityVo.getCouponList())) {
            List<Coupon> couponList = activityVo.getCouponList().stream().peek(coupon -> {
                BeanUtils.copyProperties(activity, coupon, "id", "name");
                coupon.setActivityId(activity.getId());
//                coupon.setStatus(Coupon.STATUS_有效);
            }).collect(Collectors.toList());
            couponService.saveBatch(couponList);
        }

        // TODO 加入活动延迟启停队列
    }


    /**
     * 主活动列表
     *
     * @param params
     * @return
     */
    @Override
    public PageBean<Activity> listActivity(ActivityQueryParam params) {
        PageHelper.startPage(params.getPageNum(), params.getPageSize());
        var list = lambdaQuery()
                .like(!CommUtil.isEmptyOrNull(params.getName()), Activity::getName, params.getName())
                .eq(params.getStatus() != null, Activity::getStatus, params.getStatus())
                .eq(params.getDiscountType() != null, Activity::getDiscountType, params.getDiscountType())
                .gt(params.getStartTime() != null, Activity::getStartTime, params.getStartTime())
                .lt(params.getEndTime() != null, Activity::getEndTime, params.getEndTime())
                .orderByDesc(Activity::getId)
                .list();
        return new PageBean<>(list);
    }

    /**
     * 活动详情
     *
     * @param activityId
     * @return
     */
    @Override
    public ActivityVo activityDetail(String activityId) {
        var activity = lambdaQuery().eq(Activity::getId, activityId).one();
        var activityVo = new ActivityVo();
        BeanUtils.copyProperties(activity, activityVo);
         if (activity.getDiscountType().equals(DISCOUNT_TYPE_优惠券)) {
            List<Coupon> couponList = couponService.lambdaQuery().eq(Coupon::getActivityId, activityId).list();
            activityVo.setCouponList(couponList);
            var activityStationIds = activityStationService.lambdaQuery().eq(ActivityStation::getActivityId, activityId).list().stream().map(ActivityStation::getStationId).toList();
            if (CommUtil.isNotEmptyAndNull(activityStationIds)) {
                activityVo.setStationIds(activityStationIds);
//                var stationList = stationService.lambdaQuery().in(Station::getStationId, activityStationIds).list();
//                activityVo.setStationList(stationList);
            }
        }
        return activityVo;
    }

    /**
     * 终止活动
     *
     * @param activityId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void terminateActivity(String activityId) {
        var activity = lambdaQuery().eq(Activity::getId, activityId).one();
        if (activity != null) {
            // 根据活动类型分别处理
            if (activity.getDiscountType().equals(Activity.DISCOUNT_TYPE_优惠券)) {
                var couponList = couponService.lambdaQuery().eq(Coupon::getActivityId, activityId).list();
                // 优惠券状态修改为已结束
                if (CommUtil.isNotEmptyAndNull(couponList)) {
                    couponService.updateBatchById(couponList.stream().peek(coupon -> coupon.setStatus(Activity.STATUS_已结束)).toList());

                    // redis 优惠券失效，删除数据
                    var userCoupons = redisTemplate.opsForSet().members(RedisKeys.COUPON_ID_TO_USERS);
                    if (userCoupons != null) {
                        couponList.forEach(coupon -> {
                            // 筛选出活动相关的数据
                            var coupon2user = userCoupons.stream().filter(userCoupon -> userCoupon.startsWith(String.valueOf(coupon.getId()))).toArray();
                            if (coupon2user.length > 0) {
                                redisTemplate.opsForSet().remove(RedisKeys.COUPON_ID_TO_USERS, coupon2user);
                            }
                        });
                    }

                }
            }
            // 修改活动状态
            lambdaUpdate().set(Activity::getStatus, Activity.STATUS_已结束).eq(Activity::getId, activityId).update();

            // 修改站点活动关联表状态
            activityStationService.lambdaUpdate().set(ActivityStation::getStatus, Activity.STATUS_已结束).eq(ActivityStation::getActivityId, activityId).update();
        }

    }

}
