using System;
using System.Collections.Generic;
using System.Linq;
using Net.Eagle0.Eagle.Api;
using Net.Eagle0.Eagle.Views;
using TMPro;

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

    public class SuppressBeastsCommandSelector : CommandSelector {
        public HeroDropdownController heroDropdownController;
        public BattalionDropdownController battalionDropdownController;
        public TextMeshProUGUI beastDescriptionText;

        public override AvailableCommand.SealedValueOneofCase CommandType =>
                AvailableCommand.SealedValueOneofCase.SuppressBeastsCommand;
        public override string HeaderString =>
                $"Suppress {DisplayNames.Capitalized(BeastTypeName)}";
        public override string CommitButtonString => "Commit Suppression";
        public override bool WarnOnCommitButton => !SelectedBattalionId.HasValue;
        public override string CommitWarningText =>
                "You aren't sending a battalion. Your hero may be killed.";

        public override List<HeroId> TargetedHeroIds => new List<HeroId> { SelectedHeroId };
        public override bool HeroIsTargetable(HeroId heroId) =>
                SuppressBrigandsAvailableCommand.AvailableHeroIds.Contains(heroId);
        public override void AddTargetedHero(HeroId heroId) =>
                heroDropdownController.SelectedHeroId = heroId;

        public override List<BattalionId> TargetedBattalionIds =>
                SelectedBattalionId.HasValue ? new List<BattalionId> { SelectedBattalionId.Value }
                                             : new List<BattalionId>();
        public override bool BattalionIsTargetable(BattalionId bid) =>
                SuppressBrigandsAvailableCommand.AvailableBattalionIds.Contains(bid);
        public override void AddTargetedBattalion(BattalionId bid) =>
                battalionDropdownController.SelectedBattalionId = bid;

        private SuppressBeastsAvailableCommand SuppressBrigandsAvailableCommand =>
                _availableCommand.SuppressBeastsCommand;
        private ProvinceId ActingProvinceId => SuppressBrigandsAvailableCommand.ActingProvinceId;

        private String BeastTypeName {
            get {
                if (Province == null) return "";
                var beastEvents = Province.KnownEvents.Where(ev => ev.BeastsEvent != null);

                if (!beastEvents.Any()) return "";

                return BeastCount == 1 ? beastEvents.First().BeastsEvent.BeastInfo.SingularName
                                       : beastEvents.First().BeastsEvent.BeastInfo.PluralName;
            }
        }

        private int BeastCount {
            get {
                if (Province == null) return 0;
                var beastEvents = Province.KnownEvents.Where(ev => ev.BeastsEvent != null);

                if (!beastEvents.Any()) return 0;

                return beastEvents.First().BeastsEvent.Count;
            }
        }

        private ProvinceView Province => _model == null ? null : _model.Provinces[ActingProvinceId];

        protected override void SetUpUI() {
            heroDropdownController.AvailableHeroes =
                    SuppressBrigandsAvailableCommand.AvailableHeroIds
                            .Select(id => _model.Heroes[id])
                            .ToList();

            var availableBattalions =
                    SuppressBrigandsAvailableCommand.AvailableBattalionIds
                            .Select(id => Province.FullInfo.Battalions.First(b => b.Id == id))
                            .OrderBy(batt => batt.Type)
                            .ToList();

            battalionDropdownController.AvailableBattalions = availableBattalions;

            var maxSize = availableBattalions.Max(x => x.Size);
            battalionDropdownController.SelectedBattalionId =
                    availableBattalions.Where(batt => batt.Size == maxSize)
                            .Select(batt => (BattalionId?)batt.Id)
                            .FirstOrDefault();

            var beastName = BeastTypeName;
            var count = BeastCount;

            beastDescriptionText.text = $"We face {count} {beastName}!";
        }

        private HeroId SelectedHeroId => heroDropdownController.SelectedHeroId;
        private BattalionId? SelectedBattalionId => battalionDropdownController.SelectedBattalionId;

        public override SelectedCommand Command => new() {
            SuppressBeastsCommand =
                    new SuppressBeastsSelectedCommand {
                        HeroId = SelectedHeroId,
                        BattalionId = SelectedBattalionId
                    }
        };
    }
}