package com.czg.service.market.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.shaded.com.google.common.util.concurrent.RateLimiter;
import com.czg.account.entity.ShopConfig;
import com.czg.account.service.ShopConfigService;
import com.czg.market.service.AttendanceService;
import com.czg.market.vo.DingAttendanceStatsVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedDeque;

@Service
public class AttendanceServiceImpl implements AttendanceService {
    @Resource
    private DingService dingService;
    @Resource
    private ShopConfigService shopConfigService;

    @Override
    public ArrayList<DingAttendanceStatsVO> list(Long shopId, String name, String startTime, String endTime, String userId) {
        DateTime start;
        DateTime end;
        if (StrUtil.isBlank(startTime)) {
            start = DateUtil.beginOfMonth(new Date());
        } else {
            start = DateUtil.parse(startTime);
        }

        if (StrUtil.isBlank(endTime)) {
            end = DateUtil.date();
        } else {
            end = DateUtil.parse(endTime);
        }

        ShopConfig config = shopConfigService.getById(shopId);
        if (config == null || StrUtil.isBlank(config.getDingAppSecret())) {
            return new ArrayList<>();
        }

        return dingService.getUserReport(shopId, config.getDingAppKey(), config.getDingAppSecret(), start, end, name, userId);
    }

    // 自定义规则：1-5 → 数字, 6 → 六, 7 → 日
    private static String formatWeek(DateTime dateTime) {
        String chinese = DateUtil.dayOfWeekEnum(dateTime).toChinese();
        String week = switch (chinese) {
            case "星期六" -> "六";
            case "星期日" -> "日";
            default -> null;
        };
        if (week == null) {
            week = String.valueOf(DateUtil.dayOfMonth(dateTime));
        }
        return week;
    }

    @Override
    public Map<String, Object> detail(Long shopId, String userId, String startTime, String endTime, Integer weekNum) {
        ArrayList<DingAttendanceStatsVO> listed = list(shopId, null, startTime, endTime, userId);

        ArrayList<Map<String, Object>> weekList = new ArrayList<>();

// 结束时间：默认今天
        DateTime endDate = StrUtil.isBlank(endTime)
                ? DateUtil.date()
                : DateUtil.parse(endTime);

// 开始时间：默认当月1号
        DateTime startDate = StrUtil.isBlank(startTime)
                ? DateUtil.beginOfMonth(endDate)
                : DateUtil.parse(startTime);

// 若开始时间 > 结束时间，交换，避免死循环
        if (startDate.after(endDate)) {
            DateTime temp = startDate;
            startDate = endDate;
            endDate = temp;
        }

// 按天递增循环（跨月完全没问题）
        DateTime current = startDate;
        while (!current.after(endDate)) {

            String week = formatWeek(current);

            Map<String, Object> map = new HashMap<>();
            map.put("week", week);
            map.put("date", current);

            weekList.add(map);

            // 下一天
            current = DateUtil.offsetDay(current, 1);
        }


        if (listed.isEmpty()) {
            return new HashMap<String, Object>() {{
                put("attendanceSummary", null);
                put("weekList", weekList);
                put("statusList", null);
            }};
        }
        ShopConfig config = shopConfigService.getById(shopId);
        if (config == null || StrUtil.isBlank(config.getDingAppSecret())) {
            return new HashMap<String, Object>() {{
                put("attendanceSummary", null);
                put("weekList", weekList);
                put("statusList", null);
            }};
        }
        ConcurrentLinkedDeque<String> statusList = new ConcurrentLinkedDeque<>();
        RateLimiter rateLimiter = RateLimiter.create(15.0); // 每秒15次

        weekList.parallelStream().forEachOrdered(week -> {
            rateLimiter.acquire(); // 阻塞直到获取令牌（保证限流）
            statusList.add(
                    dingService.getAttendanceStatus(
                            config.getDingAppKey(),
                            config.getDingAppSecret(),
                            shopId,
                            (Date) week.get("date"),
                            userId
                    )
            );
        });

        return Map.of(
                "attendanceSummary", listed.getFirst(),
                "weekList", weekList,
                "statusList", statusList
        );
    }
}
