package com.xjrsoft.module.holiday.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.utils.DateUtils;
import com.xjrsoft.common.utils.HolidayUtil;
import com.xjrsoft.module.holiday.dto.AddHolidayDateDto;
import com.xjrsoft.module.holiday.entity.HolidayDate;
import com.xjrsoft.module.holiday.mapper.HolidayDateMapper;
import com.xjrsoft.module.holiday.service.IHolidayDateService;
import com.xjrsoft.module.holiday.vo.AlmanacVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @title:
 * @Author fanxp
 * @Date: 2024-03-26
 * @Version 1.0
 */
@Service
@AllArgsConstructor
public class HolidayDateServiceImpl extends MPJBaseServiceImpl<HolidayDateMapper, HolidayDate> implements IHolidayDateService {

    private final HolidayDateMapper holidayDateMapper;

    /**
     * 当前时间是否休息
     */
    public Boolean currentIsRest() {
        LocalDateTime now = LocalDateTime.now();
        String day = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        Long count = holidayDateMapper.selectCount(Wrappers.<HolidayDate>query().lambda()
                .eq(HolidayDate::getDate, day)
                .eq(HolidayDate::getStatus,3)
        );
        return count > 0;
    }

    /**
     * 添加数据
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(AddHolidayDateDto dto) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date start = sdf.parse(dto.getStartDate());
        Date end = sdf.parse(dto.getEndDate());

        if (start.compareTo(end) > 0) {
            throw new MyException("开始时间不能大于结束时间！");
        }

        while (start.compareTo(end) <= 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(start);

            HolidayDate param = HolidayDate.builder()
                    .date(sdf.format(start))
                    .way(2)
                    .year(calendar.get(Calendar.YEAR))
                    .month(calendar.get(Calendar.MONTH) + 1)
                    .day(calendar.get(Calendar.DATE))
                    .status(dto.getStatus())
                    .build();
            holidayDateMapper.insert(param);
            start = DateUtils.addDateDays(start, 1);
        }
        return true;
    }

    /**
     * 删除数据
     *
     * @param ids
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(List<Long> ids) {
        List<HolidayDate> holidayDates = holidayDateMapper.selectBatchIds(ids);
        for (HolidayDate h : holidayDates) {
            // 用户数据直接删除，系统数据添加标识
            if (h.getWay() == 1) {
                h.setDeleteStatus(1);
                holidayDateMapper.updateById(h);
            } else {
                holidayDateMapper.deleteById(h.getId());
            }
        }
        return true;
    }

    /**
     * 初始化节假日
     *
     * @param year
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean initHoliday(int year) {
        List<HolidayDate> allList = new ArrayList<>();
        for (int month = 1; month < 13; month++) {
            List<HolidayDate> monthList = getYearMonthHoliday(year, month);
            allList.addAll(monthList);
        }
//        List<HolidayDate> monthList = getYearMonthHoliday(year - 1, 12);
//        allList.addAll(monthList);

        Map<String, HolidayDate> mData = allList.stream().collect(Collectors.toMap(HolidayDate::getDate, item -> item));
        // 获取用户数据
        List<HolidayDate> userDates = holidayDateMapper.selectList(Wrappers.<HolidayDate>query().lambda().eq(HolidayDate::getYear, year).eq(HolidayDate::getWay, 2));
        for (HolidayDate uh : userDates) {
            mData.keySet().removeIf(key -> Objects.equals(key, uh.getDate()));
        }
        // 清除系统数据
        holidayDateMapper.delete(Wrappers.<HolidayDate>query().lambda().eq(HolidayDate::getYear, year).eq(HolidayDate::getWay, 1));
        // 保存系统数据
        for (Map.Entry<String, HolidayDate> entry : mData.entrySet()) {
            holidayDateMapper.insert(entry.getValue());
        }
        return true;
    }

    /**
     * Init month list.
     * 按月爬取节假日
     *
     * @param year  the year
     * @param month the month
     * @return the list
     */
    public static List<HolidayDate> getYearMonthHoliday(int year, int month) {
        List<HolidayDate> holidayDateList = new ArrayList<>();
        try {
            String result = HolidayUtil.getMonth(year + "", month + "");
            JSONObject json = JSON.parseObject(result);
            System.out.println(result);
            JSONArray data = json.getJSONArray("data");
            JSONObject dataObj = JSON.parseObject(data.get(0).toString());
            List<AlmanacVo> almanacs = JSONArray.parseArray(dataObj.getString("almanac"), AlmanacVo.class);
            for (AlmanacVo almanac : almanacs) {
                if (almanac.getMonth().equals(String.valueOf(month)) && almanac.getStatus() != null) {
                    HolidayDate date = HolidayDate.builder()
                            .year(year).month(month).day(Integer.parseInt(almanac.getDay()))
                            .date(DateUtils.format(new Date(year - 1900, month - 1, Integer.parseInt(almanac.getDay())), "yyyy-MM-dd"))
                            .build();
                    String status = almanac.getStatus();
                    if (status.equals("1")) {
                        date.setStatus(3);
                    } else if (status.equals("2")) {
                        date.setStatus(2);
                    }
                    holidayDateList.add(date);
                }
            }
        } catch (ClassCastException classCastException) {
            throw new MyException("可能是当前月份(" + month + "月)没有节日");
        } catch (Exception e) {
            throw new MyException(e.getMessage());
        }
        return holidayDateList;
    }


}
