using Microsoft.UI.Input;
using Microsoft.UI.Xaml.Input;
using System;
using Windows.Foundation;
using Windows.System;

namespace Sonex.Client.Controls.DataGridView
{
    // Odpowiedzialnosc pliku: interakcje wskaznika dla naglowkow (sortowanie, drag, resize, pin/hide).
    public sealed partial class DataGridView
    {
        private void OnHeaderPressedAsync(PointerRoutedEventArgs e)
        {

            PointerPoint? pointer = e.GetCurrentPoint(_Canvas);
            var column = GetColumnAtPosition(pointer.Position);

            bool Shift = e.KeyModifiers.HasFlag(VirtualKeyModifiers.Shift);
            bool Alt = e.KeyModifiers.HasFlag(VirtualKeyModifiers.Menu);
            bool Ctrl = e.KeyModifiers.HasFlag(VirtualKeyModifiers.Control);

            if (column != null)
                column.IsPressed = true;

            if (column != null && HoverHeaderArea == HeaderArea.Text)
            {
                ColumnDraging = column;
                ColumnDragingOffset = pointer.Position.X - column.LeftOnScreen;
                RequestRender();

            }
            if (column != null && HoverHeaderArea == HeaderArea.Separator)
            {
                CursorResizeHorizontal();
                ColumnResizing = column;
                ColumnResizing.IsResizing = true;
                RequestRender();
                return;
            }
            if (column != null && HoverHeaderArea == HeaderArea.Menu)
            {
                column.ShowFilter();
                return;
            }

            RequestRender();
        }

        private void OnHeaderDrag(PointerRoutedEventArgs e)
        {

            PointerPoint? pointer = e.GetCurrentPoint(_Canvas);
            HeaderHitInfo hitInfo = GetHeaderAreaAtPosition(pointer.Position);
            var column = hitInfo.Column;

            if (ColumnResizing != null)
            {
                ColumnResizing.ManualWidth = pointer.Position.X - ColumnResizing.LeftOnScreen;
            }

            // Przeciąganie kolumny
            if (isHeaderTextHover && column != null && ColumnDraging != null)
            {
                ColumnDraging.IsDraging = ColumnDraging.IsDraging || Math.Abs(pointer.Position.X - (ColumnDraging.LeftOnScreen + ColumnDragingOffset)) > 6;
                if (ColumnDraging.IsDraging)
                {
                    ColumnDraging.DragingOffset = pointer.Position.X - ColumnDragingOffset;
                    ColumnDragingDropLeftOrRight = ColumnDraging.DragingOffset + ColumnDragingOffset < column.LeftOnScreen + (column.Width * 0.5);
                    ColumnDragingDropPoint = ColumnDragingDropLeftOrRight ? column.LeftOnScreen : column.LeftOnScreen + column.Width;
                }




                // Przewijanie krawędziowe w poziomie

                if (pointer.Position.X > ActualWidth - 40)
                {
                    double power = Math.Clamp((1d - ((ActualWidth - pointer.Position.X) / 40d)) * 40d, 1d, 40d);
                    _ScrollMoverHorizontal.GoToEnd(step: power);
                }
                else if (pointer.Position.X < _IndexColWidth + _PinedColWidth + 40)
                {
                    //double power = Math.Clamp((1d - ((pointer.Position.X - (_IndexColWidth + _PinedColWidth)) / 80d)) * 25, 1, 25);
                    double power = (1d - (Math.Clamp(pointer.Position.X - _IndexColWidth - _PinedColWidth, 0, 40) / 40d)) * 40d;
                    _ScrollMoverHorizontal.GoToStart(step: power);
                }
                else
                    _ScrollMoverHorizontal.Stop();

                RequestRender();

            }
            _NeedCalcHeaders = true;
            _NeedCalcHorizontalScroll = true;
            RequestRender();
        }
        private void OnHeaderMoved(PointerRoutedEventArgs e)
        {
            PointerPoint? pointer = e.GetCurrentPoint(_Canvas);
            HeaderHitInfo hitInfo = GetHeaderAreaAtPosition(pointer.Position);

            if (HeaderHover?.Name == hitInfo.Column?.Name && HoverHeaderArea == hitInfo.Area)
            {
                // return;
            }
            HeaderHover = hitInfo.Column;
            HoverHeaderArea = hitInfo.Area;

            if (HoverHeaderArea == HeaderArea.Separator)
                CursorResizeHorizontal();
            else if (ProtectedCursor != null)
                CursorDefault();

            RequestRender();
        }

