using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Xml.Serialization;
using System.Collections.ObjectModel;
using System.Text.Json;
using Models.Game;
using Models.Interfaces;

namespace DataContractPersistence
{
    public class DataContractJson : IPersistence
    {
        /// <summary>
        /// Name of the file where the data will be saved
        /// </summary>
        public string FileName { get; set; } = "data.json";

        /// <summary>
        /// Path (relative to the project)
        /// </summary>
        public string FilePath { get; set; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Trek_12");

        /// <summary>
        /// Load all the data from JSON file
        /// </summary>
        /// <returns>A tuple with the lists of players, games, maps and best scores</returns>
        public (ObservableCollection<Player>, ObservableCollection<Game>, ObservableCollection<Map>, ObservableCollection<BestScore>) LoadData()
        {
            var JsonSerializer = new DataContractJsonSerializer(typeof(DataToPersist));
            DataToPersist? data = new DataToPersist();

            using (Stream s = File.OpenRead(Path.Combine(FilePath, FileName)))
            {
                data = JsonSerializer.ReadObject(s) as DataToPersist;
            }
            Console.WriteLine("Data loaded: " + Path.Combine(FilePath, FileName));
            return (data.Players, data.Games, data.Maps, data.BestScores);
        }

        /// <summary>
        /// Save all the data to a JSON file
        /// </summary>
        /// <param name="players"></param>
        /// <param name="games"></param>
        /// <param name="maps"></param>
        /// <param name="bestScores"></param>
        public void SaveData(ObservableCollection<Player> players, ObservableCollection<Game> games, ObservableCollection<Map> maps, ObservableCollection<BestScore> bestScores)
        {
            Debug.WriteLine("Saving data at " + Path.Combine(FilePath, FileName));
            if (!Directory.Exists(FilePath))
            {
                Debug.WriteLine("Directory created");
                Debug.WriteLine(Directory.GetDirectoryRoot(FilePath));
                Debug.WriteLine(FilePath);
                Directory.CreateDirectory(FilePath);
            }

            var JsonSerializer = new DataContractJsonSerializer(typeof(DataToPersist));
            DataToPersist? data = new DataToPersist();

            data.Players = players;
            data.Games = games;
            data.Maps = maps;
            data.BestScores = bestScores;

            var settings = new XmlWriterSettings() { Indent = true };
            using (FileStream stream = File.Create(Path.Combine(FilePath, FileName)))
            {
                using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
                           stream,
                           Encoding.UTF8,
                           false,
                           true))
                {
                    JsonSerializer.WriteObject(writer, data);
                    writer.Flush();
                }
            }
        }
    }
}
