@inject IJSRuntime jsRuntime

@inject IBuildOrderService buildOrder
@inject ITimingService timingService

@implements IDisposable

<FormLayoutComponent>
    <div style="display: flex; gap: 24px;">
        <FormDisplayComponent Label="Army Completed At">
            <Display>@lastInterval | T @Interval.ToTime(lastInterval)</Display>
        </FormDisplayComponent>
        <FormDisplayComponent Label="Army Attacking At">
            <Display>@(lastInterval + timingService.GetTravelTime()) | T @Interval.ToTime(lastInterval + timingService.GetTravelTime())</Display>
        </FormDisplayComponent>
    </div>
    <FormDisplayComponent Label="Army units built">
        <Display>
            <div class="armyCardsContainer">
                @foreach (var unit in armyCount)
                {
                    <div class="armyCard">
                        <div class="armyCountPosition">
                            <div class="armyCount">@unit.Value.ToString()x</div>
                        </div>
                        <div>@unit.Key</div>
                    </div>
                }
            </div>
        </Display>
    </FormDisplayComponent>

</FormLayoutComponent>

<style>
.armyCardsContainer {
    display: flex; 
    width: 100%; 
    gap: 16px;  
    flex-wrap: wrap;
}

    .armyCard {
        width:100px; 
        height: 80px; 
        padding: 16px;
    }
    
    .armyCountPosition {
        height: 0;
        top: -20px;
        left: -16px;
        position: relative;
    }
    .armyCount {
        font-weight: bolder;
    }
    
</style>

@code {
    private int lastInterval;

    readonly Dictionary<string, int> armyCount = new();

    List<EntityModel> army = new();

    protected override void OnInitialized()
    {
        buildOrder.Subscribe(OnBuildOrderChanged);
        timingService.Subscribe(StateHasChanged);
    }

    void IDisposable.Dispose()
    {
        buildOrder.Unsubscribe(OnBuildOrderChanged);
        timingService.Unsubscribe(StateHasChanged);
    }

    protected override bool ShouldRender()
    {
#if DEBUG
        jsRuntime.InvokeVoidAsync("console.time", "ArmyComponent");
#endif
        return true;
    }

    protected override void OnAfterRender(bool firstRender)
    {
#if DEBUG
        jsRuntime.InvokeVoidAsync("console.timeEnd", "ArmyComponent");
#endif
    }

    void OnBuildOrderChanged()
    {
        var armyCountWas = 0;
        foreach (var army in armyCount)
        {
            armyCountWas += army.Value;
        }

        armyCount.Clear();

        lastInterval = 0;

        var entitiesOverTime = buildOrder.GetOrders();

        foreach (var entitiesAtTime in entitiesOverTime)
        {
            foreach (var entity in entitiesAtTime.Value)
            {
                if (entity.EntityType == EntityType.Army)
                {
                    if (!armyCount.TryAdd(entity.Info().Name, 1))
                    {
                        armyCount[entity.Info().Name]++;
                    }

                    if (entity.Production() != null && entity.Production().BuildTime + entitiesAtTime.Key > lastInterval)
                    {
                        lastInterval = entity.Production().BuildTime + entitiesAtTime.Key;
                    }
                }
            }
        }

    //TODO Better
        var armyCountIs = 0;
        foreach (var army in armyCount)
        {
            armyCountIs += army.Value;
        }


        if (armyCountWas != armyCountIs)
        {
            StateHasChanged();
        }
    }

}