using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Platform.Storage;
using Avalonia.Threading;
using DialogHostAvalonia;
using Progrart.Controls.TabSystem;
using Progrart.Dialogs;
using Progrart.Icons;
using Progrart.Pages;
using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace Progrart.Controls;

public partial class FileItem : UserControl
{
	IStorageItem? currentItem;
	bool isOpen = false;
	string extension = "";
	FileItem? root = null;
	bool isSelectOnly = false;
	public IStorageItem? CurrentItem => currentItem;
	public Action<FileItem>? onSelected = null;
	public FileItem()
	{
		InitializeComponent();
	}
	public FileItem(IStorageItem storageItem, FileItem? RootItem, bool SelectOnly = false)
	{
		InitializeComponent();
		this.root = RootItem;
		isSelectOnly = SelectOnly;
		if (isSelectOnly)
		{
			MainButton.ContextMenu = null;
		}
		currentItem = storageItem;
		if (storageItem is IStorageFolder folder)
		{
			FolderIcon.IsVisible = true;
			GenericFileIcon.IsVisible = false;
			IconContainer.IsVisible = false;
			OpenWithMenu.IsVisible = false;
		}
		else if (storageItem is IStorageFile file)
		{
			NewFiles.IsVisible = false;
			FolderIcon.IsVisible = false;
			GenericFileIcon.IsVisible = true;
			IconContainer.Children.Clear();
			var dotIndex = file.Name.LastIndexOf('.');
			if (dotIndex >= 0)
			{
				extension = file.Name[(dotIndex + 1)..];
				if (IconProvider.TryGetIcon(extension, out var icon))
				{
					GenericFileIcon.IsVisible = false;
					IconContainer.Children.Add(icon);
				}
				foreach (var item in EditorProvider.GetHandlerCollection(extension))
				{
					MenuItem mItem = new() { Header = item.Name };
					mItem.Click += async (a, b) =>
					{
						if (item.OpenAction is not null)
							await item.OpenAction(file);
					};
					OpenWithMenu.Items.Add(mItem);
				}
			}
			IconContainer.IsVisible = true;
		}
		NameBlock.Text = storageItem.Name;
		if (isSelectOnly)
			MainButton.Click += (a, b) =>
			{
				(root ?? this).SelectFileItem(this);
			};
		MainButton.DoubleTapped += async (_, _) =>
		{
			await OpenItem();
		};
		OpenFileMenuItem.Click += async (a, b) =>
		{
			await OpenItem();
		};
		CreateFolderItem.Click += async (a, b) =>
		{
			InputDialog content = new();
			content.SetDialogContent("Create New Folder", "Specify a name that is legal for your filesystem.");
			content.onOK = async (v) =>
			{
				if (currentItem is IStorageFolder folder)
				{
					try
					{
						var fldr = await folder.CreateFolderAsync(v);
						if (fldr is not null)
						{
							if (isOpen)
								Dispatcher.UIThread.Invoke(() =>
								{
									var fitem = new FileItem(fldr, root ?? this, SelectOnly);
									ItemContainer.Children.Add(fitem);
								});
						}
						else
						{
							content.SetErrorMessage($"{v} is not a valid name for target filesystem.");
							return true;
						}
					}
					catch (System.Exception e)
					{
						content.SetErrorMessage($"{v} is not a valid name for target filesystem.\nMsg:{e.Message}");
						return true;
					}
				}
				return false;
			};
			await DialogHost.Show(content);
		};
		CopyToMenuItem.Click += CopyToMenuItem_Click;
		MoveToMenuItem.Click += MoveToMenuItem_Click;
		CreateProgrartItem.Click += async (a, b) =>
		{
			InputDialog content = new();
			content.SetDialogContent("Create A PROGRART Image", "Specify a name that is legal for your filesystem.");
			content.onOK = async (v) =>
			{
				if (currentItem is IStorageFolder folder)
				{
					try
					{
						var fldr = await folder.CreateFileAsync($"{v}.progrart");
						if (fldr is not null)
						{
							if (isOpen)
								Dispatcher.UIThread.Invoke(() =>
								{
									var fitem = new FileItem(fldr, root ?? this, SelectOnly);
									ItemContainer.Children.Add(fitem);
								});
						}
						else
						{
							content.SetErrorMessage($"{v} is not a valid name for target filesystem.");
							return true;
						}
					}
					catch (System.Exception e)
					{
						content.SetErrorMessage($"{v} is not a valid name for target filesystem.\nMsg:{e.Message}");
						return true;
					}
				}
				return false;
			};
			await DialogHost.Show(content);
		};
	}

