using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.VisualBasic.FileIO;
using PCL.Core.App;
using SearchOption = System.IO.SearchOption;
using PCL.Core.App.Localization;
using PCL.Core.UI;

namespace PCL;

public partial class PageInstanceScreenshot : IRefreshable
{
    private bool _AppendLock;
    private int _Offset;

    private List<string> fileList = new();

    private bool isLoad;
    private string screenshotPath;

    public PageInstanceScreenshot()
    {
        InitializeComponent();
        Loaded += PageSetupLaunch_Loaded;
        PanBack.ScrollChanged += RequireAppend;
        BtnOpenFolder.Click += BtnOpenFolder_Click;
        BtnOpenFolderTop.Click += BtnOpenFolder_Click;
    }

    void IRefreshable.Refresh()
    {
        RefreshSelf();
    }

    private void RefreshSelf()
    {
        var ignore = RefreshAsync();
    }

    public static async Task RefreshAsync()
    {
        if (ModMain.frmInstanceScreenshot is not null)
            await ModMain.frmInstanceScreenshot.ReloadAsync();
        ModMain.frmInstanceLeft.ItemScreenshot.Checked = true;
        HintService.Hint(Lang.Text("Instance.Saves.Status.Refreshing"), log: false);
    }

    private void PageSetupLaunch_Loaded(object sender, RoutedEventArgs e)
    {
        // 重复加载部分
        PanBack.ScrollToHome();
        screenshotPath = PageInstanceLeft.McInstance.PathIndie + @"screenshots\";
        if (!Directory.Exists(screenshotPath))
            Directory.CreateDirectory(screenshotPath);
        Dispatcher.BeginInvoke(new Func<Task>(ReloadAsync));

        // 非重复加载部分
        if (isLoad)
            return;
        isLoad = true;
    }

    /// <summary>
    ///     确保当前页面上的信息已正确显示。
    /// </summary>
    public async Task ReloadAsync()
    {
        ModAnimation.AniControlEnabled += 1;
        PanBack.ScrollToHome();
        await LoadFileListAsync();
        ModAnimation.AniControlEnabled -= 1;
    }

    private void RefreshTip()
    {
        if (fileList.Count.Equals(0))
        {
            PanNoPic.Visibility = Visibility.Visible;
            PanContent.Visibility = Visibility.Collapsed;
        }
        else
        {
            PanNoPic.Visibility = Visibility.Collapsed;
            PanContent.Visibility = Visibility.Visible;
        }
    }
    
    private static string[] allowedSuffix = { "*.png", "*.jpg", "*.jpeg", "*.bmp", "*.webp", "*.tiff" };
    
    private async Task LoadFileListAsync()
    {
        ModBase.Log("[Screenshot] 刷新截图文件");
        fileList.Clear();
        if (Directory.Exists(screenshotPath))
        {
            fileList = allowedSuffix
                .SelectMany(suffix => Directory.EnumerateFiles(screenshotPath, suffix, SearchOption.TopDirectoryOnly))
                .OrderByDescending(f => File.GetCreationTime(f))
                .ToList();
        }
        PanList.Children.Clear();
        RefreshTip();
        //FileList = FileList.Where(e => !e.ContainsF(@"\debug\")).ToList(); // 排除资源包调试输出
        //FileList.Sort((a, b) => new FileInfo(a).CreationTime > new FileInfo(b).CreationTime);
        ModBase.Log("[Screenshot] 共发现 " + fileList.Count + " 个截图文件");
        if (fileList.Count == 0)
            return;
        await ListAppendAsync(20, 0);
    }

    private void RequireAppend(object sender, ScrollChangedEventArgs e)
    {
        if (fileList.Count != 0 && !_AppendLock && PanBack.VerticalOffset + PanBack.ViewportHeight >= PanBack.ExtentHeight)
        {
            Dispatcher.BeginInvoke(new Func<Task>(async () => await ListAppendAsync()));
        }
    }

