package com.sqx.modules.activity.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.sqx.common.exception.SqxException;
import com.sqx.modules.activity.bo.ShopActivityBO;
import com.sqx.modules.activity.dto.ActivityOfFullReductionDTO;
import com.sqx.modules.activity.dto.ActivityOfGlobalDiscountDTO;
import com.sqx.modules.activity.dto.ActivityOfTimeIntervalDTO;
import com.sqx.modules.activity.entity.Activity;
import com.sqx.modules.activity.enums.ActivityTypeEnum;
import com.sqx.modules.activity.vo.ActivityVO;
import org.springframework.beans.BeanUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.function.Consumer;

/**
 * activity工具集合
 *
 * @author : codingliang
 * @date : 2024-06-22 18:01
 */
public class ActivityUtil {
    /**
     * Activity转ActivityVO
     * @param activity 活动信息
     * @return
     */
    public static ActivityVO convertActivityEntityToVO(Activity activity) {
        ActivityVO vo = new ActivityVO();
        BeanUtils.copyProperties(activity, vo);

        parseActivityConfig(activity.getType(), activity.getConfig(), e -> {
            if (e instanceof ActivityOfFullReductionDTO) {
                vo.setFullReductionInfo((ActivityOfFullReductionDTO) e);
            } else if (e instanceof ActivityOfGlobalDiscountDTO) {
                vo.setGlobalDiscountsInfo((ActivityOfGlobalDiscountDTO) e);
            } else {
                vo.setTimeIntervalInfos((List<ActivityOfTimeIntervalDTO>) e);
            }
        });
        return vo;
    }

    /**
     * 解析ShopActivityBO中的config
     * @param shopActivityBO 店铺活动信息
     * @return
     */
    public static ShopActivityBO parseActivityConfig(ShopActivityBO shopActivityBO) {
        String config = shopActivityBO.getConfig();
        String type = shopActivityBO.getType();
        parseActivityConfig(type, config, e -> {
            if (e instanceof ActivityOfFullReductionDTO) {
                shopActivityBO.setFullReductionInfo((ActivityOfFullReductionDTO) e);
            } else if (e instanceof ActivityOfGlobalDiscountDTO) {
                shopActivityBO.setGlobalDiscountsInfo((ActivityOfGlobalDiscountDTO) e);
            } else {
                shopActivityBO.setTimeIntervalInfos((List<ActivityOfTimeIntervalDTO>) e);
            }
        });

        return shopActivityBO;
    }

    /**
     * 解析活动config
     * @param type 活动类型
     * @param config 活动配置字符串
     * @param consumer 回调
     */
    public static void parseActivityConfig(String type, String config, Consumer consumer) {
        if (ActivityTypeEnum.TIME.getTypeCode().equals(type)) {
            consumer.accept(JSONUtil.toList(JSONUtil.parseArray(config), ActivityOfTimeIntervalDTO.class));
        } else if (ActivityTypeEnum.FULL.getTypeCode().equals(type)) {
            consumer.accept(JSONUtil.toBean(config, ActivityOfFullReductionDTO.class));
        } else if (ActivityTypeEnum.GLOBAL.getTypeCode().equals(type)) {
            consumer.accept(JSONUtil.toBean(config, ActivityOfGlobalDiscountDTO.class));
        } else if (ActivityTypeEnum.NORMAL.getTypeCode().equals(type)){
            // not to do
        } else {
            throw new SqxException("活动类型不存在");
        }
    }

    /**
     * 判断活动是否适用于当前时间段
     * @param activityVO 活动信息
     * @return true or false
     */
    public static Boolean judgeActivitySuitCurTime(ActivityVO activityVO) {
        if (ObjectUtil.isNull(activityVO)) return false;

        // 非时段优惠活动直接返回true
        if (!ActivityTypeEnum.TIME.getTypeCode().equals(activityVO.getType())) return true;

        // 时段优惠根据具体的时间端配置判定
        return ActivityUtil.getCurTimeTimeActivity(activityVO.getTimeIntervalInfos()) != null;
    }

    /**
     * 判断活动是否适用于当前时间段
     * @param shopActivityBO 店铺活动信息
     * @return true or false
     */
    public static Boolean judgeActivitySuitCurTime(ShopActivityBO shopActivityBO) {
        if (ObjectUtil.isNull(shopActivityBO)) return false;

        // 非时段优惠活动直接返回true
        if (!ActivityTypeEnum.TIME.getTypeCode().equals(shopActivityBO.getType())) return true;

        // 时段优惠根据具体的时间端配置判定
        return ActivityUtil.getCurTimeTimeActivity(shopActivityBO.getTimeIntervalInfos()) != null;
    }

    /**
     * 获取符合当前时间段内的时段优惠活动
     * @param timeConfigs 时段配置信息
     * @return 符合的活动或者null
     */
    public static ActivityOfTimeIntervalDTO getCurTimeTimeActivity(List<ActivityOfTimeIntervalDTO> timeConfigs) {
        LocalDate curDate = LocalDate.now();
        LocalDateTime now = LocalDateTime.now();

        for (ActivityOfTimeIntervalDTO timeIntervalInfo : timeConfigs) {
            String startTimeStr = timeIntervalInfo.getStartTime();
            String endTimeStr = timeIntervalInfo.getEndTime();

            LocalDateTime startTime = LocalDateTime.of(curDate, LocalTime.parse(startTimeStr));
            LocalDateTime endTime;
            if (startTimeStr.compareTo(endTimeStr) > 0) {
                // endTime需要加一天
                endTime = LocalDateTime.of(curDate.plusDays(1), LocalTime.parse(endTimeStr));
            } else {
                endTime = LocalDateTime.of(curDate, LocalTime.parse(endTimeStr));
            }

            if (now.isAfter(startTime) && now.isBefore(endTime)) {
                return timeIntervalInfo;
            }
        }

        return null;
    }
}
