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

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.ruoyi.web.modules.industryservice.domain.dto.BreedingIndustryYakSnapshot;
import com.ruoyi.web.modules.industryservice.domain.vo.BreedingIndustryAgeBandVo;

/**
 * 养殖产业看板纯计算（月龄分档、月末存栏、性别、占比）。
 */
public final class BreedingIndustryCalculator
{
    private BreedingIndustryCalculator()
    {
    }

    public static String normalizeGender(String gender)
    {
        if (gender == null)
        {
            return null;
        }
        String g = gender.trim();
        if (BreedingIndustryRules.GENDER_BULL.equals(g) || BreedingIndustryRules.GENDER_COW.equals(g))
        {
            return g;
        }
        if (g.contains("公") && !g.contains("母"))
        {
            return BreedingIndustryRules.GENDER_BULL;
        }
        if (g.contains("母"))
        {
            return BreedingIndustryRules.GENDER_COW;
        }
        return null;
    }

    public static int resolveAgeMonths(BreedingIndustryYakSnapshot asset, LocalDate statDate)
    {
        if (asset.getAgeMonths() != null)
        {
            return Math.max(0, asset.getAgeMonths());
        }
        if (asset.getBirthDate() == null)
        {
            return 0;
        }
        LocalDate birth = toLocalDate(asset.getBirthDate());
        int months = (statDate.getYear() - birth.getYear()) * 12 + (statDate.getMonthValue() - birth.getMonthValue());
        if (statDate.getDayOfMonth() < birth.getDayOfMonth())
        {
            months--;
        }
        return Math.max(0, months);
    }

    public static String bandCodeOf(int ageMonths)
    {
        if (ageMonths <= 6)
        {
            return BreedingIndustryRules.BAND_M1_6;
        }
        if (ageMonths <= 12)
        {
            return BreedingIndustryRules.BAND_M7_12;
        }
        return BreedingIndustryRules.BAND_M13_PLUS;
    }

    public static boolean countsAtMonthEnd(BreedingIndustryYakSnapshot asset, LocalDate monthEndInclusive)
    {
        if (asset.getPastureId() == null)
        {
            return false;
        }
        Integer status = asset.getAssetStatus();
        if (status == null || status < YakAssetRules.ASSET_STATUS_MIN || status > YakAssetRules.ASSET_STATUS_MAX)
        {
            return false;
        }
        LocalDate changeDate = toLocalDate(asset.getStatusChangeDate());
        if (status != BreedingIndustryRules.ASSET_STATUS_NORMAL)
        {
            if (changeDate == null)
            {
                return false;
            }
            if (!changeDate.isAfter(monthEndInclusive))
            {
                return false;
            }
        }
        return true;
    }

    public static boolean countsAsCurrentInventory(BreedingIndustryYakSnapshot asset)
    {
        return asset.getPastureId() != null
                && asset.getAssetStatus() != null
                && asset.getAssetStatus() == BreedingIndustryRules.ASSET_STATUS_NORMAL;
    }

    public static BigDecimal ratioPercent(int part, int total)
    {
        if (total <= 0)
        {
            return BigDecimal.ZERO.setScale(BreedingIndustryRules.RATIO_SCALE, RoundingMode.HALF_UP);
        }
        return new BigDecimal(part).multiply(new BigDecimal("100"))
                .divide(new BigDecimal(total), BreedingIndustryRules.RATIO_SCALE + 2, RoundingMode.HALF_UP)
                .setScale(BreedingIndustryRules.RATIO_SCALE, RoundingMode.HALF_UP);
    }

    public static Map<String, Integer> countAgeBands(List<BreedingIndustryYakSnapshot> assets, LocalDate statDate)
    {
        Map<String, Integer> counts = new HashMap<>();
        counts.put(BreedingIndustryRules.BAND_M1_6, 0);
        counts.put(BreedingIndustryRules.BAND_M7_12, 0);
        counts.put(BreedingIndustryRules.BAND_M13_PLUS, 0);
        for (BreedingIndustryYakSnapshot asset : assets)
        {
            if (!countsAsCurrentInventory(asset))
            {
                continue;
            }
            String band = bandCodeOf(resolveAgeMonths(asset, statDate));
            counts.put(band, counts.get(band) + 1);
        }
        return counts;
    }

    public static List<BreedingIndustryAgeBandVo> buildAgeStructure(Map<String, Integer> bandCounts, int inventoryTotal)
    {
        List<BreedingIndustryAgeBandVo> list = new ArrayList<>();
        list.add(ageBandVo(BreedingIndustryRules.BAND_M1_6, BreedingIndustryRules.LABEL_M1_6,
                bandCounts.getOrDefault(BreedingIndustryRules.BAND_M1_6, 0), inventoryTotal));
        list.add(ageBandVo(BreedingIndustryRules.BAND_M7_12, BreedingIndustryRules.LABEL_M7_12,
                bandCounts.getOrDefault(BreedingIndustryRules.BAND_M7_12, 0), inventoryTotal));
        list.add(ageBandVo(BreedingIndustryRules.BAND_M13_PLUS, BreedingIndustryRules.LABEL_M13_PLUS,
                bandCounts.getOrDefault(BreedingIndustryRules.BAND_M13_PLUS, 0), inventoryTotal));
        return list;
    }

    public static LocalDate resolveMonthEnd(int year, int month, LocalDate statDate)
    {
        if (month == statDate.getMonthValue() && year == statDate.getYear())
        {
            return statDate;
        }
        return LocalDate.of(year, month, 1).with(TemporalAdjusters.lastDayOfMonth());
    }

    private static BreedingIndustryAgeBandVo ageBandVo(String code, String label, int count, int total)
    {
        BreedingIndustryAgeBandVo vo = new BreedingIndustryAgeBandVo();
        vo.setBandCode(code);
        vo.setBandLabel(label);
        vo.setCount(count);
        vo.setRatio(ratioPercent(count, total));
        return vo;
    }

    private static LocalDate toLocalDate(Date date)
    {
        if (date == null)
        {
            return null;
        }
        return date.toInstant().atZone(ZoneId.of(BreedingIndustryRules.ZONE_SHANGHAI)).toLocalDate();
    }
}
