package com.starry.admin.modules.order.job;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
import com.starry.admin.modules.order.mapper.PlayOrderInfoMapper;
import com.starry.admin.modules.order.module.dto.OrderCompletionContext;
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
import com.starry.admin.modules.order.service.IOrderLifecycleService;
import com.starry.admin.modules.weichat.service.WxCustomMpService;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


@Slf4j
@Component
public class OrderJob {
    @Resource
    private PlayOrderInfoMapper orderInfoMapper;
    @Resource
    private WxCustomMpService wxCustomMpService;
    @Resource
    private IPlayClerkUserInfoService clerkUserInfoService;
    @Resource
    private IOrderLifecycleService orderLifecycleService;
    @Resource
    public RedisTemplate<String, Object> redisTemplate;


    /**
     * 每20秒执行一次的定时任务，修改订单状态为已完成
     */
    @Scheduled(fixedRate = 20000, initialDelay = 20000)
    public void orderFinishJob() {
        // 查询出所有应该完成的订单
        List<String> serviceDurationList = Arrays.asList("一周", "一个月", "一小时", "15分钟", "一天", "半小时", "30分钟");
        List<PlayOrderInfoEntity> orderInfoEntityList = orderInfoMapper.selectList(Wrappers.lambdaQuery(PlayOrderInfoEntity.class).isNotNull(PlayOrderInfoEntity::getServiceDuration)
                .eq(PlayOrderInfoEntity::getOrderStatus, "2")
                .eq(PlayOrderInfoEntity::getOrderType, "2")
                .isNotNull(PlayOrderInfoEntity::getOrderStartTime)
                .in(PlayOrderInfoEntity::getServiceDuration, serviceDurationList)
                .in(PlayOrderInfoEntity::getPlaceType, Arrays.asList("1", "0"))
        );
        if (CollectionUtils.isEmpty(orderInfoEntityList)) return;

        orderInfoEntityList.forEach(ca -> {
            try {
                // 根据serviceDuration换取时间
                Integer serviceDuration = this.getServiceDuration(ca.getServiceDuration());
                if (serviceDuration.equals(0)) return;

                // 判断与开始时间相比较，如果大于服务时长，则修改订单状态为已完成
                if (ca.getOrderStartTime().plusMinutes(serviceDuration).isBefore(LocalDateTime.now())) {
                    orderLifecycleService.completeOrder(
                            ca.getId(),
                            OrderCompletionContext.scheduler("auto finish by duration")
                                    .withForceNotify(true));
                }

            } catch (Exception e) {
                log.error(e.getMessage(), e);
                log.error("订单完成失败：{}", ca.getOrderNo());
            }
        });

    }

    @Scheduled(fixedRate = 20000, initialDelay = 20000)
    public void orderNoticeJob() {
        // 查询出所有应该待接单的订单,超过10分钟还没接单
        List<PlayOrderInfoEntity> orderInfoEntityList = orderInfoMapper.selectList(Wrappers.lambdaQuery(PlayOrderInfoEntity.class)
                .eq(PlayOrderInfoEntity::getOrderStatus, "0")
                .eq(PlayOrderInfoEntity::getPlaceType, "1")
                .lt(PlayOrderInfoEntity::getCreatedTime, DateUtil.offsetMinute(new Date(), -10)
                ));
        if (CollectionUtils.isEmpty(orderInfoEntityList)) return;

        orderInfoEntityList.forEach(orderInfo -> {
            try {
                // 半小时只能发一次，使用redis做频次限制
                if (Boolean.TRUE.equals(redisTemplate.hasKey("order_notice_" + orderInfo.getId()))) {
                    log.error("订单已催促,执行跳过：{}", orderInfo.getOrderNo());
                    return;
                }
                redisTemplate.opsForValue().set("order_notice_" + orderInfo.getId(), "1", 30, java.util.concurrent.TimeUnit.MINUTES);
                List<PlayClerkUserInfoEntity> clerkList = clerkUserInfoService.list(Wrappers.lambdaQuery(PlayClerkUserInfoEntity.class).isNotNull(PlayClerkUserInfoEntity::getOpenid).eq(PlayClerkUserInfoEntity::getClerkState, "1")
                        .eq(PlayClerkUserInfoEntity::getSex, orderInfo.getSex()).eq(PlayClerkUserInfoEntity::getTenantId, orderInfo.getTenantId()));
                wxCustomMpService.sendCreateOrderMessageBatch(
                        clerkList,
                        orderInfo.getOrderNo(),
                        orderInfo.getOrderMoney().toString(),
                        orderInfo.getCommodityName(),
                        orderInfo.getId(),
                        orderInfo.getPlaceType(),
                        orderInfo.getRewardType());

            } catch (Exception e) {
                log.error(e.getMessage(), e);
                log.error("订单催促失败：{}", orderInfo.getOrderNo());
            }
        });

    }

    private Integer getServiceDuration(String serviceDuration) {
        if (StringUtils.isEmpty(serviceDuration)) {
            throw new CustomException("服务时长不能为空");
        }
        switch (serviceDuration) {
            case "一周":
                return 7 * 24 * 60; // 一周 = 7天，每天24小时，每小时60分钟

            case "一个月":
                return 30 * 24 * 60; // 按30天计算一个月

            case "一小时":
                return 60; // 一小时 = 60分钟

            case "15分钟":
                return 15;
            case "一天":
                return 24 * 60; // 一天 = 24小时

            case "半小时":
                return 30; // 半小时 = 30分钟

            case "30分钟":
                return 30;
        }
        return 0;
    }

}
