using Blazorise;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.JSInterop;
using Seenginx.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Seenginx.Components
{
	public partial class FilesWithEditor<CFile> : ComponentBase
		where CFile : ConfigFile
	{
		[Inject]
		public IJSRuntime JsRuntime { get; set; }

		[Parameter]
		public List<CFile> Files { get; set; } = new List<CFile>();

		[Parameter]
		public List<string> Filters { get; set; } = new List<string>();
		[Parameter]
		public Dictionary<string, string> FilterFolder { get; set; } = new Dictionary<string, string>();

		[Parameter]
		public EventCallback<CFile> UpdateFile { get; set; }

		[Parameter]
		public RenderFragment<CFile> Editor { get; set; } = null;

		protected string SelectedFilter { get; set; }
		protected string SearchInput { get; set; }

		protected bool IsAnyFileSelected => SelectedFile != default;
		protected string IsSelectedFileDeletable
		{
			get
			{
				if (SelectedFile != null && SelectedFile.CanBeDeleted)
					return string.Empty;
				else
					return "is-hidden";
			}
		}

		[Parameter]
		public EventCallback<CFile> SelectedFileChanged { get; set; }
		[Parameter]
		public CFile SelectedFile { get; set; } = default;


		protected async override Task OnInitializedAsync()
		{
			SelectedFilter = Filters.First();
			await base.OnInitializedAsync();
		}

		protected async override Task OnAfterRenderAsync(bool firstRender)
		{
			await JsRuntime.InvokeVoidAsync("InitEditor");
			await base.OnAfterRenderAsync(firstRender);
		}

		protected async Task OnFilterClick(string filter)
		{
			SelectedFilter = filter;
			SearchFile();
		}

		protected async Task SearchInputChanged(string searchInput)
		{
			SearchInput = searchInput;
			SearchFile();
		}

		private void SearchFile()
		{
			if (string.IsNullOrEmpty(SearchInput))
			{
				if (SelectedFilter == "All")
					Files.ForEach(f => f.Unhide());
				else if (SelectedFilter == "Root")
					Files.ForEach(f =>
					{
						if (f.Folder == FilterFolder[SelectedFilter])
							f.Unhide();
						else
							f.Hide();
					});
				else
					Files.ForEach(f =>
					{
						if (f.Folder.Contains(FilterFolder[SelectedFilter]))
							f.Unhide();
						else
							f.Hide();
					});
			}
			else
			{
				if (SelectedFilter == "All")
					Files.ForEach(f => { if (f.Name.ToLower().Contains(SearchInput)) f.Unhide(); else f.Hide(); });
				else
					Files.ForEach(f =>
					{
						if (SelectedFilter == "Root")
						{
							if (f.Folder == FilterFolder[SelectedFilter] && f.Folder.ToLower().Contains(SearchInput.ToLower()))
								f.Unhide();
							else
								f.Hide();
						}
						else
						{
							Files.ForEach(f =>
							{
								if (f.Folder.Contains(FilterFolder[SelectedFilter]) && f.Folder.ToLower().Contains(SearchInput.ToLower()))
									f.Unhide();
								else
									f.Hide();
							});
						}
					});
			}
		}

		protected async Task OnFileClick(MouseEventArgs e, CFile file)
		{
			Files.ForEach(f => f.Deselect());
			file.Select();
			await JsRuntime.InvokeVoidAsync("UpdateEditor", file.Body);
			await SelectedFileChanged.InvokeAsync(file);
		}

		protected async Task OnFileCloseClick(MouseEventArgs e)
		{
			Files.ForEach(f => f.Deselect());
			SelectedFile = null;
			await JsRuntime.InvokeVoidAsync("ClearEditor");
		}

		protected async Task OnSaveDraft(MouseEventArgs e)
		{
			var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode");
			SelectedFile.DraftBody = draftCode;
		}
		protected async Task OnUndoChanges(MouseEventArgs e)
		{
			SelectedFile.DraftBody = SelectedFile.Body;
			await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.Body);
		}
		protected async Task OnSave(MouseEventArgs e)
		{
			var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode");
			SelectedFile.Body = draftCode;
		}

		[Parameter]
		public EventCallback TestConfiguration { get; set; }
		[Parameter]
		public Result<string> TestResult { get; set; }
		protected async Task OnTest(MouseEventArgs e)
		{
			await TestConfiguration.InvokeAsync(null);
		}

		[Parameter]
		public EventCallback AddFileModal { get; set; }
		[Parameter]
		public Result<ConfigFile> AddResult { get; set; }
		protected async Task OnAddDialog()
		{
			await AddFileModal.InvokeAsync(null);
		}

		[Parameter]
		public EventCallback DeleteFileModal { get; set; }
		[Parameter]
		public Result<bool> DeleteResult { get; set; }
		protected async Task OnDeleteDialog(MouseEventArgs eventArgs)
		{
			await DeleteFileModal.InvokeAsync(eventArgs);
		}


	}
}
