using System;
using System.Collections.Generic;
using System.Linq;
using common.GUIUtils;
using Net.Eagle0.Eagle.Api;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace eagle {
    public class CommandPanelController : MonoBehaviour {
        public EagleGameController mainController;

        public CommandSelector _selector;
        public CommandSelector Selector {
            get => _selector;
        private
            set {
                if (_selector != value) {
                    if (_selector != null) _selector.Hide();
                    _selector = value;
                    if (_selector != null) _selector.Show();
                }
            }
        }
        public SelectedCommand SelectedCommand => Selector == null ? null : Selector.Command;

        public TMP_Text headerLabel;
        public Button commitCommandButton;
        public TextMeshProUGUI commitButtonText;
        public IGameModel Model { get; set; }
        public ErrorHandler errorHandler;
        public CommandWarningPanelController commandWarningPanelController;

        private AvailableCommand _availableCommand;
        public AvailableCommand AvailableCommand {
            get => _availableCommand;
        private
            set {
                if (_availableCommand == null || !_availableCommand.Equals(value)) {
                    _availableCommand = value;
                }
            }
        }

        public void RefreshUI() {
            if (Selector != null) { Selector.RefreshUI(); }
        }

        public void SetAvailableCommandAndSelector(AvailableCommand cmd, CommandSelector sel) {
            AvailableCommand = cmd;
            Selector = sel;

            try {
                if (AvailableCommand == null) {
                    Selector = null;
                    headerLabel.text = null;
                    return;
                }

                Selector.UpdateAvailableCommand(Model, AvailableCommand);
                headerLabel.text = Selector.HeaderString;
            } catch (Exception e) { errorHandler.Add(e); }
        }

        public List<CommandSelector> AppropriateSelectors(AvailableCommand cmd) =>
                commandSelectors.FindAll(sel => sel.IsAppropriateFor(cmd));

        public List<GUIContent> ButtonContentsForCommand(AvailableCommand cmd) {
            return (from sel in AppropriateSelectors(cmd)
                    where sel.ButtonImage != null
                    select new GUIContent(sel.ButtonImage, sel.HeaderString)).ToList();
        }

        private List<CommandSelector> commandSelectors;

        public void Awake() {
            commandSelectors = new List<CommandSelector>();

            foreach (Transform child in gameObject.transform) {
                var sel = child.gameObject.GetComponent<CommandSelector>();
                if (sel != null) { commandSelectors.Add(sel); }
            }

            foreach (var kvp in commandSelectors) {
                kvp.gameObject.SetActive(true);
                kvp.Hide();
            }
        }

        public void Start() {
            foreach (var kvp in commandSelectors) { kvp.gameObject.SetActive(false); }
        }

        public void PointerEnteredCommitButton() {
            if (Selector != null) {
                if (!Selector.EnableCommitButton) {
                    if (string.IsNullOrEmpty(Selector.DisabledCommitButtonReason)) {
                        commandWarningPanelController.SetWarning(
                                "Invalid",
                                "CROSBY NEEDS TO PUT SOME TEXT HERE");
                    } else {
                        commandWarningPanelController.SetWarning(
                                "Invalid",
                                Selector.DisabledCommitButtonReason);
                    }
                } else if (Selector.WarnOnCommitButton) {
                    commandWarningPanelController.SetWarning(
                            "Are you sure?",
                            Selector.CommitWarningText);
                }
            }
        }

        public void PointerExitedCommitButton() { commandWarningPanelController.ClearWarning(); }

        public void OnGUI() {
            var eventType = Event.current.type;
            try {
                if (Selector == null) {
                    commitCommandButton.gameObject.SetActive(false);
                } else {
                    bool disableWarningPanel = !commitCommandButton.gameObject.activeSelf;

                    if (Selector.WarnOnCommitButton) {
                        commitButtonText.text =
                                $"<color=#FF0000FF>{Selector.CommitButtonString}</color>";
                    } else {
                        commitButtonText.text = Selector.CommitButtonString;
                    }
                    commitCommandButton.gameObject.SetActive(true);
                    commitCommandButton.interactable = Selector.EnableCommitButton;

                    if (disableWarningPanel) {
                        MainQueue.Q.EnqueueForNextUpdate(
                                () => { commandWarningPanelController.ClearWarning(); });
                    }
                }
            } catch (Exception e) {
                Debug.Log($"Event type is {eventType}");
                errorHandler.Add(e);
            }
        }
    }
}
