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

namespace eagle {
    using ProvinceId = Int32;

    public class ResolveRansomOfferCommandSelector : PopupPanelController {
        public Action<SelectedCommand> submissionAction;

        public IGameModel Model { get; set; }

        public HeroDetailsController heroDetailsController;
        public TMP_Text goldAmountLabel;
        private AvailableCommand _availableCommand = null;

        public EventBasedTable exchangedHeroesTable;

        public AvailableCommand AvailableCommand {
            get => _availableCommand;
            set {
                _availableCommand = value;
                if (value == null) {
                    PopupInfos = new List<PopupInfo>();
                } else {
                    var diploOffer =
                            _availableCommand.ResolveRansomOfferCommand.Offers[DisplayedIndex];
                    var ransomOffer = diploOffer.OfferDetails.RansomOffer;
                    FactionView offeringFaction =
                            Model.ActiveFactions[diploOffer.OriginatingFactionId];

                    // If the faction head is being ransomed, show the headshot of the leader
                    // of the offering province. Otherwise, show the faction head's headshot.
                    HeroView displayedHero =
                            offeringFaction.FactionHeadId ==
                                            ransomOffer.PrisonerToBeRansomed.PrisonerHeroId
                                    ? Model.Heroes[diploOffer.OriginatingFactionId]
                                    : Model.Heroes[offeringFaction.FactionHeadId];

                    PopupInfos = _availableCommand.ResolveRansomOfferCommand.Offers
                                         .Select(off => new PopupInfo {
                                             titleText = "Ransom Offered",
                                             mainTextLlmId = off.OfferTextId,
                                             affectedProvinceIds = new List<ProvinceId>(),
                                             displayedHeroes = new List<HeroView> { displayedHero }
                                         })
                                         .ToList();
                }

                SetUpPanel();
            }
        }

        private SelectedCommand SelectedCommand(DiplomacyOfferStatus resolution) => new() {
            ResolveRansomOfferCommand =
                    new ResolveRansomOfferSelectedCommand {
                        Resolution = resolution,
                        OfferingFactionId = AvailableCommand.ResolveRansomOfferCommand
                                                    .Offers[DisplayedIndex]
                                                    .OriginatingFactionId,
                        RansomOffer =
                                AvailableCommand.ResolveRansomOfferCommand.Offers[DisplayedIndex]
                    }
        };

        public void AcceptButtonClicked() {
            submissionAction(SelectedCommand(DiplomacyOfferStatus.Accepted));
            AvailableCommand = null;
            SetUpPanel();
        }

        public void RejectButtonClicked() {
            submissionAction(SelectedCommand(DiplomacyOfferStatus.Rejected));
            AvailableCommand = null;
            SetUpPanel();
        }

        public void ImprisonButtonClicked() {
            submissionAction(SelectedCommand(DiplomacyOfferStatus.Imprisoned));
            AvailableCommand = null;
            SetUpPanel();
        }

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

            mapController.OverrideTargetedProvinces = new List<ProvinceId>();

            if (_availableCommand?.ResolveRansomOfferCommand?.Offers.Count > DisplayedIndex) {
                var diploOffer = _availableCommand.ResolveRansomOfferCommand.Offers[DisplayedIndex];
                var ransomOffer = diploOffer.OfferDetails.RansomOffer;
                heroDetailsController.SetHero(
                        Model.Heroes[ransomOffer.PrisonerToBeRansomed.PrisonerHeroId],
                        Model);
                FactionView offeringFaction = Model.ActiveFactions[diploOffer.OriginatingFactionId];

                mapController.OverrideTargetedProvinces =
                        Model.Provinces.Values.Where(pv => pv.RulingFactionId == offeringFaction.Id)
                                .Select(pv => pv.Id)
                                .ToList();

                exchangedHeroesTable.RowCount = 0;

                var offeringFactionName = Model.FactionName(diploOffer.OriginatingFactionId);
                foreach (var hostage in ransomOffer.HostagesOffered) {
                    var row =
                            exchangedHeroesTable.AddRowWithComponent<ExchangedHeroRowController>();
                    row.SetHostage(Model.Heroes[hostage.HeroId], offeringFactionName);
                }

                foreach (var prisoner in ransomOffer.PrisonersOffered) {
                    var row =
                            exchangedHeroesTable.AddRowWithComponent<ExchangedHeroRowController>();

                    row.SetPrisoner(Model.Heroes[prisoner.HeroId], offeringFactionName);
                }

                goldAmountLabel.text = ransomOffer.GoldOffered.ToString();
            }
        }
    }
}