using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Timers;
using VirindiViewService;
using VirindiViewService.XMLParsers;

namespace MosswartMassacre.Views
{
    /// <summary>
    /// Base class for VVS (VirindiViewService) based views.
    /// Replaces the wrapper-based BaseView with direct VVS integration.
    /// </summary>
    public class VVSBaseView : IDisposable
    {
        #region Windows API for boundary checking
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;

            public int Width { get { return Right - Left; } }
            public int Height { get { return Bottom - Top; } }
        }

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
        #endregion

        #region Core VVS Components
        protected HudView view;
        protected ViewProperties properties;
        protected ControlGroup controls;
        protected PluginCore pluginCore;
        #endregion

        #region Position Management
        private Timer positionSaveTimer;
        #endregion

        public VVSBaseView(PluginCore core)
        {
            pluginCore = core;
            InitializePositionTimer();
        }

        #region VVS Initialization
        protected void CreateFromXMLResource(string resourcePath, bool doIcon = true, bool doTitle = true)
        {
            try
            {
                // Parse XML using VVS Decal3XMLParser
                new Decal3XMLParser().ParseFromResource(resourcePath, out properties, out controls);

                // Set window properties
                if (doTitle)
                {
                    properties.Title = $"Mosswart Massacre v{Constants.PluginVersion}";
                }

                if (doIcon)
                {
                    // Use default icon for now - can be customized later
                    properties.Icon = 7735; // Same icon as in XML
                }

                // Create the HudView
                view = new HudView(properties, controls);
                
                // Subscribe to essential events
                view.VisibleChanged += View_VisibleChanged;
                view.Moved += View_Moved;
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error creating VVS view from {resourcePath}: {ex.Message}");
                PluginCore.WriteToChat($"Stack trace: {ex.StackTrace}");
            }
        }

        protected void CreateFromXMLString(string xmlString, bool doIcon = true, bool doTitle = true)
        {
            try
            {
                // Parse XML string using VVS Decal3XMLParser
                new Decal3XMLParser().Parse(xmlString, out properties, out controls);

                if (doTitle)
                {
                    properties.Title = $"Mosswart Massacre v{Constants.PluginVersion}";
                }

                if (doIcon)
                {
                    properties.Icon = 7735;
                }

                view = new HudView(properties, controls);
                view.VisibleChanged += View_VisibleChanged;
                view.Moved += View_Moved;
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error creating VVS view from XML string: {ex.Message}");
            }
        }
        #endregion

