using System;
using System.Collections.Generic;
using System.IO;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using Decal.Adapter;

namespace MosswartMassacre
{
    public class PluginSettings
    {
        private static PluginSettings _instance;
        private static string _filePath;
        private static readonly object _sync = new object();

        // backing fields
        private bool _rareMetaEnabled = true;
        private bool _webSocketEnabled = false;
        private bool _inventorylog = true;
        private string _charTag = "default";
        private int _mainWindowX = 100;
        private int _mainWindowY = 100;
        private bool _useTabbedInterface = true;
        private string _vtankProfilesPath = "";
        private bool _verboseLogging = false;
        private bool _autoUpdateEnabled = true;
        private bool _vitalSharingEnabled = false;
        private int _vitalSharingOverlayX = 50;
        private int _vitalSharingOverlayY = 200;
        private ChestLooterSettings _chestLooterSettings = new ChestLooterSettings();

        public static PluginSettings Instance => _instance
            ?? throw new InvalidOperationException("PluginSettings not initialized");

        public static bool IsInitialized => _instance != null;

        public static void Initialize()
        {
            // determine plugin folder and character-specific folder
            string characterName = CoreManager.Current.CharacterFilter.Name;
            
            // For hot reload scenarios, use the AssemblyDirectory set by the Loader
            // For normal loading, fall back to the executing assembly location
            string pluginFolder;
            if (!string.IsNullOrEmpty(PluginCore.AssemblyDirectory))
            {
                pluginFolder = PluginCore.AssemblyDirectory;
            }
            else
            {
                pluginFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            }

            // Path for character-specific folder
            string characterFolder = Path.Combine(pluginFolder, characterName);

            // Create the character folder if it doesn't exist
            if (!Directory.Exists(characterFolder))
            {
                try
                {
                    Directory.CreateDirectory(characterFolder);
                }
                catch (Exception ex)
                {
                    PluginCore.DispatchChatToBoxWithPluginIntercept($"[Settings] Failed to create character folder: {ex.Message}");
                }
            }

            // YAML file is now in the character-specific folder
            _filePath = Path.Combine(characterFolder, $"{characterName}.yaml");

            // build serializer/deserializer once
            var builder = new DeserializerBuilder()
                .WithNamingConvention(UnderscoredNamingConvention.Instance)
                .IgnoreUnmatchedProperties();
            var deserializer = builder.Build();

            PluginSettings loaded = null;

            if (File.Exists(_filePath))
            {
                try
                {
                    string yaml = File.ReadAllText(_filePath);
                    loaded = deserializer.Deserialize<PluginSettings>(yaml);
                }
                catch (Exception ex)
                {
                    PluginCore.DispatchChatToBoxWithPluginIntercept(
                        $"[MosswartMassacre] Error reading settings, using defaults: {ex.Message}");
                }
            }

            if (loaded == null)
            {
                // either file didn't exist, was empty, or deserialized as null
                _instance = new PluginSettings();
                Save();  // write out default skeleton
            }
            else
            {
                _instance = loaded;
                Save();
            }
        }

        public static void Save()
        {
            lock (_sync)
            {
                try
                {
                    // serialize to YAML
                    var serializer = new SerializerBuilder()
                        .WithNamingConvention(UnderscoredNamingConvention.Instance)
                        .Build();
                    var yaml = serializer.Serialize(_instance);

                    // write temp file
                    var temp = _filePath + ".tmp";
                    File.WriteAllText(temp, yaml);

                    // if the settings file already exists, do an atomic Replace
                    if (File.Exists(_filePath))
                    {
                        File.Replace(temp, _filePath, null);
                    }
                    else
                    {
                        // first‐time save: just move the temp into place
                        File.Move(temp, _filePath);
                    }
                }
                catch (Exception ex)
                {
                    // log to chat so you can see what went wrong
                    CoreManager.Current.Actions.AddChatText(
                        $"[MosswartMassacre] Error saving settings: {ex.Message}", 5);
                }
            }
        }

        // public properties
        public bool RareMetaEnabled
        {
            get => _rareMetaEnabled;
            set { _rareMetaEnabled = value; Save(); }
        }

        public bool WebSocketEnabled
        {
            get => _webSocketEnabled;
            set { _webSocketEnabled = value; Save(); }
        }
        public string CharTag
        {
            get => _charTag;
            set { _charTag = value; Save(); }
        }
        public bool InventoryLog
        {
            get => _inventorylog;
            set { _inventorylog = value; Save(); }
        }

        public int MainWindowX
        {
            get => _mainWindowX;
            set { _mainWindowX = value; Save(); }
        }

        public int MainWindowY
        {
            get => _mainWindowY;
            set { _mainWindowY = value; Save(); }
        }

        public bool UseTabbedInterface
        {
            get => _useTabbedInterface;
            set { _useTabbedInterface = value; Save(); }
        }

        public string VTankProfilesPath
        {
            get => _vtankProfilesPath;
            set { _vtankProfilesPath = value; Save(); }
        }

        public bool VerboseLogging
        {
            get => _verboseLogging;
            set { _verboseLogging = value; Save(); }
        }

        public bool AutoUpdateEnabled
        {
            get => _autoUpdateEnabled;
            set { _autoUpdateEnabled = value; Save(); }
        }

        public bool VitalSharingEnabled
        {
            get => _vitalSharingEnabled;
            set { _vitalSharingEnabled = value; Save(); }
        }

        public int VitalSharingOverlayX
        {
            get => _vitalSharingOverlayX;
            set { _vitalSharingOverlayX = value; Save(); }
        }

        public int VitalSharingOverlayY
        {
            get => _vitalSharingOverlayY;
            set { _vitalSharingOverlayY = value; Save(); }
        }

        public ChestLooterSettings ChestLooterSettings
        {
            get
            {
                if (_chestLooterSettings == null)
                {
                    _chestLooterSettings = new ChestLooterSettings();
                }
                return _chestLooterSettings;
            }
            set
            {
                _chestLooterSettings = value;
                Save();
            }
        }
    }
}
