package cn.ey.biz.module.system.service.category.dynamic.service;

import cn.ey.biz.common.util.date.DateUtils;
import cn.ey.biz.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.ey.biz.module.system.api.category.dto.CategoryDynamicReq;
import cn.ey.biz.module.system.dal.dataobject.category.DictWeekDO;
import cn.ey.biz.module.system.dal.mapper.category.DictWeekMapper;
import cn.ey.biz.module.system.enums.ErrorCodeConstants;
import cn.ey.biz.module.system.enums.category.CategoryCodeEnum;
import cn.hutool.core.date.LocalDateTimeUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static cn.ey.biz.common.exception.util.ServiceExceptionUtil.exception;


@Service(DictWeekServiceImpl.CATEGORY_CODE + IBaseService.BASE_SERVICE_NAME)
public class DictWeekServiceImpl implements IBaseService {

    public static final String CATEGORY_CODE = "FiscalWeek";

    @Resource
    private DictWeekMapper dictWeekMapper;

    @Override
    public List<Map<String, Object>> get(HttpServletRequest request, HttpServletResponse response, CategoryDynamicReq req) {
        return dictWeekMapper.selectMaps(null);
    }

    /**
     * 获取当前日期前18个月后的财年周数据
     *
     * @param req 请求参数
     * @return 前18个月后的财年周数据
     */
    public List<Map<String, Object>> get18Month(HttpServletRequest request, HttpServletResponse response, CategoryDynamicReq req) {
        LocalDateTime before = LocalDateTime.now().minusMonths(18L);
        return dictWeekMapper.selectMaps(new LambdaQueryWrapperX<DictWeekDO>()
                .gt(DictWeekDO::getBeginDate, before));
    }

    /**
     * 获取查询日期所在的财年周数据
     *
     * @param req 请求参数   requestBody (key - dayDate)
     * @return 日期所在的财年周数据
     */
    public List<Map<String, Object>> getFiscalWeekByDate(HttpServletRequest request, HttpServletResponse response, CategoryDynamicReq req) {
        Map<String, Object> params = this.checkParams(CategoryCodeEnum.FunctionTypeConstants.DICT_WEEK_FISCAL_WEEK_BY_DATE, req);
        LocalDateTime parse = (LocalDateTime) params.get(DickWeekCustomParam.DAY_DATE.getValue());
        return dictWeekMapper.selectMaps(new LambdaQueryWrapperX<DictWeekDO>()
                .and(query -> query.le(DictWeekDO::getStartTime, parse).ge(DictWeekDO::getEndTime, parse))
        );
    }

    /**
     * 获取财周中所有财年列表
     *
     * @return  财年列表
     */
    public List<String> getAllFiscalYear(HttpServletRequest request, HttpServletResponse response, CategoryDynamicReq req) {
        return dictWeekMapper.getAllFiscalYear();
    }

    enum DickWeekCustomParam {
        /**
         * 查询日期
         */
        DAY_DATE("dayDate");

        final String value;

        DickWeekCustomParam(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }
    }


    @Override
    public Map<String, Object> checkParams(String functionType, CategoryDynamicReq req) {
        boolean nullError = false;
        boolean otherError = false;
        StringBuilder errorMsg = new StringBuilder();
        Map<String, Object> result = req.getRequestBody();
        // FiscalWeekByDate
        if (CategoryCodeEnum.FunctionTypeConstants.DICT_WEEK_FISCAL_WEEK_BY_DATE.equals(functionType)) {
            nullError = (result == null || result.get(DickWeekCustomParam.DAY_DATE.getValue()) == null);
            if (!nullError) {
                try {
                    String dayDate = (String) req.getRequestBody().get(DickWeekCustomParam.DAY_DATE.getValue());
                    LocalDateTime parse = LocalDateTimeUtil.parse(dayDate, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
                    result.put(DickWeekCustomParam.DAY_DATE.getValue(), parse);
                } catch (Exception e) {
                    otherError = true;
                }
            }
            if (nullError || otherError) {
                errorMsg.append(DickWeekCustomParam.DAY_DATE.getValue());
            }
        }

        if (nullError || otherError) {
            throw exception(ErrorCodeConstants.CATEGORY_DATA_REQUEST_BODY_PARAMETER_ERROR, errorMsg.toString());
        }
        return result;
    }
}
