using System;
using System.Collections.Generic;
using Net.Eagle0.Eagle.Api;
using Net.Eagle0.Eagle.Views;
using UnityEngine;

namespace eagle {
    using ProvinceId = Int32;
    using HeroId = Int32;
    using BattalionId = Int32;
    using FactionId = Int32;

    public abstract class CommandSelector : MonoBehaviour {
        public Texture ButtonImage;

        public abstract AvailableCommand.SealedValueOneofCase CommandType { get; }
        public virtual bool IsAppropriateFor(AvailableCommand cmd) => cmd.SealedValueCase
                                                                      == CommandType;
        public abstract string HeaderString { get; }
        public abstract string CommitButtonString { get; }
        public abstract SelectedCommand Command { get; }
        protected abstract void SetUpUI();

        public virtual void RefreshUI() {}  // When a setting like DisplayFactionName changes

        // Optional accessors
        protected virtual ProvinceId? TargetedProvince {
            get => null;
            set {}
        }
        public virtual List<ProvinceId> TargetedProvinces {
            get {
                if (TargetedFactionIds.Count > 0) {
                    var list = new List<ProvinceId>();
                    foreach (ProvinceView province in _model.Provinces.Values) {
                        if (province.RulingFactionId is FactionId fid &&
                            TargetedFactionIds.Contains(fid)) {
                            list.Add(province.Id);
                        }
                    }
                    return list;
                }
                if (TargetedProvince is ProvinceId pid) {
                    return new List<ProvinceId> { pid };
                } else
                    return new List<ProvinceId>();
            }
            set {
                switch (value.Count) {
                    case 0: return;
                    case 1: TargetedProvince = value[0]; break;
                    default:
                        throw new ArgumentException(
                                "Unable to handle multiple targeted provinces in default");
                }
            }
        }
        public virtual bool EnableCommitButton => true;
        public virtual string DisabledCommitButtonReason => null;
        public virtual bool WarnOnCommitButton => false;
        public virtual string CommitWarningText => null;

        public virtual List<HeroId> TargetedHeroIds => new();
        public virtual bool HeroIsTargetable(HeroId heroId) => false;
        public virtual void AddTargetedHero(HeroId heroId) {}
        public virtual void RemoveTargetedHero(HeroId heroId) {}

        public virtual List<HeroId> TargetedBattalionIds => new List<BattalionId>();
        public virtual bool BattalionIsTargetable(BattalionId battalionId) => false;
        public virtual void AddTargetedBattalion(BattalionId battalionId) {}
        public virtual void RemoveTargetedBattalion(BattalionId battalionId) {}

        public virtual List<FactionId> TargetedFactionIds => new List<FactionId>();
        public virtual bool FactionIsTargetable(FactionId factionId) => false;
        public virtual void AddTargetedFaction(FactionId factionId) {}
        public virtual void RemoveTargetedFaction(FactionId factionId) {}

        public GameObject Panel => gameObject;

        protected IGameModel _model = null;
        protected AvailableCommand _availableCommand = null;

        public void Show() { Panel.gameObject.SetActive(true); }

        public void Hide() { Panel.gameObject.SetActive(false); }

        public void UpdateAvailableCommand(IGameModel model, AvailableCommand ac) {
            _model = model;
            _availableCommand = ac;
            SetUpUI();
        }
    }
}