using PicView.Core.Config;
using PicView.WPF.ChangeTitlebar;
using PicView.WPF.Editing;
using PicView.WPF.PicGallery;
using PicView.WPF.UILogic.Sizing;
using PicView.WPF.UILogic.TransformImage;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using PicView.Core.FileHandling;
using static PicView.WPF.ChangeImage.Navigation;
using static PicView.WPF.SystemIntegration.NativeMethods;
using ArchiveHelper = PicView.Core.FileHandling.ArchiveHelper;

namespace PicView.WPF.UILogic.DragAndDrop;

internal static class DragToExplorer
{
    private static Window? _dragdropWindow;

    internal static void DragFile(object sender, MouseButtonEventArgs e)
    {
        if (ConfigureWindows.GetMainWindow.MainImage.Source == null
            || Keyboard.Modifiers is ModifierKeys.Shift or ModifierKeys.Alt
            || GalleryFunctions.IsGalleryOpen
            || SettingsHelper.Settings.WindowProperties.Fullscreen
            || Scroll.IsAutoScrolling
            || ZoomLogic.IsZoomed
            || UC.GetQuickResize is not null && UC.GetQuickResize.Opacity > 0
            || UC.UserControls_Open()
            || ConfigureWindows.MainContextMenu.IsVisible
            || ConfigureWindows.WindowContextMenu.IsVisible
            || ConfigureWindows.NavigationContextMenu.IsVisible
            || ColorPicking.IsRunning)
        {
            return;
        }

        if (ConfigureWindows.GetMainWindow.TitleText.IsFocused)
        {
            EditTitleBar.Refocus();
            return;
        }

        if (UC.GetCroppingTool is { IsVisible: true }) return;

        if (SettingsHelper.Settings.UIProperties.ShowInterface == false)
        {
            if (Keyboard.Modifiers != ModifierKeys.Control)
            {
                return;
            }
        }

        if (!ConfigureWindows.GetMainWindow.IsActive) return;

        string? file;
        if (Pics.Count == 0)
        {
            try
            {
                // Check if from URL and locate it
                var url = ConfigureWindows.GetMainWindow.TitleText.Text.GetURL();
                if (!string.IsNullOrEmpty(url))
                {
                    file = ArchiveHelper.TempFilePath;
                }
                else
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                Tooltip.ShowTooltipMessage(ex, true, TimeSpan.FromSeconds(5));
                return;
            }
        }
        else if (Pics.Count > FolderIndex)
            file = Pics[FolderIndex];
        else return;

        if (file == null) return;

        ConfigureWindows.GetMainWindow.Dispatcher.Invoke(() =>
        {
            if (_dragdropWindow == null)
            {
                CreateDragDropWindow(ConfigureWindows.GetMainWindow.MainImage);
            }
            else if (!_dragdropWindow.IsVisible)
            {
                _dragdropWindow.Show();
                UpdateDragDropWindow(ConfigureWindows.GetMainWindow.MainImage);
            }

            try
            {
                var senderElement = sender as FrameworkElement;
                var dragObj = new DataObject();
                dragObj.SetFileDropList(new StringCollection { file });
                if (senderElement is null) return;
                DragDrop.AddQueryContinueDragHandler(senderElement, DragContrinueHandler);
                DragDrop.DoDragDrop(senderElement, dragObj, DragDropEffects.Copy);
            }
            catch (Exception)
            {
                // A drag operation already occurred exception
            }
        });
    }

    private static void DragContrinueHandler(object sender, QueryContinueDragEventArgs e)
    {
        if (ColorPicking.IsRunning ||
            e.Action == DragAction.Continue && e.KeyStates != DragDropKeyStates.LeftMouseButton)
        {
            _dragdropWindow?.Hide();
            return;
        }

        var w32Mouse = new Win32Point();
        GetCursorPos(ref w32Mouse);

        _dragdropWindow.Left = w32Mouse.X + 10;
        _dragdropWindow.Top = w32Mouse.Y - 50;
    }

    private static void CreateDragDropWindow(Visual dragElement)
    {
        _dragdropWindow = new Window
        {
            WindowStyle = WindowStyle.None,
            AllowsTransparency = true,
            AllowDrop = false,
            Background = Brushes.Transparent,
            IsHitTestVisible = false,
            SizeToContent = SizeToContent.WidthAndHeight,
            Topmost = true,
            ShowInTaskbar = false,
            Opacity = .75,
        };

        UpdateDragDropWindow(dragElement);

        _dragdropWindow.Show();
    }

    private static void UpdateDragDropWindow(Visual dragElement)
    {
        var xWidth = ScaleImage.XWidth;
        var xHeight = ScaleImage.XHeight;

        var maxWidth = Math.Min(xWidth, xWidth / 1.8);
        var maxHeight = Math.Min(xHeight, xHeight / 1.8);
        var ratio = Math.Min(maxWidth / xHeight / 1.8, maxHeight / xWidth / 1.8);

        var r = new Rectangle
        {
            Width = maxWidth * ratio,
            Height = maxHeight * ratio,
            Fill = new VisualBrush(dragElement)
        };
        _dragdropWindow.Content = r;
    }
}