@inject IJSRuntime jsRuntime;
@implements IDisposable
@inject IKeyService keyService
@inject IBuildOrderService buildOrderService
@inject IImmortalSelectionService filterService

@inject IEconomyService economyService
@inject ITimingService timingService
@inject IToastService toastService


<InputPanelComponent>
    <div class="keyContainer">
        @foreach (var hotkey in hotkeys)
        {
            if (hotkey.IsHidden)
            {
                continue;
            }

            var color = hotkey.KeyText.Equals("SPACE") && keyService.IsHoldingSpace() || keyService.GetAllPressedKeys().Contains(hotkey.KeyText)
                ? "#0a0f12" : hotkey.GetColor();

            var x = hotkey.PositionX * Size;
            var y = hotkey.PositionY * Size;

            var border = "1px solid black";
            if (hotkey.KeyText.Equals(key))
            {
                border = "5px solid black";
            }
            if (hotkey.KeyText.Equals(controlGroup))
            {
                border = "5px solid green";
            }

            if (hotkey.KeyText.Equals("SPACE") && keyService.IsHoldingSpace())
            {
                border = "5px solid green";
            }

            <div style="position:relative;
                    cursor:pointer;
							top:@y.ToString()px;
							left:@x.ToString()px;
							width: 0px;
							height: 0px;">

                <div @onclick="x => { if (hotkey.KeyText.Equals(HotKeyType.SPACE.ToString())) { if (keyService.IsHoldingSpace()) { keyService.RemovePressedKey(hotkey.KeyText); } else { keyService.AddPressedKey(hotkey.KeyText); } } else { keyService.AddPressedKey(hotkey.KeyText); keyService.RemovePressedKey(hotkey.KeyText); }}" style="background-color:@color;
								border: @border;
								width: @Size.ToString()px;
								height: @Size.ToString()px;
								overflow: hidden;
								padding: 4px;">
                    @hotkey.KeyText
                    @foreach (var entity in data.Values)
                    {
                        if (InvalidKey(entity, hotkey) || InvalidKeyGroup(entity, hotkey) || InvalidHoldSpace(entity))
                        {
                            continue;
                        }

                        if (InvalidFaction(entity))
                        {
                            continue;
                        }

                        if (InvalidVanguard(entity) || InvalidNonVanguard(entity))
                        {
                            continue;
                        }

                        var isVanguard = entity.VanguardAdded() != null;
                        var style = isVanguard ? "font-weight: bold;" : "";

                        if (buildOrderService.WillMeetRequirements(entity) == null)
                        {
                            style += "color:gray; font-style: italic;";
                        }


                        <div style="@style">@entity.Info()?.Name</div>
                    }
                </div>
            </div>
        }
    </div>
</InputPanelComponent>

<style>
    .keyContainer {
        width: 400px;
        max-width: 95vw;
        height: 400px;
        outline: 3px solid black;
        border-radius: 8px;
        background-color: #282A30;
        margin: auto;
    }

    @@media only screen and (max-width: 1025px) {
        .keyContainer {
            transform: scale(0.85) translateX(-20px);
            background-color: transparent;
            outline: none;
        }
    }
</style>