        private void OnHeaderReleased(PointerRoutedEventArgs e)
        {
            _ScrollMoverHorizontal.Stop();

            // zakończenie zmiany rozmiaru kolumny
            if (ColumnResizing != null)
            {
                ColumnResizing.IsResizing = false;
                ColumnResizing = null;
                _NeedCalcHeaders = true;
                _NeedCalcHorizontalScroll = true;
                RequestRender();
            }

            if (HeaderHover != null)
                HeaderHover.IsPressed = false;

            PointerPoint? pointer = e.GetCurrentPoint(_Canvas);
            var target = GetColumnAtPosition(pointer.Position);

            bool Shift = e.KeyModifiers.HasFlag(VirtualKeyModifiers.Shift);
            bool Alt = e.KeyModifiers.HasFlag(VirtualKeyModifiers.Menu);
            bool Ctrl = e.KeyModifiers.HasFlag(VirtualKeyModifiers.Control);

            if (HeaderHover != null && HoverHeaderArea == HeaderArea.Text && !HeaderHover.IsDraging)
            {
                if (Ctrl)
                {
                    HeaderHover.isSelected = !HeaderHover.isSelected;
                }
                else if (Alt)
                {
                    HideColumn(HeaderHover.Name);
                }
                else if (Shift)
                {
                    if (HeaderHover.IsPinned)
                        UnPin(HeaderHover.Name);
                    else
                        Pin(HeaderHover.Name);
                }
                else
                {
                    HeaderHover.Sort();
                }
                RequestRender();
            }

            if (ColumnDraging != null)
            {


                if (target != null)
                {
                    ColumnDragingDropLeftOrRight = ColumnDraging.DragingOffset + ColumnDragingOffset < target.LeftOnScreen + (target.Width * 0.5);

                    if (ColumnDragingDropLeftOrRight)
                    {
                        var index = target.Index - 1;
                        foreach (var col in _Columns)
                        {
                            if (col.Index < target.Index)
                                col.Index--;
                        }
                        ColumnDraging.Index = index;
                    }
                    else
                    {
                        var index = target.Index + 1;
                        foreach (var col in _Columns)
                        {
                            if (col.Index > target.Index)
                                col.Index++;
                        }
                        ColumnDraging.Index = index;
                    }


                    //ColumnDraging.DragingOffset;
                }

                ColumnDraging.IsDraging = false;
                ColumnDraging = null;
                _NeedCalcHeaders = true;
                RequestRender();
            }
            if (target != null && HoverHeaderArea == HeaderArea.Menu)
            {
                //column.ShowFilter();
            }
            if (target != null && HoverHeaderArea == HeaderArea.Text)
            {
            }
            else
            {
                RequestRender();
            }
            UpdateFooterTextSelected();

        }

        private void OnHeaderDoubleTapped(PointerPoint pointer)
        {
            var column = GetColumnAtPosition(pointer.Position);

            if (column != null && HoverHeaderArea == HeaderArea.Separator)
            {
                column.AutoSize();
                RequestRender();
            }
        }
        private HeaderHitInfo GetHeaderAreaAtPosition(Point position)
        {
            if (ColumnResizing != null)
                return new HeaderHitInfo(ColumnResizing, HeaderArea.Separator);

            // lewy górny róg
            if (position.X < _IndexColWidth)
                return new HeaderHitInfo(null, HeaderArea.Settings);



            // jeśli nie wykryje kolumny 
            var column = GetColumnAtPosition(position);
            if (column == null)
                return new HeaderHitInfo(null, HeaderArea.None);


            var right = column.LeftOnScreen + column.Width;


            if (position.X > right - 8 && position.X < right + 8)
                return new HeaderHitInfo(column, HeaderArea.Separator);

            if (position.X + 24 >= right)
                return new HeaderHitInfo(column, HeaderArea.Menu);


            return new HeaderHitInfo(column, HeaderArea.Text);
        }
        public enum HeaderArea
        {
            None = 0,
            Text = 1,
            Separator = 2,
            Settings = 3,
            Menu = 4,

        }
        public record HeaderHitInfo(Column? Column, HeaderArea Area);

    }
}
