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

import java.util.ArrayList;
import java.util.List;
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.BizYakHerdInventory;
import com.ruoyi.web.modules.industryservice.support.YakHerdInventoryExcelParser.ParsedRow;

/**
 * 牦牛存栏数据填报校验与派生字段计算
 */
public final class YakHerdInventoryValidation
{
    private YakHerdInventoryValidation()
    {
    }

    public static void validateRowForSave(BizYakHerdInventory row, TownDeptSupport townDeptSupport)
    {
        if (row == null)
        {
            throw new ServiceException("参数不能为空");
        }
        YakHerdInventoryMonthSupport.validateStatPeriod(row.getStatYear(), row.getStatMonth());
        if (row.getVillageDeptId() == null)
        {
            throw new ServiceException("所属村不能为空");
        }
        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());
        validateNonNegative(row.getVillageCount(), "村居数");
        validateNonNegative(row.getHerdsmanHouseholdCount(), "牧户数");
        validateNonNegative(row.getBreedingBullCount(), "种公牛存栏数");
        validateNonNegative(row.getBullCastratedCount(), "公牛/阉畜存栏数");
        validateNonNegative(row.getCowYoungCount(), "0-1.5岁幼畜存栏数");
        validateNonNegative(row.getCowAdultCount(), "1.5岁以上成畜存栏数");
        validateNonNegative(row.getMilkingCowCount(), "产奶母牛存栏数");
        validateNonNegative(row.getFertileCowCount(), "能繁母牛存栏数");
        validateNonNegative(row.getSheepTotal(), "羊总存栏数");
        validateNonNegative(row.getMilkingSheepCount(), "产奶羊存栏数");
        validateMilkingSheepLessThanSheepTotal(row);
        validateNonNegative(row.getInsuredYakCount(), "保险牦牛存栏数");
        if (StringUtils.isNotEmpty(row.getRemark()) && row.getRemark().length() > 500)
        {
            throw new ServiceException("备注不能超过500字");
        }
        recalculateDerived(row);
    }

    /**
     * 产奶羊存栏数须小于羊总存栏数（两者均非空时）。
     */
    public static void validateMilkingSheepLessThanSheepTotal(BizYakHerdInventory row)
    {
        if (row == null || row.getMilkingSheepCount() == null || row.getSheepTotal() == null)
        {
            return;
        }
        if (row.getMilkingSheepCount() >= row.getSheepTotal())
        {
            throw new ServiceException("产奶羊存栏数须小于羊总存栏数");
        }
    }

    /**
     * 按模板计算逻辑回写合计字段（直接覆盖，不以 Excel 合计为准）。
     */
    public static void recalculateDerived(BizYakHerdInventory row)
    {
        if (row == null)
        {
            return;
        }
        int bull = safe(row.getBreedingBullCount()) + safe(row.getBullCastratedCount());
        int cow = safe(row.getCowYoungCount()) + safe(row.getCowAdultCount());
        int dairy = safe(row.getMilkingCowCount()) + safe(row.getFertileCowCount());
        int insured = safe(row.getInsuredYakCount());
        int sheep = safe(row.getSheepTotal());
        row.setBullTotal(bull);
        row.setCowTotal(cow);
        row.setDairyTotal(dairy);
        row.setYakTotal(bull + cow + insured);
        row.setGrandTotal(bull + cow + insured + dairy + sheep);
        row.setYakSheepTotal(bull + cow + insured + sheep);
    }

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

    /**
     * 导入时对照 Excel 中已填合计列，不一致则返回警告文案（非阻断）。
     */
    public static List<String> buildExcelTotalWarns(ParsedRow parsed, BizYakHerdInventory row)
    {
        List<String> warns = new ArrayList<>();
        if (parsed == null || row == null)
        {
            return warns;
        }
        appendMismatch(warns, "公牛合计", parsed.getExcelBullTotal(), row.getBullTotal());
        appendMismatch(warns, "母牛合计", parsed.getExcelCowTotal(), row.getCowTotal());
        appendMismatch(warns, "奶牛合计", parsed.getExcelDairyTotal(), row.getDairyTotal());
        appendMismatch(warns, "牦牛公母分类合计", parsed.getExcelYakTotal(), row.getYakTotal());
        appendMismatch(warns, "总合计", parsed.getExcelGrandTotal(), row.getGrandTotal());
        appendMismatch(warns, "总量（牦牛+羊）", parsed.getExcelYakSheepTotal(), row.getYakSheepTotal());
        return warns;
    }

    private static void appendMismatch(List<String> warns, String label, Integer excelValue, Integer calcValue)
    {
        if (excelValue == null)
        {
            return;
        }
        if (!excelValue.equals(safe(calcValue)))
        {
            warns.add(label + "与明细加总不一致（表内=" + excelValue + "，计算=" + safe(calcValue) + "）");
        }
    }

    private static int safe(Integer value)
    {
        return value == null ? 0 : value;
    }
}
