using AssortGenerator.Common.Helpers;
using QuestValidator.Common;
using QuestValidator.Common.Helpers;
using QuestValidator.Helpers;
using QuestValidator.Models;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

namespace GenerateQuestFile
{
    class Program
    {
        /// <summary>
        /// Generate a quests.json file in /output/
        /// Uses every quest from the live quest dump file
        /// If any quests are missing, it will use the quests.json file to fill in the blanks
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            var inputPath = DiskHelpers.CreateWorkingFolders();
            InputFileHelper.SetInputFiles(inputPath);

            //read in quest files
            var questData = QuestHelper.GetQuestData();
            var liveQuestData = QuestHelper.GetLiveQuestData();
            //var oldQuestData = QuestHelper.GetQuestData("oldQuests");

            // Find the quests that are missing from the live file
            var missingQuests = new List<Quest>();
            foreach (var quest in questData.Values)
            {
                if (quest._id == "5936da9e86f7742d65037edf")
                {

                }

                var liveQuest = liveQuestData.data.Find(x => x._id == quest._id);
                if (liveQuest == null)
                {
                    missingQuests.Add(quest);
                    LoggingHelpers.LogError($"ERROR Quest {quest._id} {QuestHelper.GetQuestNameById(quest._id)}  missing in live");
                }
            }

            // Create a list of quests to output
            // use all quests in live file
            // Use quests from quests.json to fill in missing quests
            var questsToOutputToFile = new Dictionary<string, Quest>();
            //create live version of quests.json
            foreach (var quest in liveQuestData.data)
            {
                var questName = QuestHelper.GetQuestNameById(quest._id); // special characters like ", brake the client when it parses it
                var rgx = new Regex("[^a-zA-Z0-9 -]");
                quest.QuestName = rgx.Replace(questName, "");
                questsToOutputToFile.Add(quest._id, quest);
            }
            foreach (var missingQuest in missingQuests)
            {
                missingQuest.QuestName = QuestHelper.GetQuestNameById(missingQuest._id);
                questsToOutputToFile.Add(missingQuest._id, missingQuest);
            }

            

            foreach (var quest in questsToOutputToFile)
            {
                if (quest.Key == "5c0d4c12d09282029f539173")
                {
                    
                }

                var originalQuest = questData.FirstOrDefault(x => x.Key == quest.Key).Value;
                if (originalQuest.conditions.AvailableForStart.Count > 0)
                {
                    // Iterate over quest requirements in existing qeust file
                    foreach (var questRequirementToAdd in originalQuest.conditions.AvailableForStart.ToList())
                    {
                        //Exists already
                        if (quest.Value.conditions.AvailableForStart.Any(x => x._parent == questRequirementToAdd._parent
                        && x._props.target?.ToString() == questRequirementToAdd._props.target?.ToString()))
                        {
                            continue;
                        }

                        quest.Value.conditions.AvailableForStart.Add(questRequirementToAdd);
                    }
                }
            }

            // iterate over qeust objects a final time and add hard coded quest requirements if they dont already exist
            foreach (var quest in questsToOutputToFile)
            {
                if (quest.Key == "5c0d4c12d09282029f539173")
                {
                    //fishin gear
                }

                var questRequirement = QuestHelper.GetQuestDependancy(quest.Key);
                if (questRequirement == null || questRequirement.PreceedingQuest?.Length == 0)
                {
                    continue;
                }

                if (!quest.Value.conditions.AvailableForStart.Any(x => x._parent == "Quest" 
                        && x._props.target.ToString() == questRequirement.PreceedingQuest))
                {
                    LoggingHelpers.LogSuccess($"{quest.Value.QuestName} needs a prereq of quest {questRequirement.GetQuestName()}, adding.");
                    quest.Value.conditions.AvailableForStart.Add(new AvailableFor
                    {
                        _parent = "Quest",
                        _props = new AvailableForProps
                        {
                            id = "",
                            index = quest.Value.conditions.AvailableForStart.Count,
                            parentId = "",
                            status = new[] { questRequirement.QuestStatus },
                            target = questRequirement.PreceedingQuest
                        }
                    }
                        );
                }
                else
                {
                    if (questRequirement != null)
                    {
                        LoggingHelpers.LogInfo($"{quest.Value.QuestName} already has prereq of quest {questRequirement.GetQuestName()}, skipping.");
                    }
                }
            }

            JsonWriter.WriteJson(questsToOutputToFile, "output", Directory.GetCurrentDirectory(), "quests");
        }
    }
}