using ComPDFKitViewer;
using ComPDFKitViewer.AnnotEvent;
using ComPDFKitViewer.PdfViewer;
using PDF_Master.CustomControl.CompositeControl;
using PDF_Master.EventAggregators;
using PDF_Master.Helper;
using PDF_Master.Properties;
using PDF_Master.ViewModels.BOTA;
using PDF_Master.ViewModels;
using PDF_Master.ViewModels.PropertyPanel.AnnotPanel;
using PDF_Master.Views.BOTA;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using PDF_Master.ViewModels.Tools;

namespace PDF_Master.Views.PropertyPanel.AnnotPanel
{
    /// <summary>
    /// StickyNotePopup.xaml 的交互逻辑
    /// </summary>

    public class GripThumb : Thumb
    {
        private Pen DrawPen;
        private Brush FillBrush;

        public GripThumb()
        {
            DefaultStyleKey = typeof(GripThumb);
            DrawPen = new Pen(new SolidColorBrush(Colors.Blue), 2);
            FillBrush = new SolidColorBrush(Color.FromArgb(0x0A, 0xFF, 0xFF, 0xFF));
        }

        protected override void OnRender(DrawingContext DrawContext)
        {
            DrawContext.DrawRectangle(FillBrush, null, new Rect(0, 0, Width, Height));
            DrawContext.DrawLine(DrawPen, new Point(Width, 0), new Point(0, Height));
            DrawContext.DrawLine(DrawPen, new Point(Width, Height / 3), new Point(Width / 3, Height));
            DrawContext.DrawLine(DrawPen, new Point(Width, Height * 2 / 3), new Point(Width * 2 / 3, Height));
        }
    }

    /// <summary>
    /// StickyNotePopup.xaml 的交互逻辑
    /// </summary>
    public partial class StickyNotePopup : StickyPopupExt
    {
        private ObservableCollection<ColorItem> colors = new ObservableCollection<ColorItem>();
        private Point PressPoint;
        public Point OffsetParent;
        public IEventAggregator eventAggregator;
        private byte saveOpacity = 1;
        private string Unicode = "";

        public StickyNotePopup(IEventAggregator eventAggregator)
        {
            this.eventAggregator = eventAggregator;

            InitializeComponent();
            AddHandler(MouseUpEvent, new MouseButtonEventHandler(StickyPopupControl_MouseUp), true);
            ContentText.AddHandler(MouseDownEvent, new MouseButtonEventHandler(StickyPopupControl_MouseDown), true);
            Loaded += StickyPopupControl_Loaded;
            ContentText.GotFocus += ContentText_GotFocus;
            ContentText.LostFocus += ContentText_LostFocus;
            eventAggregator.GetEvent<StickyNotePopupColorEvent>().Subscribe(SetStickyNotePopupColor, e =>
            e.Unicode == Unicode);
            colors.Add(new ColorItem(Color.FromArgb(0xFF, 0xFF, 0xFF, 0x10)));
            colors.Add(new ColorItem(Color.FromArgb(0xFF, 0xFF, 0x10, 0x10)));
            colors.Add(new ColorItem(Color.FromArgb(0xFF, 0x10, 0xFF, 0x10)));
            colors.Add(new ColorItem(Color.FromArgb(0xFF, 0x10, 0x70, 0xFF)));
            ListColor.ItemsSource = colors;
        }

        private void SetStickyNotePopupColor(StickyNoteColorUnicode stickyNoteColorUnicode)
        {
            border.BorderBrush = stickyNoteColorUnicode.brush;
            //if (ListColor.SelectedItem is ColorItem colorItem)
            //{
            //    var color = (colorItem.Color as SolidColorBrush).Color;
            //    if (color.A != GetCurrentAnnot.Color.A ||
            //        color.R != GetCurrentAnnot.Color.R ||
            //        color.G != GetCurrentAnnot.Color.G ||
            //        color.B != GetCurrentAnnot.Color.B
            //        )
            //    {
            //        ListColor.SelectedIndex = -1;
            //    }
            //}
            foreach (var item in colors)
            {
                var colorItem = (item.Color as SolidColorBrush).Color;
                if (colorItem.A == GetCurrentAnnot.Color.A &&
                    colorItem.R == GetCurrentAnnot.Color.R &&
                    colorItem.G == GetCurrentAnnot.Color.G &&
                    colorItem.B == GetCurrentAnnot.Color.B
                    )
                {
                    ListColor.SelectedItem = item;
                    return;
                }
                else
                {
                    ListColor.SelectedIndex = -1;
                }
            }
        }

