package com.ruoyi.web.modules.technology.support;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.technology.domain.BizPracticalTraining;

/**
 * 实战业务培训入参校验。
 */
public final class PracticalTrainingValidation
{
    private static final String DATE_PATTERN = "yyyy-MM-dd";

    private PracticalTrainingValidation()
    {
    }

    public static void trimFieldsForSave(BizPracticalTraining row)
    {
        if (row == null)
        {
            return;
        }
        if (row.getTrainingTopic() != null)
        {
            row.setTrainingTopic(row.getTrainingTopic().trim());
        }
        if (row.getTrainingIntro() != null)
        {
            row.setTrainingIntro(row.getTrainingIntro().trim());
        }
        if (row.getTrainingLocation() != null)
        {
            row.setTrainingLocation(row.getTrainingLocation().trim());
        }
        if (row.getExpectedOutcome() != null)
        {
            String outcome = row.getExpectedOutcome().trim();
            row.setExpectedOutcome(outcome.isEmpty() ? null : outcome);
        }
        if (row.getCoverFileUrl() != null)
        {
            row.setCoverFileUrl(row.getCoverFileUrl().trim());
        }
        if (row.getCoverFilePath() != null)
        {
            row.setCoverFilePath(row.getCoverFilePath().trim());
        }
        if (row.getRemark() != null)
        {
            String remark = row.getRemark().trim();
            row.setRemark(remark.isEmpty() ? null : remark);
        }
    }

    public static void validateTrainingTopic(String trainingTopic)
    {
        if (StringUtils.isEmpty(trainingTopic)
                || trainingTopic.length() < PracticalTrainingRules.MIN_TOPIC_LEN
                || trainingTopic.length() > PracticalTrainingRules.MAX_TOPIC_LEN)
        {
            throw new ServiceException("培训主题不能超过20个字符");
        }
    }

    public static void validateTrainingIntro(String trainingIntro)
    {
        if (StringUtils.isEmpty(trainingIntro))
        {
            throw new ServiceException("请填写培训简介");
        }
        if (trainingIntro.length() > PracticalTrainingRules.MAX_INTRO_LEN)
        {
            throw new ServiceException("培训简介不能超过500个字符");
        }
    }

    public static void validateTrainingLocation(String trainingLocation)
    {
        if (StringUtils.isEmpty(trainingLocation)
                || trainingLocation.length() < PracticalTrainingRules.MIN_LOCATION_LEN
                || trainingLocation.length() > PracticalTrainingRules.MAX_LOCATION_LEN)
        {
            throw new ServiceException("培训地点须为1～200个字符");
        }
    }

    public static void validatePlannedHeadCount(Integer plannedHeadCount)
    {
        if (plannedHeadCount == null || plannedHeadCount < 1)
        {
            throw new ServiceException("计划人数须为正整数");
        }
    }

    public static void validateTimeChain(Date registrationStartTime, Date registrationEndTime, Date trainingTime)
    {
        if (registrationStartTime == null)
        {
            throw new ServiceException("报名开始时间不能为空");
        }
        if (registrationEndTime == null)
        {
            throw new ServiceException("报名截止时间不能为空");
        }
        if (trainingTime == null)
        {
            throw new ServiceException("培训时间不能为空");
        }
        if (!registrationStartTime.before(registrationEndTime))
        {
            throw new ServiceException("报名开始时间须早于报名截止时间");
        }
        if (!registrationEndTime.before(trainingTime))
        {
            throw new ServiceException("报名截止时间须早于培训时间");
        }
    }

    public static void validateCoverPair(String coverUrl, String coverPath)
    {
        boolean hasUrl = StringUtils.isNotEmpty(coverUrl);
        boolean hasPath = StringUtils.isNotEmpty(coverPath);
        if (hasUrl != hasPath)
        {
            throw new ServiceException("封面 url 与 path 须同时填写或同时为空");
        }
        if (!hasPath)
        {
            return;
        }
        if (!PracticalTrainingRules.isCoverExtensionAllowed(coverPath))
        {
            throw new ServiceException("仅支持 jpg、png 格式");
        }
        if (!coverPath.startsWith(Constants.RESOURCE_PREFIX))
        {
            throw new ServiceException("封面存储路径非法");
        }
    }

    public static void validateRemark(String remark)
    {
        if (remark != null && remark.length() > PracticalTrainingRules.MAX_REMARK_LEN)
        {
            throw new ServiceException("备注不能超过500个字符");
        }
    }

    public static void validateRowForSave(BizPracticalTraining row)
    {
        trimFieldsForSave(row);
        validateTrainingTopic(row.getTrainingTopic());
        validateTrainingIntro(row.getTrainingIntro());
        validatePlannedHeadCount(row.getPlannedHeadCount());
        validateTrainingLocation(row.getTrainingLocation());
        validateTimeChain(row.getRegistrationStartTime(), row.getRegistrationEndTime(), row.getTrainingTime());
        validateCoverPair(row.getCoverFileUrl(), row.getCoverFilePath());
        validateRemark(row.getRemark());
    }

    public static void validateForUpdate(BizPracticalTraining db)
    {
        if (db == null)
        {
            throw new ServiceException("记录不存在或已删除");
        }
        if (!PracticalTrainingRules.canEdit(db.getPublishStatus()))
        {
            throw new ServiceException("已发布培训须先下架后再修改");
        }
    }

    public static void validateForDelete(BizPracticalTraining db)
    {
        if (db == null)
        {
            throw new ServiceException("记录不存在或已删除");
        }
        if (!PracticalTrainingRules.canDelete(db.getPublishStatus()))
        {
            throw new ServiceException("已发布培训须先下架后再删除");
        }
        Integer actual = db.getActualEnrolledCount();
        if (actual != null && actual > 0)
        {
            throw new ServiceException("存在报名记录，无法删除");
        }
    }

    public static void validateForPublish(BizPracticalTraining db)
    {
        if (db == null)
        {
            throw new ServiceException("记录不存在或已删除");
        }
        if (!PracticalTrainingRules.canPublish(db.getPublishStatus()))
        {
            throw new ServiceException("培训已发布，不可重复发布");
        }
    }

    public static void validateOffline(BizPracticalTraining db, Date now)
    {
        if (db == null)
        {
            throw new ServiceException("记录不存在或已删除");
        }
        if (!PracticalTrainingRules.canOffline(db.getPublishStatus()))
        {
            throw new ServiceException("仅「已发布」可下架");
        }
        if (now == null || db.getRegistrationStartTime() == null
                || !now.before(db.getRegistrationStartTime()))
        {
            throw new ServiceException("报名已开始，不允许下架");
        }
    }

    public static void validateListDateRange(String startDate, String endDate)
    {
        boolean hasStart = StringUtils.isNotEmpty(startDate);
        boolean hasEnd = StringUtils.isNotEmpty(endDate);
        if (!hasStart && !hasEnd)
        {
            return;
        }
        Date start = hasStart ? parseQueryDate(startDate, "培训日期开始") : null;
        Date end = hasEnd ? parseQueryDate(endDate, "培训日期结束") : null;
        if (start != null && end != null && start.after(end))
        {
            throw new ServiceException("培训日期开始不能晚于结束");
        }
    }

    private static Date parseQueryDate(String text, String label)
    {
        try
        {
            return new SimpleDateFormat(DATE_PATTERN).parse(text.trim());
        }
        catch (ParseException ex)
        {
            throw new ServiceException(label + "格式须为 yyyy-MM-dd");
        }
    }
}
