using System.Collections.ObjectModel;
using Dock.Model.Core;
using Dock.Serializer;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PSCHelpdesk.Shared.Model;
using PSCHelpdesk.Shared.Service;

namespace PSCHelpdesk.Shared.Setting;

public class SettingsManager: ISettingsManager
{
    public string DataRoot => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "PSC", "PSCHelpDesk");

    private string SettingsPath => Path.Combine(this.DataRoot, "settings.json");

    public SettingsManager()
    {
        Directory.CreateDirectory(this.DataRoot);
        this.LoadSettings();
    }

    /// <summary>
    /// Gets or sets the core settings instance.
    /// </summary>
    public CoreSettings CoreSettings { get; set; } = new CoreSettings();

    /// <summary>
    /// Gets or sets the UI Settings instance.
    /// </summary>
   // public UISettings UISettings { get; set; } = new UISettings();

    private string SettingsFile { get; set; }

    /// <summary>
    /// Reads the configuration file.
    /// </summary>
    public void LoadSettings()
    {
        if (File.Exists(this.SettingsPath))
        {
            string json = File.ReadAllText(this.SettingsPath);
            JsonConvert.PopulateObject(json, this.CoreSettings);
        }
        else
        {
            this.CoreSettings = new CoreSettings();
        }
    }

    /// <summary>
    /// Saves the configuration file.
    /// </summary>
    public void SaveSettings()
    {
        // serialize JSON directly to a file
        using (StreamWriter file = File.CreateText(this.SettingsPath))
        {
            JsonSerializer serializer = new JsonSerializer()
            {
                Formatting = Formatting.Indented,
            };

            serializer.Serialize(file, this.CoreSettings);
        }
    }
    
    public void LoadPluginSettings(string pluginName, object? settingsObject)
    {

        var pluginSettingsPath = Path.Combine(this.CoreSettings.GlobalConfigFilePath, pluginName + "_settings.json");
        
        if (File.Exists(pluginSettingsPath))
        {
            string json = File.ReadAllText(pluginSettingsPath);
            JsonConvert.PopulateObject(json, settingsObject);
        }
    }
    
    public void SavePluginSettings(string pluginName, object? settingsObject)
    {
        var pluginSettingsPath = Path.Combine(this.CoreSettings.GlobalConfigFilePath, pluginName + "_settings.json");
        
        using (StreamWriter file = File.CreateText(pluginSettingsPath))
        {
            JsonSerializer serializer = new JsonSerializer()
            {
                Formatting = Formatting.Indented,
            };

            serializer.Serialize(file, settingsObject);
        }
    }

    public void SaveLayoutModels(IDock? data)
    {
        var settingsPath = Path.Combine(this.DataRoot, "layout_settings.json");
        var jsonSettings = new JsonSerializerSettings()
        {
            Formatting = Formatting.Indented,
            TypeNameHandling = TypeNameHandling.Objects,
            PreserveReferencesHandling = PreserveReferencesHandling.Objects,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
            ContractResolver = new ListContractResolver(typeof(ObservableCollection<>)),
            NullValueHandling = NullValueHandling.Ignore,
            Converters =
            {
                new KeyValuePairConverter()
            }
        };
        
        using (StreamWriter file = File.CreateText(settingsPath))
        {
            file.Write(JsonConvert.SerializeObject(data, jsonSettings));
        }
    }

    public IDock LoadLayoutModels()
    {
        var settingsPath = Path.Combine(this.DataRoot, "layout_settings.json");
        var jsonSettings = new JsonSerializerSettings()
        {
            Formatting = Formatting.Indented,
            TypeNameHandling = TypeNameHandling.Objects,
            PreserveReferencesHandling = PreserveReferencesHandling.Objects,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
            ContractResolver = new ListContractResolver(typeof(ObservableCollection<>)),
            NullValueHandling = NullValueHandling.Ignore,
            Converters =
            {
                new KeyValuePairConverter()
            }
        };
        var layoutModels = JsonConvert.DeserializeObject<IDock>(File.ReadAllText(settingsPath), jsonSettings);
        return layoutModels;
    }
}
