using System;
using System.Runtime.InteropServices;
using Decal.Interop.Core;

namespace Decal.Core
{
    [ComVisible(true)]
    [Guid("E2284FC7-17E5-4846-ADAB-07953273C5FB")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("Decal.PluginSite2")]
    public class PluginSite2Impl : IPluginSite2
    {
        private DecalCoreImpl _decal;
        private IPlugin2 _plugin;
        private Guid _pluginClsid;

        internal void Setup(DecalCoreImpl decal, IPlugin2 plugin, Guid pluginClsid)
        {
            _decal = decal;
            _plugin = plugin;
            _pluginClsid = pluginClsid;
        }

        public void Unload()
        {
            if (_plugin != null)
            {
                try { _plugin.Terminate(); } catch { }
                _plugin = null;
            }
            _decal?.RemovePlugin(this);
        }

        public object Object
        {
            get
            {
                // Parameterized property: returns service/plugin objects by path
                // Path format: "services\{CLSID}" or "plugins\{CLSID}"
                return null;
            }
        }

        public DecalCore Decal => (DecalCore)(object)_decal;
        public ACHooks Hooks => (ACHooks)(object)_decal?.ACHooksInstance;

        public object PluginSite => this;

        public void RegisterSinks(object pPlugin)
        {
            // Register event sinks for the plugin
            // This connects COM event sources to the plugin's event handlers
        }

        internal IPlugin2 Plugin => _plugin;
        internal Guid PluginClsid => _pluginClsid;

        internal object LookupObject(string path)
        {
            if (string.IsNullOrEmpty(path) || _decal == null)
                return null;

            // Parse path: "collection\{CLSID}\subpath..."
            string[] parts = path.Split('\\');
            if (parts.Length < 2) return null;

            string collection = parts[0].ToLowerInvariant();
            if (!Guid.TryParse(parts[1], out var clsid))
                return null;

            object obj = null;

            if (collection == "services")
                obj = _decal.GetService(clsid);
            else if (collection == "plugins")
                obj = _decal.GetPlugin(clsid);

            // If there are additional path segments, use IDecalDirectory for nested lookup
            if (obj != null && parts.Length > 2)
            {
                for (int i = 2; i < parts.Length; i++)
                {
                    if (obj is IDecalDirectory dir)
                        obj = dir.Lookup(parts[i]);
                    else
                        return null;
                }
            }

            return obj;
        }
    }
}
