package com.kingdee.eas.custom.integration.beisen.validator;

import com.kingdee.eas.custom.integration.beisen.dto.AttendanceRequest;
import com.kingdee.eas.custom.integration.beisen.enums.ReportType;
import com.kingdee.eas.custom.integration.beisen.exception.BeisenErrorCodes;
import com.kingdee.eas.custom.integration.beisen.exception.BeisenIntegrationException;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.regex.Pattern;

/**
 * 考勤数据校验器
 */
public class AttendanceValidator {

    /** 日期格式 yyyy-MM-dd */
    private static final Pattern DATE_PATTERN =
            Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$");

    /** 考勤周期格式 yyyyMM */
    private static final Pattern PERIOD_PATTERN =
            Pattern.compile("^\\d{6}$");

    /**
     * 校验单条考勤记录，返回错误信息（不抛异常）。
     * 用于批量写入场景，单条校验失败不影响其他记录。
     *
     * @param request    请求对象
     * @param reportType 报表类型
     * @return 校验通过返回 null，否则返回错误信息
     */
    public static String validateAndGetError(AttendanceRequest request, ReportType reportType) {
        try {
            validate(request, reportType);
        } catch (BeisenIntegrationException e) {
            return e.getMessage();
        }
        return null;
    }

    /**
     * 校验考勤写入请求
     *
     * @param request    请求对象
     * @param reportType 报表类型
     * @throws BeisenIntegrationException 校验失败时抛出
     */
    public static void validate(AttendanceRequest request, ReportType reportType) {
        if (request == null) {
            throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "请求体不能为空");
        }

        // 校验员工工号
        if (StringUtils.isBlank(request.getPersonNumber())) {
            throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "员工工号(personNumber)不能为空");
        }


        // 校验考勤日期/周期（日报用日期，月报用周期）
        if (ReportType.DAILY.equals(reportType)) {
            if (StringUtils.isBlank(request.getAttendanceDate())) {
                throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "考勤日期(attendanceDate)不能为空");
            }
            if (!DATE_PATTERN.matcher(request.getAttendanceDate()).matches()) {
                throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "考勤日期(attendanceDate)格式错误，正确格式为: yyyy-MM-dd");
            }
        } else if (ReportType.MONTHLY.equals(reportType)) {
            if (StringUtils.isBlank(request.getAttendancePeriod())) {
                throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "考勤周期(attendancePeriod)不能为空");
            }
            if (!PERIOD_PATTERN.matcher(request.getAttendancePeriod()).matches()) {
                throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "考勤周期(attendancePeriod)格式错误，正确格式为: yyyyMM");
            }
        }

        // 校验行政组织编码
        if (StringUtils.isBlank(request.getAdminOrgCode())) {
            throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "行政组织编码(adminOrgCode)不能为空");
        }

        // 校验岗位编码
        if (StringUtils.isBlank(request.getPositionCode())) {
            throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "岗位编码(positionCode)不能为空");
        }

        // 校验动态参数
        Map<String, Object> dynamicParams = request.getDynamicParams();
        if (dynamicParams == null || dynamicParams.isEmpty()) {
            throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "考勤明细参数(dynamicParams)不能为空，需至少包含一个考勤项目数据");
        }

        // 校验动态参数的键和值
        for (Map.Entry<String, Object> entry : dynamicParams.entrySet()) {
            if (StringUtils.isBlank(entry.getKey())) {
                throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "考勤明细参数中包含空的考勤项目编码");
            }
            if (entry.getKey().length() > 100) {
                throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "考勤项目编码[" + entry.getKey() + "]长度不能超过100位");
            }
            if (entry.getValue() == null) {
                throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "考勤项目[" + entry.getKey() + "]的值为空");
            }
            if (!(entry.getValue() instanceof Number) && !(entry.getValue() instanceof String)) {
                throw new BeisenIntegrationException(BeisenErrorCodes.VALIDATION_ERROR, "考勤项目[" + entry.getKey() + "]的值类型不支持，仅支持数字或字符串");
            }
        }
    }
}
