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

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.industryservice.domain.BizLargeLivestockFarmer;

/**
 * 养殖大户数据填报入参校验（手工新增/修改与 Excel 导入共用）。
 * <p>
 * 主要职责：
 * <ul>
 *   <li>校验所属年月（不可未来月）</li>
 *   <li>校验村合法并反推乡镇写入 townDeptId / townName / villageName</li>
 *   <li>企业类型、销售渠道枚举；空值补默认（个体工商户 / 其他）</li>
 *   <li>是/否字段规范化；数量与金额非负</li>
 *   <li>末尾调用 {@link LargeLivestockFarmerDerivedSupport#applyDerived} 计算派生字段</li>
 * </ul>
 * </p>
 */
public final class LargeLivestockFarmerValidation
{
    /** 企业类型默认值 */
    public static final String DEFAULT_ENTERPRISE_TYPE = "个体工商户";

    /** 销售渠道默认值 */
    public static final String DEFAULT_SALES_CHANNEL = "其他";

    /** 允许的企业类型 */
    public static final String[] ENTERPRISE_TYPE_OPTIONS = {
            "个体工商户", "个人独资企业", "有限责任公司", "合伙企业", "其他"
    };

    /** 允许的销售渠道 */
    public static final String[] SALES_CHANNEL_OPTIONS = {
            "其他", "线上销售", "线下集市", "企事业单位", "商超门店"
    };

    private static final Set<String> ENTERPRISE_TYPE_SET = new HashSet<>(Arrays.asList(ENTERPRISE_TYPE_OPTIONS));

    private static final Set<String> SALES_CHANNEL_SET = new HashSet<>(Arrays.asList(SALES_CHANNEL_OPTIONS));

    private LargeLivestockFarmerValidation()
    {
    }

    /**
     * 保存前完整校验，并回填乡镇信息与派生字段。
     * 校验失败抛 {@link ServiceException}。
     */
    public static void validateRowForSave(BizLargeLivestockFarmer row, TownDeptSupport townDeptSupport)
    {
        if (row == null)
        {
            throw new ServiceException("参数不能为空");
        }
        YakHerdInventoryMonthSupport.validateStatPeriod(row.getStatYear(), row.getStatMonth());
        if (row.getVillageDeptId() == null)
        {
            throw new ServiceException("所属村不能为空");
        }
        if (StringUtils.isEmpty(row.getEnterpriseName()))
        {
            throw new ServiceException("企业名称不能为空");
        }
        row.setEnterpriseName(row.getEnterpriseName().trim());
        if (row.getEnterpriseName().length() > 200)
        {
            throw new ServiceException("企业名称不能超过200字");
        }
        SysDept village = townDeptSupport.requireReportVillage(row.getVillageDeptId());
        if (village == null)
        {
            throw new ServiceException("所属村不合法");
        }
        SysDept town = townDeptSupport.requireReportTown(village.getParentId());
        if (town == null)
        {
            throw new ServiceException("所属村的上级乡镇不合法");
        }
        row.setVillageName(village.getDeptName());
        row.setTownDeptId(town.getDeptId());
        row.setTownName(town.getDeptName());

        if (StringUtils.isNotEmpty(row.getLegalRepresentative()) && row.getLegalRepresentative().length() > 64)
        {
            throw new ServiceException("法定代表人不能超过64字");
        }
        if (StringUtils.isNotEmpty(row.getEstablishDate()) && row.getEstablishDate().length() > 32)
        {
            throw new ServiceException("成立时间不能超过32字");
        }

        if (StringUtils.isEmpty(row.getEnterpriseType()))
        {
            row.setEnterpriseType(DEFAULT_ENTERPRISE_TYPE);
        }
        else
        {
            String type = row.getEnterpriseType().trim();
            if (!ENTERPRISE_TYPE_SET.contains(type))
            {
                throw new ServiceException("企业类型取值不合法");
            }
            row.setEnterpriseType(type);
        }

        if (StringUtils.isEmpty(row.getSalesChannel()))
        {
            row.setSalesChannel(DEFAULT_SALES_CHANNEL);
        }
        else
        {
            String channel = row.getSalesChannel().trim();
            if (!SALES_CHANNEL_SET.contains(channel))
            {
                throw new ServiceException("产品销售渠道取值不合法");
            }
            row.setSalesChannel(channel);
        }

        row.setHasSubsidy(LargeLivestockFarmerDerivedSupport.normalizeYesNo(row.getHasSubsidy(), "是否享受补助"));
        row.setHasTrademark(LargeLivestockFarmerDerivedSupport.normalizeYesNo(row.getHasTrademark(), "是否有注册商标"));
        row.setHasQualityCert(LargeLivestockFarmerDerivedSupport.normalizeYesNo(row.getHasQualityCert(), "是否通过农产品质量认证"));

        validateNonNegative(row.getLivestockLaborCount(), "从事畜牧业生产经营劳力人员");
        validateNonNegative(row.getCattleYearEndStock(), "牛年底存栏");
        validateNonNegative(row.getCattleBreedingFemaleStock(), "牛能繁母畜");
        validateNonNegative(row.getSheepYearEndStock(), "羊年底存栏");
        validateNonNegative(row.getSheepBreedingFemaleStock(), "羊能繁母畜");
        validateNonNegative(row.getCattleOutbound(), "牛出栏");
        validateNonNegative(row.getSheepOutbound(), "羊出栏");
        validateNonNegative(row.getDrivenPopulation(), "带动人数");
        validateNonNegative(row.getSubsidyYear(), "补助年份");

        validateNonNegativeDecimal(row.getRegisteredCapital(), "注册资本");
        validateNonNegativeDecimal(row.getGrassBalanceArea(), "草畜平衡面积");
        validateNonNegativeDecimal(row.getTransferGrassArea(), "流转经营草地面积");
        validateNonNegativeDecimal(row.getApprovedCarryingCapacity(), "核定年末草畜平衡载畜量");
        validateNonNegativeDecimal(row.getYearEndStockSheepUnit(), "年底牲畜存栏绵羊单位");
        validateNonNegativeDecimal(row.getIncome(), "年度经营总收入");
        validateNonNegativeDecimal(row.getExpense(), "年度经营总支出");
        validateNonNegativeDecimal(row.getSubsidyAmount(), "补贴资金");
        validateNonNegativeDecimal(row.getWagePaid(), "发放工资");

        LargeLivestockFarmerDerivedSupport.applyDerived(row);

        if (StringUtils.isNotEmpty(row.getRemark()) && row.getRemark().length() > 500)
        {
            throw new ServiceException("备注不能超过500字");
        }
    }

    private static void validateNonNegative(Integer value, String label)
    {
        if (value != null && value < 0)
        {
            throw new ServiceException(label + "不能为负数");
        }
    }

    private static void validateNonNegativeDecimal(BigDecimal value, String label)
    {
        if (value != null && value.compareTo(BigDecimal.ZERO) < 0)
        {
            throw new ServiceException(label + "不能为负数");
        }
    }
}
