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

namespace Sonex.Client.Controls.DataGridView
{
    // Odpowiedzialnosc pliku: centralny routing zdarzen wskaznika (mysz/touch) do obszarow gridu.
    public sealed partial class DataGridView
    {
        private AreaType _ActualArea = AreaType.None;
        private AreaType _HandleArea = AreaType.None;
        private bool MouseLeftButtonDown = false;
        private bool MouseRightButtonDown = false;
        DateTime lastPointerPressedTime = DateTime.MinValue;

        // Po wyjściu kursora czyścimy hover nagłówka, aby uniknąć "wiszących" stanów UI.
        private void _Canvas_PointerExited(object sender, PointerRoutedEventArgs e)
        {
            HeaderHover = null;
            RequestRender();
        }

        private void _Canvas_DoubleTapped(object sender, PointerPoint e)
        {
            _Canvas.Focus(Microsoft.UI.Xaml.FocusState.Programmatic);
            var area = GetPoiterArea(e.Position);
            if (area == _HandleArea)
            {
                return;
            }
            else
            {
                _HandleArea = area;
                switch (area)
                {
                    case AreaType.Cell:
                        OnCellDoubleTapped(e);
                        break;
                    case AreaType.Header:
                        OnHeaderDoubleTapped(e);
                        break;
                    case AreaType.Index:
                        OnIndexDoubleTapped(e);
                        break;
                    default: break;
                }
            }
        }
        private void _Canvas_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            _Canvas.Focus(Microsoft.UI.Xaml.FocusState.Pointer);
            // Główne wejście "PointerPressed": wykrywa obszar i deleguje do odpowiedniego handlera.
            PointerPoint? pointer = e.GetCurrentPoint(_Canvas);
            if (pointer == null)
            {
                return;
            }

            MouseLeftButtonDown = pointer.Properties.IsLeftButtonPressed;
            MouseRightButtonDown = pointer.Properties.IsRightButtonPressed;

            if (MouseRightButtonDown)
            {
                _Canvas.CapturePointer(e.Pointer);
                _Canvas.Focus(Microsoft.UI.Xaml.FocusState.Programmatic);
                e.Handled = true;
                return;
            }

            if (lastPointerPressedTime.AddMilliseconds(300) > DateTime.Now)
                _Canvas_DoubleTapped(sender, pointer);
            lastPointerPressedTime = DateTime.Now;

            _Canvas.CapturePointer(e.Pointer); // przejęcie
            _Canvas.Focus(Microsoft.UI.Xaml.FocusState.Programmatic);
            e.Handled = true;
            var area = GetPoiterArea(pointer);
            if (area == _HandleArea)
            {
                return;
            }
            else
            {
                _HandleArea = area;
                switch (area)
                {
                    case AreaType.Cell:
                        OnCellPressed(e);
                        break;
                    case AreaType.Header:
                        OnHeaderPressedAsync(e);
                        break;
                    case AreaType.Index:
                        OnIndexPressed(e);
                        break;
                    default: break;
                }
            }
            base.OnPointerPressed(e);

        }



        private void _Canvas_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            //HeaderHover = null;

            if (MouseLeftButtonDown)
            {
                switch (_HandleArea)
                {
                    case AreaType.Cell:
                        OnCellDrag(e);
                        break;
                    case AreaType.Header:
                        OnHeaderDrag(e);
                        break;
                    case AreaType.Index:
                        OnIndexDrag(e);
                        break;
                    default:
                        _ActualArea = GetPoiterArea(e.GetCurrentPoint(_Canvas));
                        break;
                }
                e.Handled = true;
            }
            else
            {
                var area = GetPoiterArea(e.GetCurrentPoint(_Canvas));
                if (area != _ActualArea)
                {
                    _ActualArea = area;
                    HeaderHover = null;
                    RequestRender();
                }
                switch (_ActualArea)
                {
                    case AreaType.Cell:
                        CursorDefault();
                        OnCellMoved(e);
                        break;
                    case AreaType.Header:
                        OnHeaderMoved(e);
                        break;
                    case AreaType.Index:
                        CursorDefault();
                        //OnIndexMoved(e);
                        break;
                    default:
                        CursorDefault();
                        break;
                }

            }
        }
        private void _Canvas_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            CursorDefault();
            PointerPoint? pointer = e.GetCurrentPoint(_Canvas);

            _Canvas.Focus(Microsoft.UI.Xaml.FocusState.Programmatic);
            e.Handled = false;
            _Canvas.ReleasePointerCapture(e.Pointer);
            var shouldOpenContextMenu = MouseRightButtonDown && pointer != null && !pointer.Properties.IsRightButtonPressed;
            if (shouldOpenContextMenu && pointer != null)
            {
                // Menu pokazujemy na "button up", dzięki temu szybkie kliknięcie prawym działa poprawnie.
                e.Handled = true;
                CursorDefault();
                ShowContextMenu(pointer.Position, GetPoiterArea(pointer));
                CursorDefault();
            }
            else if (MouseLeftButtonDown)
            {
                switch (_HandleArea)
                {
                    case AreaType.Cell:
                        OnCellReleased(e);
                        break;
                    case AreaType.Header:
                        OnHeaderReleased(e);
                        break;
                    case AreaType.Index:
                        OnIndexReleased(e);
                        break;
                    default:
                        break;
                }
            }
            _HandleArea = AreaType.None;
            if (pointer != null)
            {
                MouseLeftButtonDown = pointer.Properties.IsLeftButtonPressed;
                MouseRightButtonDown = pointer.Properties.IsRightButtonPressed;
            }

            NotifyGridStateChanged("PointerUp");
            base.OnPointerReleased(e);

        }

        public void CursorDefault()
        {
            if (ProtectedCursor != null)
                ProtectedCursor = null;
        }
        public void CursorResizeHorizontal()
        {
            ProtectedCursor = InputSystemCursor.Create(InputSystemCursorShape.SizeWestEast);
        }
        enum AreaType
        {
            Cell,
            Header,
            Index,
            None
        }

        private AreaType GetPoiterArea(PointerPoint p)
        {
            return GetPoiterArea(p.Position);
        }
        private AreaType GetPoiterArea(Point p)
        {
            if (p.Y < _HeaderHeight) return AreaType.Header;
            if (p.X < _IndexColWidth) return AreaType.Index;
            return AreaType.Cell;
        }
    }
}
