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

import java.util.Calendar;
import java.util.Date;
import java.util.regex.Pattern;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.innovation.domain.BizTechProjectGuide;

/**
 * 科技项目指南入参校验。
 */
public final class TechProjectGuideValidation
{
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");

    private TechProjectGuideValidation()
    {
    }

    public static void trimFieldsForSave(BizTechProjectGuide row)
    {
        if (row == null)
        {
            return;
        }
        if (row.getProjectName() != null)
        {
            row.setProjectName(row.getProjectName().trim());
        }
        if (row.getProjectIntro() != null)
        {
            row.setProjectIntro(row.getProjectIntro().trim());
        }
        if (row.getApplicationTarget() != null)
        {
            row.setApplicationTarget(row.getApplicationTarget().trim());
        }
        if (row.getProjectPeriod() != null)
        {
            row.setProjectPeriod(row.getProjectPeriod().trim());
        }
        if (row.getApplicationConditions() != null)
        {
            row.setApplicationConditions(row.getApplicationConditions().trim());
        }
        if (row.getApplicationProcess() != null)
        {
            row.setApplicationProcess(row.getApplicationProcess().trim());
        }
        if (row.getPersonInCharge() != null)
        {
            row.setPersonInCharge(row.getPersonInCharge().trim());
        }
        if (row.getContactPhone() != null)
        {
            row.setContactPhone(row.getContactPhone().trim());
        }
        if (row.getAttachmentFileUrl() != null)
        {
            row.setAttachmentFileUrl(row.getAttachmentFileUrl().trim());
        }
        if (row.getAttachmentFilePath() != null)
        {
            row.setAttachmentFilePath(row.getAttachmentFilePath().trim());
        }
        if (row.getAttachmentFileName() != null)
        {
            row.setAttachmentFileName(row.getAttachmentFileName().trim());
        }
        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 validateProjectName(String projectName)
    {
        if (StringUtils.isEmpty(projectName) || projectName.length() < 1 || projectName.length() > 20)
        {
            throw new ServiceException("项目名称须为1～20个字符");
        }
    }

    public static void validateProjectType(String projectTypeCode)
    {
        if (StringUtils.isEmpty(projectTypeCode))
        {
            throw new ServiceException("项目类型不能为空");
        }
        if (projectTypeCode.length() > 32)
        {
            throw new ServiceException("项目类型编码过长");
        }
    }

    public static void validateProjectIntro(String projectIntro)
    {
        if (StringUtils.isEmpty(projectIntro) || projectIntro.length() < 1 || projectIntro.length() > 50)
        {
            throw new ServiceException("项目简介须为1～50个字符");
        }
    }

    public static void validateApplicationTarget(String applicationTarget)
    {
        if (StringUtils.isEmpty(applicationTarget) || applicationTarget.length() < 1 || applicationTarget.length() > 200)
        {
            throw new ServiceException("申报对象须为1～200个字符");
        }
    }

    public static void validateApplicationDateRange(Date startDate, Date endDate)
    {
        if (startDate == null)
        {
            throw new ServiceException("申报开始日期不能为空");
        }
        if (endDate == null)
        {
            throw new ServiceException("申报截止日期不能为空");
        }
        Calendar start = Calendar.getInstance();
        start.setTime(startDate);
        truncateToDay(start);
        Calendar end = Calendar.getInstance();
        end.setTime(endDate);
        truncateToDay(end);
        if (end.before(start))
        {
            throw new ServiceException("申报截止日期不能早于开始日期");
        }
    }

    public static void validateProjectPeriod(String projectPeriod)
    {
        if (StringUtils.isEmpty(projectPeriod) || projectPeriod.length() < 1 || projectPeriod.length() > 50)
        {
            throw new ServiceException("项目周期须为1～50个字符");
        }
    }

    public static void validateApplicationConditions(String applicationConditions)
    {
        if (StringUtils.isEmpty(applicationConditions))
        {
            throw new ServiceException("申报条件不能为空");
        }
    }

    public static void validateApplicationProcess(String applicationProcess)
    {
        if (StringUtils.isEmpty(applicationProcess))
        {
            throw new ServiceException("申报流程不能为空");
        }
    }

    public static void validatePersonInCharge(String personInCharge)
    {
        if (StringUtils.isEmpty(personInCharge) || personInCharge.length() < 1 || personInCharge.length() > 10)
        {
            throw new ServiceException("负责人须为1～10个字符");
        }
    }

    public static void validateContactPhone(String contactPhone)
    {
        if (StringUtils.isEmpty(contactPhone) || !PHONE_PATTERN.matcher(contactPhone).matches())
        {
            throw new ServiceException("联系方式须为合法大陆手机号");
        }
    }

    public static void validateAttachmentTriple(String url, String path, String fileName)
    {
        boolean hasUrl = StringUtils.isNotEmpty(url);
        boolean hasPath = StringUtils.isNotEmpty(path);
        boolean hasName = StringUtils.isNotEmpty(fileName);
        if (hasUrl != hasPath || hasUrl != hasName)
        {
            throw new ServiceException("附件 url、path、文件名须同时填写或同时为空");
        }
        if (!hasPath)
        {
            return;
        }
        String checkName = StringUtils.isNotEmpty(fileName) ? fileName : path;
        if (!TechProjectGuideRules.isAttachmentExtensionAllowed(checkName))
        {
            throw new ServiceException("附件格式不支持，允许：pdf、md、doc、docx、xls、xlsx、ppt、pptx");
        }
        if (!path.startsWith(Constants.RESOURCE_PREFIX))
        {
            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 (!TechProjectGuideRules.isCoverExtensionAllowed(coverPath))
        {
            throw new ServiceException("封面格式不支持，允许：jpg、jpeg、png");
        }
        if (!coverPath.startsWith(Constants.RESOURCE_PREFIX))
        {
            throw new ServiceException("封面存储路径非法");
        }
    }

    public static void validateRowForSave(BizTechProjectGuide row)
    {
        trimFieldsForSave(row);
        validateProjectName(row.getProjectName());
        validateProjectIntro(row.getProjectIntro());
        validateApplicationTarget(row.getApplicationTarget());
        validateApplicationDateRange(row.getApplicationStartDate(), row.getApplicationEndDate());
        validateProjectPeriod(row.getProjectPeriod());
        validateApplicationConditions(row.getApplicationConditions());
        validateApplicationProcess(row.getApplicationProcess());
        validatePersonInCharge(row.getPersonInCharge());
        validateContactPhone(row.getContactPhone());
        validateAttachmentTriple(row.getAttachmentFileUrl(), row.getAttachmentFilePath(), row.getAttachmentFileName());
        validateCoverPair(row.getCoverFileUrl(), row.getCoverFilePath());
    }

    private static void truncateToDay(Calendar cal)
    {
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
    }
}
