package com.livingworld.commands;

import com.livingworld.modules.ecosystem.EcosystemModule;
import com.livingworld.modules.ecosystem.EcosystemRegionData;
import com.livingworld.modules.pollution.PollutionModule;
import com.livingworld.modules.pollution.PollutionRegionData;
import com.livingworld.modules.recovery.RecoveryModule;
import com.livingworld.modules.recovery.RecoveryRegionData;
import com.livingworld.modules.resources.ResourceDepletionModule;
import com.livingworld.modules.resources.ResourceRegionData;
import com.livingworld.modules.soil.SoilModule;
import com.livingworld.modules.soil.SoilRegionData;
import com.livingworld.modules.vegetation.VegetationModule;
import com.livingworld.modules.vegetation.VegetationRegionData;
import com.livingworld.modules.water.WaterModule;
import com.livingworld.modules.water.WaterRegionData;
import com.livingworld.regions.Region;
import com.livingworld.regions.RegionFlags;
import com.livingworld.regions.RegionMetrics;
import com.livingworld.regions.RegionModuleData;
import java.util.ArrayList;
import java.util.List;

/**
 * Formats region diagnostics without depending on Minecraft classes.
 */
public final class RegionInfoFormatter {

    private RegionInfoFormatter() {
    }

    public static List<String> format(Region region) {
        if (region == null) {
            throw new IllegalArgumentException("region must not be null");
        }

        RegionMetrics m = region.getMetrics();
        RegionFlags f = region.getFlags();
        RegionModuleData data = region.getModuleData();

        List<String> lines = new ArrayList<>();
        lines.add("Region: " + region.getCoordinate().stableId()
                + "  lifecycle=" + region.getLifecycleState()
                + "  dirty=" + region.isDirty()
                + "  tick=" + region.getLastUpdatedSimulationTick());
        lines.add("Metrics:"
                + "  health=" + fmt(m.getEcosystemHealth())
                + "  poll=" + fmt(m.getPollutionScore())
                + "  soil=" + fmt(m.getSoilQuality())
                + "  water=" + fmt(m.getWaterQuality())
                + "  veg=" + fmt(m.getVegetationPressure())
                + "  res=" + fmt(m.getResourceDepletion())
                + "  recov=" + fmt(m.getRecoveryPressure()));
        lines.add("Flags:"
                + "  playerActivity=" + f.isHasPlayerActivity()
                + "  highPollution=" + f.isHasHighPollution()
                + "  lowSoil=" + f.isHasLowSoilQuality()
                + "  ecoEvent=" + f.isHasActiveEcosystemEvent()
                + "  forceLoaded=" + f.isForceLoadedBySimulation());

        lines.add("--- Module Data ---");
        data.get(PollutionModule.MODULE_ID, PollutionRegionData.class).ifPresentOrElse(
                d -> lines.add("  pollution:  air=" + fmt(d.getAirPollution())
                        + "  ground=" + fmt(d.getGroundPollution())
                        + "  water=" + fmt(d.getWaterPollution())
                        + "  decay=" + fmt(d.getDecayResistance())),
                () -> lines.add("  pollution:  (no data)"));

        data.get(SoilModule.MODULE_ID, SoilRegionData.class).ifPresentOrElse(
                d -> lines.add("  soil:       fertility=" + fmt(d.getFertility())
                        + "  moisture=" + fmt(d.getMoisture())
                        + "  contam=" + fmt(d.getContamination())
                        + "  compact=" + fmt(d.getCompaction())
                        + "  erosion=" + fmt(d.getErosion())),
                () -> lines.add("  soil:       (no data)"));

        data.get(WaterModule.MODULE_ID, WaterRegionData.class).ifPresentOrElse(
                d -> lines.add("  water:      avail=" + fmt(d.getWaterAvailability())
                        + "  purif=" + fmt(d.getPurificationCapacity())
                        + "  drought=" + fmt(d.getDroughtRisk())
                        + "  flood=" + fmt(d.getFloodRisk())),
                () -> lines.add("  water:      (no data)"));

        data.get(VegetationModule.MODULE_ID, VegetationRegionData.class).ifPresentOrElse(
                d -> lines.add("  vegetation: grass=" + fmt(d.getGrassPressure())
                        + "  flower=" + fmt(d.getFlowerPressure())
                        + "  shrub=" + fmt(d.getShrubPressure())
                        + "  tree=" + fmt(d.getTreePressure())
                        + "  dead=" + fmt(d.getDeadVegetation())),
                () -> lines.add("  vegetation: (no data)"));

        data.get(ResourceDepletionModule.MODULE_ID, ResourceRegionData.class).ifPresentOrElse(
                d -> lines.add("  resources:  mining=" + fmt(d.getMiningDepletion())
                        + "  logging=" + fmt(d.getLoggingDepletion())
                        + "  farming=" + fmt(d.getFarmingDepletion())),
                () -> lines.add("  resources:  (no data)"));

        data.get(RecoveryModule.MODULE_ID, RecoveryRegionData.class).ifPresentOrElse(
                d -> lines.add("  recovery:   stage=" + d.getSuccessionStage()
                        + "  progress=" + fmt(d.getRecoveryProgress())
                        + "  damage=" + fmt(d.getDamageAccumulation())),
                () -> lines.add("  recovery:   (no data)"));

        data.get(EcosystemModule.MODULE_ID, EcosystemRegionData.class).ifPresentOrElse(
                d -> lines.add("  ecosystem:  health=" + fmt(d.getEcosystemHealth())
                        + "  stress=" + fmt(d.getStress())
                        + "  resilience=" + fmt(d.getResilience())
                        + "  rate=" + fmt(d.getRecoveryRate())),
                () -> lines.add("  ecosystem:  (no data)"));

        return lines;
    }

    private static String fmt(double v) {
        return String.format("%.1f", v);
    }
}
