package com.centreproject.system.service.park.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.centreproject.common.constant.GuestConstants;
import com.centreproject.common.constant.KeyConstants;
import com.centreproject.common.utils.DateUtils;
import com.centreproject.common.websocket.BusinessSocketHandler;
import com.centreproject.common.websocket.MyWebSocketHandler;
import com.centreproject.system.domain.kpi.park.ParkEvents;
import com.centreproject.system.domain.vo.RevenueTrackingDetailVo;
import com.centreproject.system.domain.vo.RevenueTrackingVo;
import com.centreproject.system.mapper.park.ParkEventsMapper;
import com.centreproject.system.service.guestExperience.impl.KpiParkGuestExperienceServiceImpl;
import com.centreproject.system.service.park.IParkEventsService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * park events
 * @author zhonglei.xu
 */
@Service
public class ParkEventsServiceImpl extends ServiceImpl<ParkEventsMapper, ParkEvents>
        implements IParkEventsService {
    private final Logger logger = LoggerFactory.getLogger(ParkEventsServiceImpl.class);
    @Autowired
    private RedisTemplate<String, List<ParkEvents>> redisTemplate;
    @Autowired
    private ParkEventsMapper mapper;
    @Autowired
    private MyWebSocketHandler myWebSocketHandler;
    private static final ZoneId RIYADH_ZONE = ZoneId.of("Asia/Riyadh");

    /**
     * get park events by park code
     *
     * @param parkCode parkCode
     * @return park events list
     */
    @Override
    public List<ParkEvents> getParkEvents(String parkCode) {
        String redisKey = KeyConstants.PARK_EVENTS + DateUtils.getRiDate() +parkCode+ GuestConstants.LATEST_60_DAYS;

        // 1. 查缓存
        List<ParkEvents> cached = redisTemplate.opsForValue().get(redisKey);
        if (null!=cached) {
            return cached;
        }
        // 带时区的获取当前日期
        LocalDate today = DateUtils.getNowLocalDate();

        LambdaQueryWrapper<ParkEvents> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ParkEvents::getParkCode, parkCode)
                .le(ParkEvents::getStartDate, today)
                .ge(ParkEvents::getEndDate, today);
        List<ParkEvents> parkEvents = mapper.selectList(wrapper);

        // Step 2: 格式化时间文本（核心逻辑）
        List<ParkEvents> results = parkEvents.stream().peek(event -> {
            // 日期格式转换
            event.setTime(formatDateRange(event.getStartDate(), event.getEndDate()));
        }).collect(Collectors.toList());
        if(ObjectUtils.isNotEmpty(results)){
            redisTemplate.opsForValue().set(redisKey, results, 10, TimeUnit.MINUTES);
        }
        return results;
    }

    /**
     * 格式化日期范围为指定文本（核心工具方法）
     */
    private String formatDateRange(Date startDate, Date endDate) {
        // 1. 将Date转换为LocalDate（使用系统默认时区）
        LocalDate start = startDate.toInstant().atZone(RIYADH_ZONE).toLocalDate();
        LocalDate end = endDate.toInstant().atZone(RIYADH_ZONE).toLocalDate();

        // 2. 月份缩写格式化器（如 Aug、Jun，大写英文）
        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMM", Locale.ENGLISH)
                .withLocale(Locale.ENGLISH);

        int startDay = start.getDayOfMonth();
        String startMonth = start.format(monthFormatter).toUpperCase();
        int endDay = end.getDayOfMonth();
        String endMonth = end.format(monthFormatter).toUpperCase();

        // 3. 判断是否同一月份
        if (start.getMonth() == end.getMonth() && start.getYear() == end.getYear()) {
            // 同一月：日-日 月份缩写（如 28-31 AUG）
            return String.format("%d-%d %s", startDay, endDay, startMonth);
        } else {
            // 不同月：日 月份缩写-日 月份缩写（如 2 JUN-3 DEC）
            return String.format("%d %s-%d %s", startDay, startMonth, endDay, endMonth);
        }
    }



    @Scheduled(fixedRate = 30000) // 每30秒执行一次
    public void pushParkEventsToRedis() {
        // 带时区的获取当前日期
        LocalDate today = DateUtils.getNowLocalDate();

        LambdaQueryWrapper<ParkEvents> wrapper = new LambdaQueryWrapper<>();
        wrapper.le(ParkEvents::getStartDate, today)
                .ge(ParkEvents::getEndDate, today);
        List<ParkEvents> parkEvents = mapper.selectList(wrapper);
        // Step 2: 格式化时间文本（核心逻辑）
        List<ParkEvents> results = parkEvents.stream().peek(event -> {
            // 日期格式转换
            event.setTime(formatDateRange(event.getStartDate(), event.getEndDate()));
        }).collect(Collectors.toList());
        if(ObjectUtils.isNotEmpty(results)){
            Map<String, List<ParkEvents>> map =
                    results.stream().collect(Collectors.groupingBy(ParkEvents::getParkCode));
            // 3. 按园区分组推送
            map.forEach((parkCode, parkEventsList) -> {
                // 构建每个园区的独立消息
                Map<String, Object> message = new HashMap<>();
                message.put("module", KeyConstants.PARK_EVENTS+parkCode);
                message.put("data", parkEventsList);
                message.put("timestamp", System.currentTimeMillis());
                // 转换为JSON并推送
                String jsonData = JSON.toJSONString(message);
                myWebSocketHandler.broadcast(jsonData);
                logger.info("模块{}园区[{}]数据推送成功，项目数量: {}",KeyConstants.PARK_EVENTS, parkCode, parkEventsList.size());
            });
        }
    }

}
