using QuestValidator.Common.Helpers;
using QuestValidator.Models;
using QuestValidator.Models.Other;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;

namespace AssortGenerator.Common.Helpers
{
    public static class QuestHelper
    {
        // Quest to lookup is key, previous quest is PreceedingQuest value

        private static List<QuestRoot> _liveQuestData;
        private static Dictionary<string, QuestValidator.Models.Quest> _questData;
        private static List<string> _questBlacklistData;
        private static List<AssortUnlocks> _assortUnlocks;

        public static Dictionary<string, QuestValidator.Models.Quest> GetQuestData(string filename = "quests")
        {
            if (_questData is null)
            {
                var questFilePath = InputFileHelper.GetInputFilePaths().FirstOrDefault(x => x.Contains(filename));
                if (questFilePath is null)
                {
                    return null;
                }

                var questDataJson = File.ReadAllText(questFilePath);
                _questData = JsonSerializer.Deserialize<Dictionary<string, QuestValidator.Models.Quest>>(questDataJson);
            }

            return _questData;
        }

        /// <summary>
        /// Merge all live quest dumps into one file
        /// </summary>
        /// <param name="liveQuestDataFiles"></param>
        /// <returns></returns>
        public static QuestRoot MergeLiveQuestFiles(List<QuestRoot> liveQuestDataFiles, List<string> questBlacklist)
        {
            QuestRoot mergedResult = new QuestRoot
            {
                data = new List<Quest>()
            };
            foreach (var liveQuestDataFile in liveQuestDataFiles)
            {
                foreach (var quest in liveQuestDataFile.data)
                {
                    // Skip quests on blacklist
                    if (questBlacklist.Contains(quest._id))
                    {
                        continue;
                    }

                    // Already has quest, skip
                    var mergedExistingQuest = mergedResult.data.FirstOrDefault(x => x._id == quest._id);
                    if (mergedExistingQuest != null)
                    {
                        // new quest has more `avail for start` conditions, use instead
                        if (mergedExistingQuest.conditions.AvailableForStart.Count < quest.conditions.AvailableForStart.Count)
                        {
                            mergedExistingQuest = quest;
                        }
                        continue;
                    }

                    mergedResult.data.Add(quest);
                }
            }

            return mergedResult;
        }

        public static List<QuestRoot> GetLiveQuestData(string filename = "resp.client.quest.list")
        {
            if (_liveQuestData is null)
            {
                _liveQuestData = new List<QuestRoot>();
                var questFilePaths = InputFileHelper.GetInputFilePaths().Where(x => x.Contains(filename));
                if (questFilePaths is null)
                {
                    return null;
                }

                foreach (var questFilepath in questFilePaths)
                {
                    var questDataJson = File.ReadAllText(questFilepath);
                    _liveQuestData.Add(JsonSerializer.Deserialize<QuestRoot>(questDataJson));
                }
            }

            return _liveQuestData;
        }

        public static string GetQuestNameById(string id)
        {
            return QuestNames.GetNameById(id);
        }

        public static List<AssortUnlocks> GetAssortUnlocks()
        {
            if (_assortUnlocks is null)
            {
                _assortUnlocks = new List<AssortUnlocks>();
                foreach (var quest in GetQuestData())
                {
                    foreach (var reward in quest.Value.rewards.Success)
                    {
                        if (string.Equals(reward.type, "assortmentunlock", System.StringComparison.OrdinalIgnoreCase))
                        {
                            _assortUnlocks.Add(new AssortUnlocks
                            {
                                AssortUnlockId = reward.id,
                                ItemUnlockedId = reward.target,
                                ItemUnlockedTemplateId = reward.items[0]._tpl,
                                LoyaltyLevel = (int)reward.loyaltyLevel,
                                QuestId = quest.Key,
                                QuestRewardId = reward.id,
                                TraderId = reward.traderId,
                                TraderType = TraderHelper.GetTraderTypeById(reward.traderId),
                                Criteria = "Success"
                            }
                        );
                        }
                    }
                }
            }

            return _assortUnlocks;
        }

        public static bool DoesIconExist(string iconPath, string imageId)
        {
            var filesInPath = Directory.GetFiles(iconPath);
            return filesInPath.Any(x => x.Contains(imageId));
        }

        public static List<string> GetQuestBlacklist()
        {
            if (_questBlacklistData is null)
            {
                var questBlacklistPath = InputFileHelper.GetInputFilePaths().FirstOrDefault(x => x.Contains("blacklist"));
                if (questBlacklistPath is null)
                {
                    return null;
                }

                var questBlacklistJson = File.ReadAllText(questBlacklistPath);
                _questBlacklistData = JsonSerializer.Deserialize<List<string>>(questBlacklistJson);
            }

            return _questBlacklistData;
        }
    }
}