using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using Elfisa.UI.Helpers;
using Elfisa.UI.Theming;

namespace Elfisa.UI.Controls
{
    public class ModernSearchBox : UserControl
    {
        private readonly ModernTextBox _textBox;
        private readonly Label _iconLabel;
        private readonly AnimationTimer _focusAnim;
        private ThemeColors _theme;
        private bool _showSearchIcon = true;
        private float _focusProgress;

        public bool ShowSearchIcon
        {
            get => _showSearchIcon;
            set
            {
                _showSearchIcon = value;
                _iconLabel.Visible = value;
                Invalidate();
            }
        }

        public override string Text
        {
            get => _textBox.Text;
            set => _textBox.Text = value;
        }

        public new event EventHandler TextChanged;

        public ModernSearchBox()
        {
            Height = 38;
            Padding = new Padding(0);
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                     ControlStyles.UserPaint |
                     ControlStyles.OptimizedDoubleBuffer |
                     ControlStyles.ResizeRedraw, true);
            _focusAnim = new AnimationTimer(v =>
            {
                _focusProgress = v;
                Invalidate();
            });
            _iconLabel = new Label
            {
                Text = "\uE721",
                Font = new Font("Segoe MDL2 Assets", 12f),
                AutoSize = false,
                Width = 34,
                TextAlign = ContentAlignment.MiddleCenter,
                Dock = DockStyle.Left
            };
            _textBox = new ModernTextBox
            {
                BorderStyle = BorderStyle.None,
                Dock = DockStyle.Fill
            };
            _textBox.TextChanged += (_, __) => TextChanged?.Invoke(this, EventArgs.Empty);
            _textBox.Enter += (_, __) => _focusAnim.AnimateTo(1f, 150);
            _textBox.Leave += (_, __) => _focusAnim.AnimateTo(0f, 150);
            Controls.Add(_textBox);
            Controls.Add(_iconLabel);
        }

        public void ApplyTheme(ThemeColors theme)
        {
            _theme = theme;
            BackColor = theme.InputBackground;
            _textBox.ApplyTheme(theme);
            _iconLabel.ForeColor = theme.TextMuted;
            _iconLabel.BackColor = theme.InputBackground;
            Padding = new Padding(1);
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            var theme = _theme ?? ThemeManager.Colors;
            var g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            var bounds = new Rectangle(0, 0, Width - 1, Height - 1);
            var radius = theme.CornerRadiusSmall;
            using (var brush = new SolidBrush(theme.InputBackground))
            {
                GraphicsExtensions.FillRoundedRectangle(g, brush, bounds, radius);
            }

            var borderColor = GraphicsExtensions.LerpColor(theme.InputBorder, theme.InputBorderFocus, _focusProgress);
            var borderWidth = 1f + (_focusProgress * 0.5f);
            using (var pen = new Pen(borderColor, borderWidth))
            {
                GraphicsExtensions.DrawRoundedRectangle(g, pen, bounds, radius);
            }

            if (_focusProgress > 0.01f)
            {
                var glowAlpha = (int)(40 * _focusProgress);
                var glowRect = new Rectangle(bounds.X + 1, bounds.Y + 1, bounds.Width - 2, bounds.Height - 2);
                using (var glowPen = new Pen(Color.FromArgb(glowAlpha, theme.InputBorderFocus), 2f))
                {
                    GraphicsExtensions.DrawRoundedRectangle(g, glowPen, glowRect, Math.Max(0, radius - 1));
                }
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _focusAnim.Dispose();
            }

            base.Dispose(disposing);
        }
    }
}
