using SpaceGame.Api.Universe.Bootstrap;

namespace SpaceGame.Api.Universe.Scenario;

public sealed class WorldRuntimeAssembler(
    IStaticDataProvider staticData,
    WorldSeedingService seedingService)
{
    public SimulationWorld Assemble(
      WorldGenerationOptions worldGenerationOptions,
      WorldBuildTopology topology,
      ScenarioWorldContent content)
    {
        seedingService.InitializeStationStockpiles(content.Stations, staticData.ModuleDefinitions);

        var factions = seedingService.CreateFactions(content.Stations, content.Ships);
        seedingService.BootstrapFactionEconomy(factions, content.Stations);
        var policies = seedingService.CreatePolicies(factions);
        var commanders = seedingService.CreateCommanders(factions, content.Stations, content.Ships);
        var nowUtc = DateTimeOffset.UtcNow;
        var claims = seedingService.CreateClaims(content.Stations, topology.SpatialLayout.Celestials, nowUtc);

        var world = new SimulationWorld
        {
            Label = "Split Viewer / Simulation World",
            Seed = worldGenerationOptions.Seed,
            Systems = topology.SystemRuntimes.ToList(),
            Celestials = topology.SpatialLayout.Celestials,
            Nodes = topology.SpatialLayout.Nodes,
            Wrecks = [],
            Stations = content.Stations.ToList(),
            Ships = content.Ships.ToList(),
            Factions = factions,
            Geopolitics = null,
            Commanders = commanders,
            Claims = claims,
            ConstructionSites = [],
            MarketOrders = [],
            Policies = policies,
            ShipDefinitions = new Dictionary<string, ShipDefinition>(staticData.ShipDefinitions, StringComparer.Ordinal),
            ItemDefinitions = new Dictionary<string, ItemDefinition>(staticData.ItemDefinitions, StringComparer.Ordinal),
            ModuleDefinitions = new Dictionary<string, ModuleDefinition>(staticData.ModuleDefinitions, StringComparer.Ordinal),
            ModuleRecipes = new Dictionary<string, ModuleRecipeDefinition>(staticData.ModuleRecipes, StringComparer.Ordinal),
            Recipes = new Dictionary<string, RecipeDefinition>(staticData.Recipes, StringComparer.Ordinal),
            ProductionGraph = staticData.ProductionGraph,
            OrbitalTimeSeconds = worldGenerationOptions.Seed * 97d,
            GeneratedAtUtc = nowUtc,
        };

        var (constructionSites, marketOrders) = seedingService.CreateConstructionSites(world);
        world.ConstructionSites.AddRange(constructionSites);
        world.MarketOrders.AddRange(marketOrders);

        var geopolitics = new GeopoliticalSimulationService();
        geopolitics.Update(world, 0f, []);
        return world;
    }
}