        private void ContentText_LostFocus(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
            Color bkColor = (border.BorderBrush as SolidColorBrush).Color;
            bkColor.A = saveOpacity;
            border.BorderBrush = new SolidColorBrush(bkColor);
            this.Background = new SolidColorBrush(Colors.Transparent);
            this.BorderBrush = new SolidColorBrush(Colors.Transparent);

            //为了点击某控件之后就直接关闭窗口
            var ui = Mouse.DirectlyOver as FrameworkElement;
            if (ui != null)
            {
                var colorItem = ui.DataContext as ColorItem;
                if (colorItem != null || ui.DataContext == null)
                {
                    e.Handled = false;
                    return;
                }
            }
            eventAggregator.GetEvent<StickyNoteEvent>().Publish(new StickyNoteArgs() { Unicode = Unicode, Text = (e.Source as TextBox).Text });
            (DataContext as StickyNotePopupViewModel).ContentTextLostFocus.Execute(sender);
            CloseText_MouseUp(this, null);
        }

        private void ContentText_GotFocus(object sender, RoutedEventArgs e)
        {
            Color bkColor = (border.BorderBrush as SolidColorBrush).Color;
            saveOpacity = bkColor.A;
            bkColor.A = 255;
            border.BorderBrush = new SolidColorBrush(bkColor);
            this.Background = new SolidColorBrush(Colors.Transparent);
            this.BorderBrush = new SolidColorBrush(Colors.Transparent);
        }

        private void StickyPopupControl_Loaded(object sender, RoutedEventArgs e)
        {
            Unicode = App.mainWindowViewModel.SelectedItem.Unicode;
            ContentText.Focus();
            ContentText.CaretIndex = ContentText.Text.Length;
            LoadedColor();
            if (GetPDFViewer != null)
            {
                GetPDFViewer.PreviewMouseLeftButtonDown -= GetPDFViewer_LeftButtonDown;
                GetPDFViewer.PreviewMouseLeftButtonDown += GetPDFViewer_LeftButtonDown;

                KeyEventsHelper.KeyDown -= ShortCut_KeyDown;
                KeyEventsHelper.KeyDown += ShortCut_KeyDown;
            }
        }

        private void ShortCut_KeyDown(object sender, KeyEventArgs e)
        {
            if (KeyEventsHelper.IsSingleKey(Key.Delete))
            {
                BtnDelete_Click(null, null);
            }
            if (KeyEventsHelper.IsSingleKey(Key.Escape))
            {
                CloseText_MouseUp(this, null);
                GetPDFViewer.PreviewMouseLeftButtonDown -= GetPDFViewer_LeftButtonDown;
            }
        }

        private void GetPDFViewer_LeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var ui = e.OriginalSource as FrameworkElement;
            if (ui != null)
            {
                if (ui.DataContext != null && ui.DataContext is ColorItem == false)
                {
                    CloseText_MouseUp(this, null);
                    GetPDFViewer.PreviewMouseLeftButtonDown -= GetPDFViewer_LeftButtonDown;
                }
            }
        }

        public void LoadedColor()
        {
            if (colors != null && colors.Count > 0)
            {
                BtnDelete.DataContext = colors[0];//为了避免点击删除按钮之后,先执行取消焦点函数后,就没法执行点击事件

                if (GetCurrentAnnot != null)
                {
                    foreach (var item in colors)
                    {
                        var colorItem = (item.Color as SolidColorBrush).Color;
                        if (colorItem.A == GetCurrentAnnot.Color.A &&
                            colorItem.R == GetCurrentAnnot.Color.R &&
                            colorItem.G == GetCurrentAnnot.Color.G &&
                            colorItem.B == GetCurrentAnnot.Color.B
                            )
                        {
                            ListColor.SelectedItem = item;
                            return;
                        }
                    }
                }

                ListColor.SelectedItem = null;
            }
        }

        private void StickyPopupControl_MouseDown(object sender, MouseButtonEventArgs e)
        {
            PressPoint = new Point(0, 0);
        }

        private void StickyPopupControl_MouseUp(object sender, MouseButtonEventArgs e)
        {
            CanMove = true;
            GripControl.ReleaseMouseCapture();
        }

        public string StickyText
        {
            get
            {
                return ContentText.Text;
            }
            set
            {
                ContentText.Text = value;
            }
        }