	private async void MoveToMenuItem_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
	{
		var content = new BrowserDialog();
		content.onOK = async (si) =>
		{
			if (si is IStorageFolder destFolder)
			{

				if (currentItem is not null)
				{
					await currentItem.MoveAsync(destFolder);
				}
			}
			return false;
		};
		if ((root ?? this).CurrentItem is IStorageItem item)
			content.SetFileITem(new FileItem(item, null, true));
		await DialogHost.Show(content);
	}

	private async void CopyToMenuItem_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
	{
		var content = new BrowserDialog();
		content.onOK = async (si) =>
		{
			if (currentItem is IStorageFolder folder)
			{
			}
			else if (currentItem is IStorageFile file)
			{
			}
			return false;
		};
		if ((root ?? this).CurrentItem is IStorageItem item)
			content.SetFileITem(new FileItem(item, null, true));
		await DialogHost.Show(content);
	}

	public async Task OpenItem()
	{

		if (currentItem is IStorageFolder folder)
		{
			if (isOpen)
			{
				RemoveAll();
				isOpen = false;
			}
			else
			{
				isOpen = true;
				await Task.Run(async () =>
				{
					await LoadAll(folder);
				});
			}
		}
		else
			if (currentItem is IStorageFile file)
			{
				var btn = EditorProvider.IsOpen(file);
				if (btn is not null)
				{
					EditorProvider.SelectTabPage(btn);
				}
				else
					if (EditorProvider.TryGetHandler(extension, out var page))
					{
						if (page.OpenAction is not null)
							await page.OpenAction(file);
						//if (page is ITabPage editor)
						//{
						//	try
						//	{
						//		if (page is IEditorPage editor_page)
						//		{
						//			editor_page.LoadDocument(file);
						//		}
						//		EditorProvider.OpenEditor(editor);
						//	}
						//	catch (System.Exception e)
						//	{
						//		Trace.WriteLine(e);
						//	}
						//}
					}
			}
	}
	async Task LoadAll(IStorageFolder folder)
	{
		await foreach (var item in folder.GetItemsAsync())
		{
			if (isSelectOnly)
			{
				if (item is IStorageFile)
					continue;
			}
			Dispatcher.UIThread.Invoke(() =>
			{
				var fitem = new FileItem(item, root ?? this, isSelectOnly);
				ItemContainer.Children.Add(fitem);
			});
		}
	}
	void RemoveAll()
	{
		ItemContainer.Children.Clear();
	}
	public void SelectFileItem(FileItem item)
	{
		if (root == null) onSelected?.Invoke(item);
		SelectIndicator.IsVisible = this == item;
		foreach (var citem in ItemContainer.Children)
		{
			if (citem is FileItem fi)
			{
				fi.SelectFileItem(item);
			}
		}
	}

	private async void DeleteMenuItem_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
	{
		var content = new ConfirmationDialog("Are you sure?", "This operation cannot be undone.");
		content.onOK = async () =>
		{
			if (currentItem is not null)
				await currentItem.DeleteAsync();
			if (this.Parent is StackPanel panel)
			{
				panel.Children.Remove(this);
			}
			return false;
		};
		await DialogHost.Show(content);
	}
}