using C4IT.Graphics;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
using static C4IT.Logging.cLogManager;

namespace FasdDesktopUi.Basics.Helper
{
    internal sealed class TrayTicketNotificationManager
    {
        private readonly NotifyIcon _notifyIcon;
        private readonly object _syncRoot = new object();
        private string _baseTooltip;
        private string _currentTooltip;
        private bool _overlayInitialized;

        private const string OverlayKey = "TicketChanges";
        private const string OverlaySetName = "OverlayTicketChanges";

        public TrayTicketNotificationManager(NotifyIcon notifyIcon)
        {
            _notifyIcon = notifyIcon ?? throw new ArgumentNullException(nameof(notifyIcon));
        }

        public bool HasNotification
        {
            get
            {
                lock (_syncRoot)
                    return !string.IsNullOrWhiteSpace(_currentTooltip);
            }
        }

        public void CaptureBaseTooltip()
        {
            lock (_syncRoot)
            {
                _baseTooltip = _notifyIcon.Text;
            }
        }

        public void Show(string message)
        {
            if (string.IsNullOrWhiteSpace(message))
            {
                Clear();
                return;
            }

            EnsureOverlaySet();

            lock (_syncRoot)
            {
                _currentTooltip = BuildTooltip(message);
            }

            NotifyerSupport.SetNotifyIconOverlay(OverlayKey, OverlaySetName, NotifyerSupport.enumIconAlignment.TopRight, priority: 100);
            ApplyTooltip();
        }

        public void Clear()
        {
            lock (_syncRoot)
            {
                _currentTooltip = null;
            }

            NotifyerSupport.SetNotifyIconOverlay(OverlayKey, null, NotifyerSupport.enumIconAlignment.TopRight);
            ApplyTooltip();
        }

        public void ApplyTooltip()
        {
            if (_notifyIcon == null)
                return;

            string tooltip;
            lock (_syncRoot)
            {
                tooltip = string.IsNullOrWhiteSpace(_currentTooltip)
                    ? _baseTooltip
                    : $"F4SD - {_currentTooltip}";
            }

            _notifyIcon.Text = TrimTooltip(tooltip);
        }

        private void EnsureOverlaySet()
        {
            if (_overlayInitialized)
                return;

            try
            {
                var overlayFactories = new Dictionary<int, Func<Bitmap>>();
                var sizeMap = new SortedDictionary<int, int>();

                foreach (var size in NotifyerSupport.DefaultIconSizes)
                {
                    var overlaySize = CalculateOverlayDiameter(size);
                    if (overlaySize <= 0)
                        continue;

                    sizeMap[size] = overlaySize;

                    if (!overlayFactories.ContainsKey(overlaySize))
                    {
                        var localSize = overlaySize;
                        overlayFactories[localSize] = () => CreateBadgeBitmap(localSize);
                    }
                }

                var iconSet = NotifyerSupport.RegisterDynamicSet(OverlaySetName, overlayFactories, NoRefresh: true)
                               ?? NotifyerSupport.GetIconSet(OverlaySetName);

                if (iconSet != null)
                {
                    iconSet.SizeMap = sizeMap;
                    _overlayInitialized = true;
                }
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }

        private static string BuildTooltip(string message)
        {
            try
            {
                var parts = message
                    .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(part => part.Trim())
                    .Where(part => part.Length > 0);

                var summary = string.Join(" | ", parts);
                if (summary.Length > 140)
                    summary = summary.Substring(0, 139) + "…";

                return summary;
            }
            catch
            {
                return message;
            }
        }

        private static string TrimTooltip(string tooltip)
        {
            if (string.IsNullOrWhiteSpace(tooltip))
                return tooltip;

            tooltip = tooltip.Replace("\r", " ").Replace("\n", " ");
            tooltip = tooltip.Trim();

            return tooltip.Length <= 63
                ? tooltip
                : tooltip.Substring(0, 63);
        }

        private static int CalculateOverlayDiameter(int baseSize)
        {
            if (baseSize <= 0)
                return 0;

            if (baseSize <= 18)
                return 8;
            if (baseSize <= 26)
                return 10;
            if (baseSize <= 36)
                return 11;

            var diameter = (int)Math.Round(baseSize * 0.22f);
            return Math.Max(9, Math.Min(diameter, baseSize));
        }

        private static Bitmap CreateBadgeBitmap(int size)
        {
            var diameter = Math.Max(2, size);
            var bitmap = new Bitmap(diameter, diameter, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            bitmap.SetResolution(96f, 96f);

            using (var graphics = Graphics.FromImage(bitmap))
            {
                graphics.SmoothingMode = SmoothingMode.AntiAlias;
                graphics.Clear(Color.Transparent);

                int margin = 0;
                if (diameter >= 12)
                    margin = Math.Max(1, (int)Math.Round(diameter * 0.08f));
                else if (diameter >= 9)
                    margin = 1;

                var circleSize = Math.Max(1, diameter - (margin * 2));
                var circleRect = new Rectangle(margin, margin, circleSize, circleSize);

                using (var brush = new SolidBrush(Color.FromArgb(235, 220, 0, 0)))
                {
                    graphics.FillEllipse(brush, circleRect);
                }
            }

            return bitmap;
        }
    }
}