        public string StickyAuthor
        {
            get
            {
                return AuthorText.Text;
            }
            set
            {
                AuthorText.Text = value;
            }
        }

        public string StickyDate
        {
            get
            {
                return DateText.Text;
            }
            set
            {
                DateText.Text = value;
            }
        }

        public StickyAnnotArgs GetCurrentAnnot { get; set; }
        public CPDFViewer GetPDFViewer { get; set; }
        public AnnotToolContentViewModel AnnotToolContentVM { get; set; }
        public bool CanMove { get; set; } = true;

        private void ResizeGrip_MouseMove(object sender, MouseEventArgs e)
        {
            e.Handled = true;
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                Point currentPos = e.GetPosition(ContainerElement);
                double newWidth = GridUi.ActualWidth + currentPos.X - PressPoint.X;
                double newHeight = GridUi.ActualHeight + currentPos.Y - PressPoint.Y;
                if (Left + newWidth >= ContainerElement.ActualWidth)
                {
                    newWidth = ContainerElement.ActualWidth - Left - 5;
                }
                if (Top + newHeight >= ContainerElement.ActualHeight)
                {
                    newHeight = ContainerElement.ActualHeight - Top - 5;
                }
                GridUi.Width = newWidth;
                GridUi.Height = newHeight;
                PressPoint = currentPos;
                CanMove = false;
                if (GripControl.IsMouseCaptured == false)
                {
                    GripControl.CaptureMouse();
                }
            }
        }

        private void CloseText_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (e != null)
            {
                e.Handled = true;
            }
            PlaceChange = null;
            RemoveFromLayer();
            if (Closed != null)
            {
                Closed.Invoke(sender, EventArgs.Empty);
            }
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            e.Handled = true;
            PressPoint = e.GetPosition(ContainerElement);
        }

        protected override void OnMouseEnter(MouseEventArgs e)
        {
            e.Handled = true;
            if (PlaceChange != null)
            {
                PlaceChange.Invoke(this, new EventArgs());
            }
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            e.Handled = true;
            if (PlaceChange != null)
            {
                PlaceChange.Invoke(null, new EventArgs());
            }
            PressPoint = new Point(0, 0);
        }

        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            CanMove = true;
            if (PlaceChange != null)
            {
                PlaceChange.Invoke(this, new EventArgs());
            }
            PressPoint = new Point(0, 0);
            GripControl.ReleaseMouseCapture();
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            e.Handled = true;
            if (e.LeftButton == MouseButtonState.Pressed && e.Source.GetType() != typeof(TextBox) && e.Source.GetType() != typeof(GripThumb))
            {
                if (CanMove == false || (PressPoint.X == 0 && PressPoint.Y == 0) || ContainerElement == null)
                {
                    return;
                }
                Point currentPoint = e.GetPosition(ContainerElement);
                double newLeft = Left + currentPoint.X - PressPoint.X;
                double newTop = Top + currentPoint.Y - PressPoint.Y;
                if (newLeft < 0)
                {
                    newLeft = 0;
                }
                if (newLeft + GridUi.ActualWidth > ContainerElement.ActualWidth)
                {
                    newLeft = ContainerElement.ActualWidth - GridUi.ActualWidth;
                }
                if (newTop < 0)
                {
                    newTop = 0;
                }
                if (newTop + GridUi.ActualHeight > ContainerElement.ActualHeight)
                {
                    newTop = ContainerElement.ActualHeight - GridUi.ActualHeight;
                }
                Left = newLeft;
                Top = newTop;
                PressPoint = currentPoint;
                if (PlaceChange != null)
                {
                    PlaceChange.Invoke(null, new EventArgs());
                }
                RefreshPosition();
            }
        }

        public override void SetAuthor(string author)
        {
            base.SetAuthor(author);
            StickyAuthor = author;
        }

        public override void SetDateText(string dateText)
        {
            base.SetDateText(dateText);
            if (Regex.IsMatch(dateText, "(?<=D\\:)[0-9]+(?=[\\+\\-])"))
            {
                string dateStr = Regex.Match(dateText, "(?<=D\\:)[0-9]+(?=[\\+\\-])").Value;
                dateText = dateStr.Substring(4, 2) + "/" + dateStr.Substring(6, 2) + "/" + dateStr.Substring(0, 4) + " " + dateStr.Substring(8, 2) + ":" +
                    dateStr.Substring(10, 2) + ":" + dateStr.Substring(12, 2);
            }
            StickyDate = dateText;
        }

        public override void SetStickyColor(Color newColor)
        {
            base.SetStickyColor(newColor);
            border.BorderBrush = new SolidColorBrush(newColor);
            this.Background = new SolidColorBrush(Colors.Transparent);
            this.BorderBrush = new SolidColorBrush(Colors.Transparent);
        }

        public override void SetStickyNote(string note)
        {
            base.SetStickyNote(note);
            StickyText = note;
            try
            {
                ContentText.FontFamily = new FontFamily(Settings.Default.AppProperties.Annotate.AnchoredFamaily);
            }
            catch (Exception ex)
            {
            }
        }

        public override void SetReadOnly(bool readOnly)
        {
            base.SetReadOnly(readOnly);
            ContentText.IsReadOnly = readOnly;
        }

        public override string GetText()
        {
            return StickyText;
        }

        /// <summary>
        /// 鼠标滚动后,图标消失,弹框消失
        /// </summary>
        public override void Close()
        {
            //base.Close();
            RemoveFromLayer();
        }

        private void ListColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var colorItem = ListColor.SelectedItem as ColorItem;
            if (colorItem != null)
            {
                var color = (colorItem.Color as SolidColorBrush).Color;
                this.SetStickyColor(color);
                var annot = GetCurrentAnnot as StickyAnnotArgs;
                if (annot != null)
                {
                    annot.Color = color;
                    var AnnotEvent = AnnotAttribEvent.GetAnnotAttribEvent(annot, annot.GetAnnotAttrib());
                    AnnotEvent?.UpdateAttrib(AnnotAttrib.Color, color);
                    AnnotEvent?.UpdateAnnot();
                }

                border.BorderBrush = new SolidColorBrush(color);
                this.Background = new SolidColorBrush(Colors.Transparent);
                this.BorderBrush = new SolidColorBrush(Colors.Transparent);
                eventAggregator.GetEvent<StickyNoteColorEvent>().Publish(new StickyNoteColorUnicode { Unicode = Unicode, brush = new SolidColorBrush(color) });
            }
        }

        private void BtnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (GetPDFViewer != null)
            {
                //猜测:此方法对GetCurrentAnnot进行了修改,所以删除要在修改后删除,而非修改前
                CloseText_MouseUp(this, null);
                if (GetCurrentAnnot != null)
                {
                    bool result = GetPDFViewer.RemovePageAnnot(GetCurrentAnnot.PageIndex, GetCurrentAnnot.AnnotIndex);
                    if (result && AnnotToolContentVM != null)
                    {
                        if (string.IsNullOrEmpty(AnnotToolContentVM.StrAnnotToolChecked))
                        {
                            AnnotToolContentVM.ViewContentViewModel.SelectedPrpoertyPanel("PropertyPanelContent", null);
                        }
                        bool isTabItemAnnotation = AnnotToolContentVM.IsBOTATabItemShow(out BOTAContentViewModel bOTAContentViewModel, out BOTAContent bOTAContent, "TabItemAnnotation");
                        if (isTabItemAnnotation)
                        {
                            AnnotationContentViewModel viewModel = AnnotToolContentVM.GetAnnotationContentViewModel(bOTAContentViewModel, out AnnotationContent annotation);
                            if (viewModel != null)
                            {
                                viewModel.DeleteModifiedAnnot(GetCurrentAnnot.PageIndex, GetCurrentAnnot.AnnotIndex);
                            }
                        }
                    }
                }

                // Closed.Invoke(sender, EventArgs.Empty);
                //CloseText_MouseUp(this, null);
                if (GetPDFViewer.ToolManager != null)
                {
                    GetPDFViewer.ToolManager.DisableStickyCreate = false;
                }
            }
            else
            {
                CloseText_MouseUp(this, null);
            }
        }

        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var frame = e.OriginalSource as Control;
            if (frame != null)
            {
                var color = frame.Background as SolidColorBrush;
                if (color != null && color.Color == Colors.Transparent)
                    Closed.Invoke(sender, EventArgs.Empty);
            }
        }

        private void StickyPopupExt_LostFocus(object sender, RoutedEventArgs e)
        {
        }

        private void StickyPopupExt_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                BtnDelete_Click(null, null);
            }
            if (e.Key == Key.Enter)
            {
                CloseText_MouseUp(this, null);
                GetPDFViewer.PreviewMouseLeftButtonDown -= GetPDFViewer_LeftButtonDown;
            }
        }
    }
}