using System;
using System.Configuration;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using InABox.Core;
using InABox.Wpf;
using InABox.WPF;

namespace InABox.DynamicGrid
{

    public enum DynamicMenuStatus
    {
        Enabled,
        Disabled,
        Hidden
    }
    
    public class DynamicMenuColumn : DynamicImageColumn
    {
        private readonly BuildMenu _build;

        private readonly ContextMenu _menu;
        
        private readonly Func<CoreRow, DynamicMenuStatus>? _status;
        
        private readonly BitmapImage _enabled = Resources.menu.AsBitmapImage();
        private readonly BitmapImage _disabled = Resources.menu.Fade(0.25F).AsBitmapImage();

        public delegate void BuildMenu(DynamicMenuColumn column, CoreRow? row);

        public DynamicMenuColumn(BuildMenu build, Func<CoreRow, DynamicMenuStatus>? status = null, GetImageDelegate? getImage = null) : base(r => null)
        {
            _menu = new ContextMenu();

            AllowHeaderClick = false;
            _build = build;
            _status = status;

            Image = getImage ?? (row =>
            {
                if (row == null)
                    return null;
                var s = _status?.Invoke(row);
                if (s == null)
                    return _enabled;
                if (s == DynamicMenuStatus.Enabled)
                    return _enabled;
                if (s == DynamicMenuStatus.Disabled)
                    return _disabled;
                return null;
            });
                
            Action = r =>
            {
                if ((_status == null) || _status.Invoke(r)== DynamicMenuStatus.Enabled)
                {
                    _menu.Tag = r;
                    _menu.Items.Clear();
                    _build?.Invoke(this, r);
                    if (_menu.HasItems)
                        _menu.IsOpen = true;
                }
                return false;
            };
        }

        public ContextMenu GetMenu() => _menu;
        
        public MenuItem AddItem(string text, System.Drawing.Bitmap? image, Action<CoreRow?>? action, object? parent = null, bool enabled = true)
        {
            var item = new MenuItem();
            if (image != null)
                item.Icon = new Image() { Source = enabled ? image.AsBitmapImage(24,24) : image.AsGrayScale().AsBitmapImage(24,24)  };
            item.Header = text;
            item.Tag = action;
            item.IsEnabled = enabled;
            item.IsCheckable = false;
            item.Click += (o, e) =>
            {
                var r = GetRow((MenuItem)o);
                action?.Invoke(r);
            };
            if (parent == null)
                _menu.Items.Add(item);
            else
                ((MenuItem)parent).Items.Add(item);
            return item;
        }
        
        public MenuItem AddCalendar(string text, DateTime startDate, System.Drawing.Bitmap? image, Action<CoreRow?, DateTime?>? action, object? parent = null, bool enabled = true)
        {
            var item = new MenuItem();
            if (image != null)
                item.Icon = new Image() { Source = enabled ? image.AsBitmapImage(24,24) : image.AsGrayScale().AsBitmapImage(24,24)  };

            var calendarItem = new MenuItem();

            var calendar = new Calendar { DisplayDate = startDate, SelectedDate = null };

            calendar.SelectedDatesChanged += (o, e) =>
            {
                var r = GetRow(calendarItem);
                action?.Invoke(r, calendar.SelectedDate);

                _menu.IsOpen = false;
            };

            calendarItem.Header = calendar;
            calendarItem.Style = DynamicGridUtils.Resources["NonHighlightMenuItem"] as Style;

            item.Header = text;
            item.Items.Add(calendarItem);

            item.IsEnabled = enabled;
            item.IsCheckable = false;
            if (parent == null)
                _menu.Items.Add(item);
            else
                ((MenuItem)parent).Items.Add(item);
            return item;
        }

        public void AddSeparator(object? parent = null)
        {
            var item = new Separator();
            if (parent == null)
                _menu.Items.Add(item);
            else
                ((MenuItem)parent).Items.Add(item);
        }

        private CoreRow? GetRow(MenuItem? item)
        {
            if (item == null)
                return null;

            if (item.Parent is ContextMenu)
                return (item.Parent as ContextMenu)?.Tag as CoreRow;

            return GetRow(item.Parent as MenuItem);
        }
    }
}