@page "/simulation"
@inject GameSimulationService SimService
@implements IDisposable

<PageTitle>Ecology Simulation</PageTitle>

<div class="section-header d-flex align-items-center mb-4">
    <h1 class="mb-0">Ecology Simulation</h1>
    <div class="ms-3 flex-grow-1 border-bottom opacity-25"></div>
</div>

@if (!SimService.Data.IsInitialized)
{
    <div class="text-center py-5">
        <p class="lead mb-4">Simulate 20 turns of predator, prey, and flora ecology across the valley.</p>
        <button class="btn btn-primary btn-lg" @onclick="StartSimulation">Run Simulation</button>
    </div>
}
else
{
    <div class="simulation-layout">
        <div class="sim-controls d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
            <div class="d-flex align-items-center gap-2">
                <button class="btn btn-outline-light btn-sm" @onclick="PrevTurn" disabled="@(SimService.Data.CurrentTurn <= 1)">
                    &#9664; Prev
                </button>
                <span class="turn-label">
                    Turn <strong>@SimService.Data.CurrentTurn</strong> / 20
                </span>
                <button class="btn btn-outline-light btn-sm" @onclick="NextTurn" disabled="@(SimService.Data.CurrentTurn >= 20)">
                    Next &#9654;
                </button>
            </div>
            <div class="d-flex align-items-center gap-2">
                <span class="event-badge badge bg-@EventBadgeClass">
                    @CurrentEvent?.MeepleType Ecology
                </span>
                <span class="text-muted small">
                    in @string.Join(", ", CurrentEvent?.RegionTypes ?? new())
                </span>
                <button class="btn btn-secondary btn-sm" @onclick="RandomizeEvents">&#8635; Randomize Events</button>
            </div>
        </div>

        <div class="sim-map-container">
            <svg viewBox="0 0 700 461" class="sim-svg">
                <defs>
                    <radialGradient id="sg-Grass" cx="50%" cy="50%" r="50%">
                        <stop offset="0%" stop-color="#4caf50" stop-opacity="0.3"/>
                        <stop offset="100%" stop-color="#4caf50" stop-opacity="0"/>
                    </radialGradient>
                    <radialGradient id="sg-Forest" cx="50%" cy="50%" r="50%">
                        <stop offset="0%" stop-color="#2e7d32" stop-opacity="0.3"/>
                        <stop offset="100%" stop-color="#2e7d32" stop-opacity="0"/>
                    </radialGradient>
                    <radialGradient id="sg-Mountain" cx="50%" cy="50%" r="50%">
                        <stop offset="0%" stop-color="#78909c" stop-opacity="0.3"/>
                        <stop offset="100%" stop-color="#78909c" stop-opacity="0"/>
                    </radialGradient>
                    <radialGradient id="sg-Water" cx="50%" cy="50%" r="50%">
                        <stop offset="0%" stop-color="#42a5f5" stop-opacity="0.3"/>
                        <stop offset="100%" stop-color="#42a5f5" stop-opacity="0"/>
                    </radialGradient>
                    <radialGradient id="sg-Wasteland" cx="50%" cy="50%" r="50%">
                        <stop offset="0%" stop-color="#8d6e63" stop-opacity="0.3"/>
                        <stop offset="100%" stop-color="#8d6e63" stop-opacity="0"/>
                    </radialGradient>
                </defs>

                <image href="docs/Map.png" width="700" height="461" preserveAspectRatio="xMidYMid meet"/>

                @{
                    var currentRegions = SimService.GetCurrentState();
                    var activatedRegionNames = new HashSet<string>();
                    if (CurrentEvent != null)
                    {
                        activatedRegionNames = currentRegions
                            .Where(r => CurrentEvent.RegionTypes.Contains(r.Terrain))
                            .Select(r => r.Name)
                            .ToHashSet();
                    }
                }

                @foreach (var line in GetConnectionLines(currentRegions))
                {
                    <line x1="@line.X1" y1="@line.Y1" x2="@line.X2" y2="@line.Y2"
                          stroke="rgba(255,255,255,0.12)" stroke-width="2" stroke-linecap="round"/>
                }

                @foreach (var region in currentRegions)
                {
                    var isActivated = activatedRegionNames.Contains(region.Name);
                    var terrainColor = GetTerrainColor(region.Terrain);
                    var labelX = region.X + 24;
                    <g class="sim-region @(isActivated ? "sim-active" : "")">
                        <circle cx="@region.X" cy="@region.Y" r="34" fill="url(#sg-@region.Terrain)"/>
                        <circle cx="@region.X" cy="@region.Y" r="18"
                                fill="@(terrainColor)cc"
                                stroke="@(isActivated ? "#ffd700" : "rgba(255,255,255,0.5)")"
                                stroke-width="@(isActivated ? 3 : 2)"/>
                        <text x="@labelX" y="@(region.Y + 4)" fill="rgba(255,255,255,0.9)"
                              font-family="system-ui,sans-serif" font-size="11" font-weight="600">
                            @region.Name
                        </text>
                        <text x="@labelX" y="@(region.Y + 20)" fill="rgba(255,255,255,0.7)"
                              font-family="system-ui,sans-serif" font-size="10">
                            P:@region.PredatorMeeples R:@region.PreyMeeples F:@region.FloraMeeples
                        </text>
                    </g>
                }
            </svg>
        </div>

        @if (CurrentEvent != null && CurrentEvent.Details.Count > 0)
        {
            <div class="sim-details mt-3">
                <h5 class="text-muted mb-2">Turn @CurrentEvent.TurnNumber Details</h5>
                <div class="sim-details-scroll">
                    @foreach (var detail in CurrentEvent.Details)
                    {
                        <div class="sim-detail-item">@detail</div>
                    }
                </div>
            </div>
        }

        <div class="sim-totals mt-3 d-flex gap-4 justify-content-center">
            @{
                var totals = SimService.GetCurrentState();
            }
            <div class="total-pred"><span class="total-dot" style="background:#e76f51"></span> Predators: @totals.Sum(r => r.PredatorMeeples)</div>
            <div class="total-prey"><span class="total-dot" style="background:#e9c46a"></span> Prey: @totals.Sum(r => r.PreyMeeples)</div>
            <div class="total-flora"><span class="total-dot" style="background:#4caf50"></span> Flora: @totals.Sum(r => r.FloraMeeples)</div>
        </div>
    </div>
}