    private async Task ListAppendAsync(int count = 20, int offset = -1)
    {
        _AppendLock = true;
        if (offset == -1)
        {
            if (_Offset * count > fileList.Count)
                return;
            offset = _Offset + 1;
            _Offset += 1;
        }
        else
        {
            _Offset = offset;
        }

        if (count * offset > fileList.Count)
            return;
        for (int j = count * offset, loopTo = count * (offset + 1) - 1; j <= loopTo; j++)
        {
            if (j >= fileList.Count)
                break;
            var i = fileList.ElementAt(j);
            try
            {
                if (!File.Exists(i))
                    continue; // 文件在加载途中消失了
                if (File.GetAttributes(i).HasFlag(FileAttributes.Hidden))
                    continue; // 隐藏文件
                if (new FileInfo(i).Length == 0L)
                    continue; // 空文件
                var myCard = new MyCard
                {
                    Margin = new Thickness(7),
                    Tag = i,
                    ToolTip = i.Replace(screenshotPath, "") // 适配高清截图模组
                };
                var grid = new Grid();
                myCard.Children.Add(grid);

                grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(9d) });
                grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(120d) });
                grid.RowDefinitions.Add(new RowDefinition());

                // 图片
                var image = new Image();
                image.Source = await Task.Run(() =>
                {
                    var bitmapImage = new BitmapImage();
                    var loadSource = i;
                    using (var fs = new FileStream(loadSource, FileMode.Open, FileAccess.Read))
                    {
                        bitmapImage.BeginInit();
                        bitmapImage.DecodePixelHeight = 200;
                        bitmapImage.DecodePixelWidth = 400;
                        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                        bitmapImage.StreamSource = fs;
                        bitmapImage.EndInit();
                        bitmapImage.Freeze();
                    }

                    return bitmapImage;
                });
                image.Stretch = Stretch.Uniform; // 使图片自适应控件大小
                image.Cursor = Cursors.Hand;
                image.MouseLeftButtonDown += (sender, e) =>
                {
                    try
                    {
                        Basics.OpenPath(i);
                    }
                    catch (Exception ex)
                    {
                        ModBase.Log(
                            ex,
                            Lang.Text("Instance.Screenshot.OpenFailed"),
                            ModBase.LogLevel.Hint,
                            userSummary: Lang.Text("Instance.Screenshot.OpenFailed"));
                    }
                }; // 使用系统默认程序打开
                Grid.SetRow(image, 1);
                grid.Children.Add(image);

                // 按钮
                var stackPanel = new StackPanel();
                stackPanel.Orientation = Orientation.Horizontal;
                stackPanel.HorizontalAlignment = HorizontalAlignment.Center;
                stackPanel.Margin = new Thickness(3d, 5d, 3d, 5d);
                Grid.SetRow(stackPanel, 2);
                grid.Children.Add(stackPanel);

                var btnOpen = new MyIconTextButton
                {
                    Name = "BtnOpen",
                    Text = Lang.Text("Common.Action.Open"),
                    LogoScale = 0.8d,
                    SvgIcon = "lucide/folder-open",
                    Tag = i
                };
                btnOpen.Click += (s, ev) => BtnOpen_Click((MyIconTextButton)s, ev);
                stackPanel.Children.Add(btnOpen);
                var btnDelete = new MyIconTextButton
                {
                    Name = "BtnDelete",
                    Text = Lang.Text("Common.Action.Delete"),
                    LogoScale = 0.8d,
                    SvgIcon = "lucide/trash-2",
                    Tag = i
                };
                btnDelete.Click += (s, ev) => BtnDelete_Click((MyIconTextButton)s, ev);
                stackPanel.Children.Add(btnDelete);
                var btnCopy = new MyIconTextButton
                {
                    Name = "BtnCopy",
                    Text = Lang.Text("Common.Action.Copy"),
                    LogoScale = 0.8d,
                    SvgIcon = "lucide/copy",
                    Tag = i
                };
                btnCopy.Click += (s, ev) => BtnCopy_Click((MyIconTextButton)s, ev);
                stackPanel.Children.Add(btnCopy);
                PanList.Children.Add(myCard);
                myCard.Opacity = 0d;
                ModAnimation.AniStart(new[] { ModAnimation.AaOpacity(myCard, 1d, 200) });
            }
            catch (Exception ex)
            {
                ModBase.Log(ex, $"[Screenshot] 创建 {i} 截图预览失败，图像可能损坏");
            }
        }

        _AppendLock = false;
    }

    private void RemoveItem(string path)
    {
        try
        {
            foreach (var i in PanList.Children)
                if (((MyCard)i).Tag.Equals(path))
                {
                    PanList.Children.Remove((UIElement)i);
                    break;
                }

            fileList.Remove(path);
        }
        catch (Exception ex)
        {
            ModBase.Log(ex, "未能找到对应 UI");
        }
    }

    private string GetPathFromSender(MyIconTextButton sender)
    {
        return (string)sender.Tag;
    }

    private void BtnOpen_Click(MyIconTextButton sender, EventArgs e)
    {
        ModBase.OpenExplorer(GetPathFromSender(sender));
    }

    private void BtnDelete_Click(MyIconTextButton sender, EventArgs e)
    {
        var path = GetPathFromSender(sender);
        try
        {
            FileSystem.DeleteFile(path, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            RemoveItem(path);
            RefreshTip();
            HintService.Hint(Lang.Text("Instance.Screenshot.Deleted"));
        }
        catch (Exception ex)
        {
            ModBase.Log(
                ex,
                Lang.Text("Instance.Screenshot.DeleteFailed"),
                ModBase.LogLevel.Hint,
                userSummary: Lang.Text("Instance.Screenshot.DeleteFailed"));
        }
    }

    private void BtnCopy_Click(MyIconTextButton sender, EventArgs e)
    {
        var imagePath = GetPathFromSender(sender);
        if (File.Exists(imagePath))
        {
            var tryTime = 0;
            while (tryTime <= 5)
                try
                {
                    ModBase.Log("[Screenshot] 尝试复制" + imagePath + "到剪贴板");
                    Clipboard.SetImage(new BitmapImage(new Uri(imagePath)));
                    HintService.Hint(Lang.Text("Instance.Screenshot.CopiedToClipboard"));
                    tryTime = 6;
                    return;
                }
                catch (Exception ex)
                {
                    tryTime += 1;
                    ModBase.Log(ex, $"[Screenshot]第 {tryTime} 次复制尝试失败");
                }

            HintService.Hint(Lang.Text("Instance.Screenshot.CopyFailed"), HintType.Error);
        }
        else
        {
            HintService.Hint(Lang.Text("Instance.Screenshot.FileNotFound"));
        }
    }

    private void BtnOpenFolder_Click(object sender, MouseButtonEventArgs e)
    {
        if (!Directory.Exists(screenshotPath))
            Directory.CreateDirectory(screenshotPath);
        ModBase.OpenExplorer(screenshotPath);
    }
}