@code {

    [Parameter]
    public int Size { get; set; } = 100;

    readonly Dictionary<string, EntityModel> data = EntityModel.GetDictionary();
    readonly List<HotkeyModel> hotkeys = HotkeyModel.GetAll();

    private string controlGroup = "C";
    private string key = "";

    protected override void OnInitialized()
    {
        base.OnInitialized();

        keyService.Subscribe(OnKeyPressed);
        filterService.Subscribe(StateHasChanged);
        buildOrderService.Subscribe(OnBuilderOrderChanged);
    }

    void IDisposable.Dispose()
    {
        keyService.Unsubscribe(OnKeyPressed);
        filterService.Unsubscribe(StateHasChanged);
        buildOrderService.Unsubscribe(OnBuilderOrderChanged);
    }

    int completedTimeCount = 0;

    void OnBuilderOrderChanged()
    {
        if (buildOrderService.UniqueCompletedTimes.Count != completedTimeCount)
        {
            completedTimeCount = buildOrderService.UniqueCompletedTimes.Count;
            StateHasChanged();
        }
    }

    protected override bool ShouldRender()
    {
#if DEBUG
        jsRuntime.InvokeVoidAsync("console.time", "HotKeyViewerComponent");
#endif

        return true;
    }

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

    // Move to Filter Service
    bool InvalidFaction(EntityModel entity)
    {
        if (entity.Faction() != null && entity.Faction()?.Faction != filterService.GetFactionType() && filterService.GetFactionType() != FactionType.Any)
        {
            return true;
        }

        return false;
    }

    // Move to Filter Service
    bool InvalidVanguard(EntityModel entity)
    {
        if (entity.VanguardAdded() != null
            && entity.VanguardAdded()?.ImmortalId != filterService.GetImmortalType()
            && filterService.GetImmortalType() != ImmortalType.Any)
        {
            return true;
        }

        return false;
    }

    // Move to Filter Service
    bool InvalidNonVanguard(EntityModel entity)
    {
        if (entity.Replaceds().Count > 0)
        {
            foreach (var replaced in entity.Replaceds())
            {
                if (filterService.GetImmortalType() == replaced.ImmortalId)
                {
                    return true;
                }
            }
        }

        return false;
    }

    bool InvalidKey(EntityModel entity, HotkeyModel key)
    {
        if (entity.Hotkey()?.Hotkey == key.KeyText)
        {
            return false;
        }
        return true;
    }

    bool InvalidKeyGroup(EntityModel entity, HotkeyModel key)
    {
        if (entity.Hotkey()?.HotkeyGroup == controlGroup)
        {
            return false;
        }

        return true;
    }

    bool InvalidKey(EntityModel entity)
    {
        if (entity.Hotkey()?.Hotkey == key)
        {
            return false;
        }
        return true;
    }

    bool InvalidKeyGroup(EntityModel entity)
    {
        if (entity.Hotkey()?.HotkeyGroup == controlGroup)
        {
            return false;
        }
        return true;
    }

    bool InvalidHoldSpace(EntityModel entity)
    {
        if (entity.Hotkey()?.HoldSpace == keyService.IsHoldingSpace())
        {
            return false;
        }
        return true;
    }

    void OnKeyPressed()
    {
        var controlGroupWas = controlGroup;
        var keyWas = key;


        if (keyService.GetAllPressedKeys().Contains("Z"))
        {
            controlGroup = "Z";
        }
        if (keyService.GetAllPressedKeys().Contains("TAB"))
        {
            controlGroup = "TAB";
        }
        if (keyService.GetAllPressedKeys().Contains("C"))
        {
            controlGroup = "C";
        }
        if (keyService.GetAllPressedKeys().Contains("D"))
        {
            controlGroup = "D";
        }
        if (keyService.GetAllPressedKeys().Contains("1"))
        {
            controlGroup = "1";
        }
    //TODO This could be better. Duplicated code
        if (keyService.GetAllPressedKeys().Contains("2"))
        {
            controlGroup = "2";
        }
        if (keyService.GetAllPressedKeys().Contains("SHIFT"))
        {
            controlGroup = "SHIFT";
        }

        if (keyService.GetAllPressedKeys().Contains("CONTROL"))
        {
            controlGroup = "CONTROL";
        }

        if (keyService.GetAllPressedKeys().Count > 0)
        {
            key = keyService.GetAllPressedKeys().First();
        }

        if (controlGroupWas != controlGroup || keyWas != key)
        {
            StateHasChanged();
        }
    }


    private void HandleClick()
    {
        var hotkey = keyService.GetHotkey();

        if (hotkey == "")
        {
            return;
        }

        if (hotkey == "`")
        {
            buildOrderService.RemoveLast();
            economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
            return;
        }

        var hotkeyGroup = keyService.GetHotkeyGroup();
        var isHoldSpace = keyService.IsHoldingSpace();
        var faction = filterService.GetFactionType();
        var immortal = filterService.GetImmortalType();

        var entity = EntityModel.GetFrom(hotkey!, hotkeyGroup, isHoldSpace, faction, immortal);

        if (entity == null)
        {
            return;
        }

        if (buildOrderService.Add(entity, economyService))
        {
            economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
        }
    }

}