@code {
    private TurnEvent? CurrentEvent => SimService.Data.CurrentTurn > 0 && SimService.Data.CurrentTurn <= SimService.Data.Events.Count
        ? SimService.Data.Events[SimService.Data.CurrentTurn - 1]
        : null;

    private string EventBadgeClass => CurrentEvent?.MeepleType switch
    {
        "Predator" => "danger",
        "Prey" => "warning",
        "Flora" => "success",
        _ => "secondary"
    };

    protected override void OnInitialized()
    {
        SimService.RunSimulation();
    }

    private void StartSimulation()
    {
        SimService.RunSimulation();
    }

    private void PrevTurn()
    {
        if (SimService.Data.CurrentTurn > 1)
            SimService.Data.CurrentTurn--;
    }

    private void NextTurn()
    {
        if (SimService.Data.CurrentTurn < 20)
            SimService.Data.CurrentTurn++;
    }

    private void RandomizeEvents()
    {
        SimService.RandomizeEvents();
    }

    private static string GetTerrainColor(string terrain)
    {
        return terrain switch
        {
            "Grass" => "#4caf50",
            "Forest" => "#2e7d32",
            "Mountain" => "#78909c",
            "Water" => "#42a5f5",
            "Wasteland" => "#8d6e63",
            _ => "#888"
        };
    }

    private record ConnectionLine(int X1, int Y1, int X2, int Y2);

    private List<ConnectionLine> GetConnectionLines(List<RegionState> regions)
    {
        var lookup = regions.ToDictionary(r => r.Name);
        var lines = new List<ConnectionLine>();
        var drawn = new HashSet<string>();

        foreach (var region in regions)
        {
            foreach (var conn in region.Connections)
            {
                var key = string.Compare(region.Name, conn, StringComparison.OrdinalIgnoreCase) < 0
                    ? $"{region.Name}|{conn}"
                    : $"{conn}|{region.Name}";

                if (!drawn.Add(key)) continue;
                if (!lookup.TryGetValue(conn, out var target)) continue;

                lines.Add(new ConnectionLine(region.X, region.Y, target.X, target.Y));
            }
        }

        return lines;
    }

    public void Dispose()
    {
    }
}
