using System;
using System.Collections.Generic;
using Net.Eagle0.Eagle.Common;
using Net.Eagle0.Eagle.Views;

namespace eagle.Notifications.ARNNotifications {
    using ProvinceId = Int32;
    using HeroId = Int32;

    public static class NewFactionHeadDetailsNotificationGenerator {
        public static readonly ARNNotificationGenerator Generator = GenerateNotifications;

        private static readonly Random Random = new();

        private static readonly List<string> NotificationTitles = new() {
            "New Leadership",
            "Succession",
            "A New Era",
            "Rise to Power",
            "The Mantle Passes",
            "Heir Ascendant",
            "Crown of Command",
            "Leadership Transferred",
            "The Torch Passes",
            "New Commander"
        };

        private static string GetNotificationTitle() {
            return NotificationTitles[Random.Next(NotificationTitles.Count)];
        }

        private static ProvinceId? FindProvinceForHero(HeroId heroId, IGameModel model) {
            foreach (var province in model.Provinces.Values) {
                if (province.FullInfo?.RulingFactionHeroIds.Contains(heroId) == true) {
                    return province.Id;
                }
            }
            return null;
        }

        private static IEnumerable<Notification> GenerateNotifications(
                Net.Eagle0.Eagle.Common.Notification notification,
                IGameModel currentModel) {
            var details = notification.Details.NewFactionHeadDetails;
            var newHeadHero = currentModel.Heroes[details.NewHeadHeroId];
            var previousHeadHero =
                    currentModel.Heroes.TryGetValue(details.PreviousHeadHeroId, out var prev)
                            ? prev
                            : null;

            string textTemplate;
            List<ProvinceId> affectedProvinces;

            if (details.FactionId == currentModel.PlayerId) {
                // Player's own faction - their new faction head
                string previousHeadDescription =
                        previousHeadHero != null ? $"Following the death of {{PreviousHead}}, your"
                                                 : "Your";
                textTemplate =
                        $"{previousHeadDescription} sworn {DisplayNames.SiblingDescription(newHeadHero.PronounGender)} {{NewHead}} now leads your faction.\n\n";

                var heroProvinceId = FindProvinceForHero(details.NewHeadHeroId, currentModel);
                affectedProvinces = heroProvinceId.HasValue
                                            ? new List<ProvinceId> { heroProvinceId.Value }
                                            : currentModel.ProvincesForFaction(details.FactionId);
            } else {
                // Another faction
                var factionName = currentModel.FactionName(details.FactionId);
                if (previousHeadHero != null) {
                    textTemplate =
                            $"Following the death of {{PreviousHead}}, {{NewHead}} now leads {factionName}.\n\n";
                } else {
                    textTemplate = $"{{NewHead}} now leads {factionName}.\n\n";
                }
                affectedProvinces = currentModel.ProvincesForFaction(details.FactionId);
            }

            var heroPlaceholders = new Dictionary<string, (string nameTextId, string fallback)> {
                { "NewHead", (newHeadHero.NameTextId, "A hero") }
            };
            if (previousHeadHero != null) {
                heroPlaceholders["PreviousHead"] =
                        (previousHeadHero.NameTextId, "the previous leader");
            }

            var displayedHeroes = new List<HeroView> { newHeadHero };
            if (previousHeadHero != null) { displayedHeroes.Add(previousHeadHero); }

            yield return DynamicTextNotification.StreamingDynamicNotification(
                    title: GetNotificationTitle(),
                    textTemplate: textTemplate,
                    heroPlaceholders: heroPlaceholders,
                    llmId: notification.LlmId,
                    provinceIds: affectedProvinces,
                    displayedHeroes: displayedHeroes);
        }
    }
}
