using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Xml;
using Newtonsoft.Json;
using RothenburgAR.Common;
using RothenburgAR.Updater;
using UnityEngine;

namespace RothenburgAR.PointOfInterest
{
    public class PoiApiDataPreloader : IPoiPreloader
    {
        public bool CanLoadPoiDirectory(string poiDirectory)
        {
            if (!Directory.Exists(poiDirectory))
                return false;

            var languageDirs = new DirectoryInfo(poiDirectory).GetDirectories().Select(d => d.Name).ToList();
            foreach (var dir in languageDirs)
            {
                var metaFilePath = PathHelper.CombinePaths(poiDirectory, dir, "meta.json");
                if (!File.Exists(metaFilePath)) return false;
            }

            // Todo: More validations
            return true;
        }

        public List<PoiData> PreloadPoi(string poiDirectory)
        {
            List<PoiData> preloadedPois = new List<PoiData>();
            Dictionary<string, List<ApiExhibit>> exhibits = new Dictionary<string, List<ApiExhibit>>();

            var languageDirs = new DirectoryInfo(poiDirectory).GetDirectories().Select(d => d.Name).ToList();
            foreach (var lang in languageDirs)
            {
                var metaFilePath = PathHelper.CombinePaths(poiDirectory, lang, "meta.json");
                if (!File.Exists(metaFilePath)) continue;
                var exhibitList = JsonConvert.DeserializeObject<List<ApiExhibit>>(File.ReadAllText(metaFilePath, System.Text.Encoding.UTF8));
                exhibits.Add(lang, exhibitList);
            }

            var poiIds = exhibits.Values.SelectMany(l => l.SelectMany(e => e.Pois.Select(p => p.Id))).Distinct().ToList();

            Dictionary<string, List<ApiPoi>> poisPerLang = new Dictionary<string, List<ApiPoi>>();
            exhibits.Keys.ToList().ForEach(k =>
                poisPerLang.Add(k, exhibits[k].SelectMany(l => l.Pois.Select(p => p)).Distinct().ToList()));

            foreach (var poiID in poiIds)
            {
                TextElement descElement = new TextElement();
                TextElement titleElement = new TextElement();
                string mediaID = null;

                foreach (var poiPerLang in poisPerLang)
                {
                    var poi = poiPerLang.Value.FirstOrDefault(p => p.Id == poiID);
                    if (poi == null) continue;

                    descElement.AddTextElement(poiPerLang.Key, TextEntryType.Inline, poi.Description);
                    titleElement.AddTextElement(poiPerLang.Key, TextEntryType.Inline, poi.Title);
                    mediaID = poi.MediaId;
                }

                PoiData poiData = new PoiData
                {
                    ID = poiID,
                    Description = descElement,
                    Title = titleElement,
                    SourcePath = poiDirectory
                };

                if (mediaID != null)
                {
                    var modelDescription = new PoiModelDescription();
                    modelDescription.ModelPath = PathHelper.CombinePaths(PathHelper.MediaPath, mediaID, mediaID + ".obj");

                    modelDescription.ModelPrefabName = string.Empty;
                    modelDescription.Scale = Vector3.one;
                    modelDescription.Position = Vector3.zero;
                    modelDescription.Rotation = Vector3.zero;

                    poiData.ModelDescription = modelDescription;
                }

                preloadedPois.Add(poiData);
            }

            return preloadedPois;
        }
    }
}