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

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.industryservice.domain.BizGrasslandUsageRecord;

/**
 * 草场使用记录入参校验与使用天数计算。
 */
public final class GrasslandUsageValidation
{
    private static final String DATE_PATTERN = "yyyy-MM-dd";

    private static final BigDecimal ZERO = BigDecimal.ZERO;

    private GrasslandUsageValidation()
    {
    }

    public static int resolveActualUseDays(Date useStartDate, Date useEndDate)
    {
        validateUseDates(useStartDate, useEndDate);
        Calendar start = truncateToDay(useStartDate);
        Calendar end = truncateToDay(useEndDate);
        long diffMs = end.getTimeInMillis() - start.getTimeInMillis();
        int days = (int) (diffMs / (24L * 60 * 60 * 1000));
        return days + 1;
    }

    public static void validateGrasslandId(Long grasslandId)
    {
        if (grasslandId == null)
        {
            throw new ServiceException("草场不能为空");
        }
    }

    public static void validatePastureId(Long pastureId)
    {
        if (pastureId == null)
        {
            throw new ServiceException("养殖主体不能为空");
        }
    }

    public static void validateUsageAreaMu(BigDecimal usageAreaMu, BigDecimal grasslandAreaMu)
    {
        if (usageAreaMu == null || usageAreaMu.compareTo(ZERO) <= 0)
        {
            throw new ServiceException("使用面积须为大于0的数字（亩）");
        }
        if (grasslandAreaMu == null || usageAreaMu.compareTo(grasslandAreaMu) > 0)
        {
            throw new ServiceException("使用面积不能大于草场总面积");
        }
    }

    public static void validateUseDates(Date useStartDate, Date useEndDate)
    {
        if (useStartDate == null || useEndDate == null)
        {
            throw new ServiceException("开始使用、结束日期不能为空");
        }
        if (truncateToDay(useStartDate).after(truncateToDay(useEndDate)))
        {
            throw new ServiceException("开始使用日期不能晚于结束日期");
        }
    }

    public static void validateGrazingHeadCount(Integer grazingHeadCount)
    {
        if (grazingHeadCount == null || grazingHeadCount < 1)
        {
            throw new ServiceException("放牧数量须为大于等于1的整数（头）");
        }
    }

    public static void validateGrazingMethod(Integer grazingMethod)
    {
        if (grazingMethod == null
                || grazingMethod < GrasslandUsageRules.GRAZING_ROTATION
                || grazingMethod > GrasslandUsageRules.GRAZING_SEASONAL)
        {
            throw new ServiceException("放牧方式须为1～3（1轮牧2自由放牧3季节性放牧）");
        }
    }

    public static void validateDateRangeForList(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("预约开始日期不能晚于结束日期");
        }
    }

    public static void validateRowForSave(BizGrasslandUsageRecord row, BigDecimal grasslandAreaMu)
    {
        validateGrasslandId(row.getGrasslandId());
        validatePastureId(row.getPastureId());
        validateUsageAreaMu(row.getUsageAreaMu(), grasslandAreaMu);
        validateUseDates(row.getUseStartDate(), row.getUseEndDate());
        row.setActualUseDays(resolveActualUseDays(row.getUseStartDate(), row.getUseEndDate()));
        validateGrazingHeadCount(row.getGrazingHeadCount());
        validateGrazingMethod(row.getGrazingMethod());
    }

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

    private static Calendar truncateToDay(Date date)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal;
    }
}