        #region Control Access
        /// <summary>
        /// Get a control by name with proper type casting.
        /// Usage: var button = GetControl&lt;HudButton&gt;("btnExample");
        /// </summary>
        protected T GetControl<T>(string controlName) where T : class
        {
            try
            {
                if (view != null && view[controlName] != null)
                {
                    return view[controlName] as T;
                }
                return null;
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error getting control '{controlName}': {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// Get a control by name (alternative syntax)
        /// Usage: var button = (HudButton)GetControl("btnExample");
        /// </summary>
        protected object GetControl(string controlName)
        {
            try
            {
                return view?[controlName];
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error getting control '{controlName}': {ex.Message}");
                return null;
            }
        }
        #endregion

        #region Window Management
        protected virtual void SaveWindowPosition()
        {
            try
            {
                if (view != null && PluginSettings.IsInitialized)
                {
                    PluginSettings.Instance.MainWindowX = view.Location.X;
                    PluginSettings.Instance.MainWindowY = view.Location.Y;
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error saving window position: {ex.Message}");
            }
        }

        protected virtual void RestoreWindowPosition()
        {
            try
            {
                if (view != null && PluginSettings.IsInitialized)
                {
                    view.Location = new Point(
                        PluginSettings.Instance.MainWindowX,
                        PluginSettings.Instance.MainWindowY
                    );
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error restoring window position: {ex.Message}");
            }
        }

        protected void KeepWindowInBounds()
        {
            try
            {
                if (view == null) return;

                RECT rect = new RECT();
                IntPtr gameWindowHandle = PluginCore.MyHost?.Decal?.Hwnd ?? IntPtr.Zero;
                
                if (gameWindowHandle != IntPtr.Zero && GetWindowRect(gameWindowHandle, ref rect))
                {
                    Point currentLocation = view.Location;
                    int viewWidth = view.Width;
                    int viewHeight = view.Height;
                    
                    bool needsUpdate = false;
                    
                    // Check right boundary
                    if (currentLocation.X + viewWidth > rect.Width)
                    {
                        currentLocation.X = rect.Width - viewWidth;
                        needsUpdate = true;
                    }
                    // Check left boundary
                    else if (currentLocation.X < 0)
                    {
                        currentLocation.X = 20;
                        needsUpdate = true;
                    }

                    // Check bottom boundary
                    if (currentLocation.Y + viewHeight > rect.Height)
                    {
                        currentLocation.Y = rect.Height - viewHeight;
                        needsUpdate = true;
                    }
                    // Check top boundary
                    else if (currentLocation.Y < 0)
                    {
                        currentLocation.Y = 20;
                        needsUpdate = true;
                    }

                    if (needsUpdate)
                    {
                        view.Location = currentLocation;
                    }
                }
            }
            catch
            {
                // Silently ignore boundary check errors
            }
        }
        #endregion

        #region Position Timer Management
        private void InitializePositionTimer()
        {
            positionSaveTimer = new Timer(2000); // 2 second delay after movement stops
            positionSaveTimer.Elapsed += (s, e) => {
                SaveWindowPosition();
                positionSaveTimer.Stop();
            };
        }

        private void View_Moved(object sender, EventArgs e)
        {
            try
            {
                // Reset timer when window moves
                if (positionSaveTimer != null)
                {
                    if (positionSaveTimer.Enabled)
                        positionSaveTimer.Stop();
                    
                    positionSaveTimer.Start();
                }
            }
            catch
            {
                // Ignore timer errors
            }
        }

        protected virtual void View_VisibleChanged(object sender, EventArgs e)
        {
            try
            {
                if (view.Visible)
                {
                    KeepWindowInBounds();
                }
            }
            catch
            {
                // Ignore visibility change errors
            }
        }
        #endregion

        #region Public Interface
        public virtual void Initialize()
        {
            try
            {
                RestoreWindowPosition();
                KeepWindowInBounds();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing VVS view: {ex.Message}");
            }
        }

        public virtual void Show()
        {
            if (view != null)
            {
                view.Visible = true;
            }
        }

        public virtual void Hide()
        {
            if (view != null)
            {
                view.Visible = false;
            }
        }

        public virtual void Toggle()
        {
            if (view != null)
            {
                view.Visible = !view.Visible;
            }
        }

        public bool IsVisible
        {
            get { return view?.Visible ?? false; }
        }

        public Point Location
        {
            get { return view?.Location ?? Point.Empty; }
            set { if (view != null) view.Location = value; }
        }

        public Size Size
        {
            get { return view != null ? new Size(view.Width, view.Height) : Size.Empty; }
        }
        #endregion

        #region IDisposable Support
        private bool disposedValue = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    try
                    {
                        // Save final position before disposal
                        SaveWindowPosition();
                        
                        // Clean up timers
                        if (positionSaveTimer != null)
                        {
                            positionSaveTimer.Stop();
                            positionSaveTimer.Dispose();
                            positionSaveTimer = null;
                        }
                        
                        // Clean up VVS view
                        if (view != null)
                        {
                            view.VisibleChanged -= View_VisibleChanged;
                            view.Moved -= View_Moved;
                            view.Dispose();
                            view = null;
                        }
                        
                        // Clean up VVS objects
                        properties = null;
                        controls = null;
                    }
                    catch (Exception ex)
                    {
                        PluginCore.WriteToChat($"Error disposing VVS view: {ex.Message}");
                    }
                }
                disposedValue = true;
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}
