/*
 * 文 件 名:  DateService
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  <描述>
 * 修 改 人:  lvwenbin
 * 修改时间:  2025/5/9
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.huashe.common.data.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.huashe.common.data.config.CollectConfig;
import com.huashe.common.data.mapper.AdmHolidayMapper;
import com.huashe.common.data.service.DateService;
import com.huashe.common.domain.model.DateAttr;
import com.huashe.common.domain.model.Holiday;
import com.huashe.common.exception.Assert;
import com.huashe.common.exception.BusinessException;
import com.huashe.common.utils.DateUtils;
import com.huashe.common.utils.HttpUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 日期服务
 * <功能详细描述>
 *
 * @author lvwenbin
 * @version [版本号, 2025/5/9]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Service
public class DateServiceImpl implements DateService {
    private static final Logger log = LoggerFactory.getLogger(DateServiceImpl.class);

    @Resource
    private CollectConfig collectConfig;

    @Resource
    private AdmHolidayMapper holidayMapper;

    @Override
    public void collectHoliday(String year) {
        try {
            String dfUrl = StringUtils.replace(collectConfig.getHolidayColUrl(), "#year#", year);

            log.debug("get url:\r\n{}", dfUrl);
            String res = HttpUtils.doGet(dfUrl);
            log.debug("get res:\r\n{}", res);
            JSONObject jsonObject = JSON.parseObject(res);

            String bodyYear = jsonObject.getString("year");
            Assert.isTrue(StringUtils.equals(year, bodyYear), -1, "data error.");
            JSONArray jsonArray = jsonObject.getJSONArray("dates");

            if (!jsonArray.isEmpty()) {
                List<Holiday> holidays = convert(jsonArray);
                holidayMapper.deleteByYear(year);
                holidayMapper.insertBatch(holidays);
            }
        }
        catch (Exception e) {
            log.error("collectRt fail!", e);
        }
    }

    @Cacheable(value = "dateAttr", key = "#dateStr")
    @Override
    public DateAttr getDateAttr(String dateStr) {
        Date date = DateUtils.stringToDate(dateStr, "yyyy-MM-dd");
        Holiday holiday = holidayMapper.selectByDate(dateStr);
        return buildDateAttr(date, holiday);
    }

    @Override
    public List<DateAttr> getDateAttr(String startDateStr, String endDateStr) {
        List<DateAttr> result = new ArrayList<>();
        List<Holiday> holidays = holidayMapper.selectBetween(startDateStr, endDateStr);
        Map<String, Holiday> holidayMap = new HashMap<>();

        if (CollectionUtils.isNotEmpty(holidays)) {
            holidays.forEach(holiday -> {
                holidayMap.put(DateUtils.dateToString(holiday.getDate(), "yyyy-MM-dd"), holiday);
            });
        }

        Date date = DateUtils.stringToDate(startDateStr, "yyyy-MM-dd");
        Date endDate = DateUtils.stringToDate(endDateStr, "yyyy-MM-dd");

        while (date.before(endDate)) {
            Holiday holiday = holidayMap.get(DateUtils.dateToString(date, "yyyy-MM-dd"));
            result.add(buildDateAttr(date, holiday));
            date = DateUtils.adjustDay(date, 1);
        }

        return result;
    }

    private String buildWeekCn(int i) {
        String ret = null;
        switch (i) {
            case Calendar.MONDAY:
                ret = "星期一";
                break;
            case Calendar.TUESDAY:
                ret = "星期二";
                break;
            case Calendar.WEDNESDAY:
                ret = "星期三";
                break;
            case Calendar.THURSDAY:
                ret = "星期四";
                break;
            case Calendar.FRIDAY:
                ret = "星期五";
                break;
            case Calendar.SATURDAY:
                ret = "星期六";
                break;
            case Calendar.SUNDAY:
                ret = "星期日";
                break;
            default:
                throw new BusinessException(-1, "week error.");
        }

        return ret;
    }

    private DateAttr buildDateAttr(Date date, Holiday holiday) {
        DateAttr dateAttr = new DateAttr();
        dateAttr.setDate(DateUtils.dateToString(date, "yyyy-MM-dd"));

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        dateAttr.setWeek(dayOfWeek);
        dateAttr.setWeekCn(buildWeekCn(dayOfWeek));

        if (holiday != null) {
            dateAttr.setType(holiday.getType());
            dateAttr.setDateName(holiday.getName());
        }
        else {
            if (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) {
                dateAttr.setType("ordinary_weekend");
                dateAttr.setDateName("普通周末");
            }
            else {
                dateAttr.setType("working_day");
                dateAttr.setDateName("工作日");
            }
        }

        return dateAttr;
    }

    private List<Holiday> convert(JSONArray jsonArray) {
        List<Holiday> holidays = new ArrayList<>();

        jsonArray.forEach(item -> {
            JSONObject jsonObject = (JSONObject) item;
            Holiday holiday = new Holiday();
            holiday.setDate(jsonObject.getDate("date"));
            holiday.setName(jsonObject.getString("name"));
            holiday.setNameCn(jsonObject.getString("name_cn"));
            holiday.setNameEn(jsonObject.getString("name_en"));
            holiday.setType(jsonObject.getString("type"));
            holidays.add(holiday);
        });

        return holidays;
    }
}