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

namespace eagle {
    using ProvinceId = Int32;

    public class BattleAftermathDecisionCommandSelector : CommandSelector {
        public EventBasedTable unitsTable;
        public Toggle keepProvinceToggle;
        public Toggle withdrawToggle;
        public ToggleGroup decisionToggleGroup;

        public GameObject withdrawContainer;
        public TMP_Dropdown destinationDropdown;
        public Slider goldSlider;
        public Slider foodSlider;
        public TMP_Text goldLabel;
        public TMP_Text foodLabel;
        public TMP_Text infoText;

        private List<ProvinceId> _sortedAdjacentProvinceIds;

        private BattleAftermathDecisionAvailableCommand BattleAftermathCommand =>
                _availableCommand.BattleAftermathDecisionCommand;

        private ProvinceId ActingProvinceId => BattleAftermathCommand.ActingProvinceId;

        public override AvailableCommand.SealedValueOneofCase CommandType =>
                AvailableCommand.SealedValueOneofCase.BattleAftermathDecisionCommand;

        public override string HeaderString => "Battle Aftermath";

        public override string CommitButtonString => IsKeepSelected ? "Keep Province" : "Withdraw";

        private bool IsKeepSelected => keepProvinceToggle != null && keepProvinceToggle.isOn;

        public override bool EnableCommitButton {
            get {
                if (IsKeepSelected) return true;
                return destinationDropdown != null && destinationDropdown.value >= 0 &&
                       _sortedAdjacentProvinceIds != null &&
                       destinationDropdown.value < _sortedAdjacentProvinceIds.Count;
            }
        }

        public override string DisabledCommitButtonReason {
            get {
                if (!IsKeepSelected &&
                    (destinationDropdown == null || destinationDropdown.value < 0 ||
                     _sortedAdjacentProvinceIds == null ||
                     destinationDropdown.value >= _sortedAdjacentProvinceIds.Count))
                    return "Select a destination province";
                return null;
            }
        }

        public override List<ProvinceId> TargetedProvinces {
            get {
                var list = new List<ProvinceId> { ActingProvinceId };
                if (!IsKeepSelected && _sortedAdjacentProvinceIds != null &&
                    destinationDropdown != null && destinationDropdown.value >= 0 &&
                    destinationDropdown.value < _sortedAdjacentProvinceIds.Count) {
                    list.Add(_sortedAdjacentProvinceIds[destinationDropdown.value]);
                }
                return list;
            }
        }

        public override SelectedCommand Command {
            get {
                var cmd = new BattleAftermathDecisionSelectedCommand();
                if (IsKeepSelected) {
                    cmd.Decision = BattleAftermathDecisionSelectedCommand.Types
                                           .BattleAftermathDecision.KeepProvince;
                } else {
                    cmd.Decision = BattleAftermathDecisionSelectedCommand.Types
                                           .BattleAftermathDecision.Withdraw;
                    cmd.DestinationProvinceId = SelectedDestinationProvinceId;
                    cmd.Gold = (int)goldSlider.value;
                    cmd.Food = (int)foodSlider.value;
                }
                return new SelectedCommand { BattleAftermathDecisionCommand = cmd };
            }
        }

        private ProvinceId SelectedDestinationProvinceId {
            get {
                if (_sortedAdjacentProvinceIds == null || destinationDropdown == null ||
                    destinationDropdown.value < 0 ||
                    destinationDropdown.value >= _sortedAdjacentProvinceIds.Count)
                    return 0;
                return _sortedAdjacentProvinceIds[destinationDropdown.value];
            }
        }

        protected override void SetUpUI() {
            unitsTable.RowCount = BattleAftermathCommand.SurvivingUnits.Count;
            BattleAftermathCommand.SurvivingUnits.Each((cu, idx) => {
                CombatUnitRowController row = unitsTable.ComponentAt<CombatUnitRowController>(idx);
                row.Hero = cu.Hero;
                row.Battalion = cu.Battalion;
            });

            bool canKeep = BattleAftermathCommand.CanKeep;

            ConfigureToggle(keepProvinceToggle, canKeep);
            ConfigureToggle(withdrawToggle, true);

            if (canKeep) {
                keepProvinceToggle.isOn = true;
            } else {
                withdrawToggle.isOn = true;
            }

            SetUpDestinationDropdown();
            SetUpSliders();
            UpdateWithdrawVisibility();

            if (infoText != null) { infoText.text = BattleAftermathCommand.InfoText; }
        }

        private void SetUpDestinationDropdown() {
            _sortedAdjacentProvinceIds = BattleAftermathCommand.AdjacentProvinceIds
                                                 .OrderBy(pid => _model.Provinces[pid].Name)
                                                 .ToList();

            var provinceNames = _sortedAdjacentProvinceIds
                                        .Select(pid => GUIUtils.DarkColoredProvinceName(
                                                        _model.Provinces[pid],
                                                        _model.PlayerId.Value))
                                        .ToList();

            destinationDropdown.ClearOptions();
            destinationDropdown.AddOptions(provinceNames);
            if (provinceNames.Count > 0) { destinationDropdown.SetValueWithoutNotify(0); }
        }

        private void SetUpSliders() {
            goldSlider.minValue = 0;
            goldSlider.maxValue = BattleAftermathCommand.AvailableGold;
            goldSlider.value = BattleAftermathCommand.AvailableGold;
            goldLabel.text = ((int)goldSlider.value).ToString();

            foodSlider.minValue = 0;
            foodSlider.maxValue = BattleAftermathCommand.AvailableFood;
            foodSlider.value = BattleAftermathCommand.AvailableFood;
            foodLabel.text = ((int)foodSlider.value).ToString();
        }

        public void ToggleChanged() { UpdateWithdrawVisibility(); }

        private void UpdateWithdrawVisibility() {
            bool showWithdraw = !IsKeepSelected;
            if (withdrawContainer != null) { withdrawContainer.SetActive(showWithdraw); }
        }

        public void GoldSliderChanged(float newValue) {
            goldLabel.text = ((int)newValue).ToString();
        }

        public void FoodSliderChanged(float newValue) {
            foodLabel.text = ((int)newValue).ToString();
        }

        private const float DisabledAlpha = 0.35f;

        private void ConfigureToggle(Toggle toggle, bool available) {
            if (toggle == null) return;

            toggle.gameObject.SetActive(true);
            toggle.interactable = available;
            toggle.group = null;
            if (!available) { toggle.isOn = false; }
            toggle.group = available ? decisionToggleGroup : null;

            var canvasGroup = toggle.GetComponent<CanvasGroup>();
            if (canvasGroup == null) {
                canvasGroup = toggle.gameObject.AddComponent<CanvasGroup>();
            }
            canvasGroup.alpha = available ? 1f : DisabledAlpha;
        }
    }
}
