using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Logging;
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; }
		[Inject] public ILogger<FilesWithEditor<CFile>> logger { get; set; }

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

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

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

		[Parameter] public bool HasTesting { get; set; } = false;
		[Parameter] public EventCallback TestConfiguration { get; set; }
		[Parameter] public EventCallback ShowAddFileModal { get; set; }
		[Parameter] public EventCallback DeleteFileCallback { get; set; }
		[Parameter] public EventCallback RenameFileCallback { get; set; }
		[Parameter] public EventCallback SaveFileCallback { get; set; }
		[Parameter] public EventCallback SaveDraftFileCallback { get; set; }
		[Parameter] public EventCallback<CFile> SelectedFileChanged { get; set; }
		[Parameter] public CFile SelectedFile { get; set; } = default;

		protected string SearchInput { get; set; }
		protected string DraftMode { get; set; } = "off";
		protected bool IsDraftMode { get; set; } = false;


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

		protected async override Task OnAfterRenderAsync(bool firstRender)
		{
			try
			{
				await JsRuntime.InvokeVoidAsync("InitEditor");
				await base.OnAfterRenderAsync(firstRender);
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

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

		private void SearchFile()
		{
			Files.ForEach(f =>
			{
				if (f.Name.ToLower().Contains(SearchInput.ToLower()))
					f.Unhide();
				else
					f.Hide();
			});
		}

		protected async Task OnDraftModeSwitch(ChangeEventArgs e)
		{
			IsDraftMode = (bool)e.Value;
			DraftMode = IsDraftMode ? "on" : "off";
			if (IsDraftMode)
				await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.DraftBody ?? SelectedFile.Body);
			else 
				await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.Body);
		}

		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);
			IsDraftMode = false;
		}

		protected async Task OnFileRenameClick(MouseEventArgs e)
		{
			await RenameFileCallback.InvokeAsync(null);
		}

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

		protected async Task OnSaveDraft(MouseEventArgs e)
		{
			var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode");
			SelectedFile.DraftBody = draftCode;
			await SaveDraftFileCallback.InvokeAsync(null);
		}

		protected async Task OnSave(MouseEventArgs e)
		{
			var currentCode = await JsRuntime.InvokeAsync<string>("GetEditorCode");
			SelectedFile.Body = currentCode;
			await SaveFileCallback.InvokeAsync(null);
		}

		protected async Task OnUndoChanges(MouseEventArgs e)
		{
			if (IsDraftMode)
				await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.DraftBody ?? SelectedFile.Body);
			else
				await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.Body);
		}

		protected async Task OnTest(MouseEventArgs e)
		{
			await TestConfiguration.InvokeAsync(null);
		}

		public async Task OnAddDialog()
		{
			await ShowAddFileModal.InvokeAsync(null);
			await JsRuntime.InvokeVoidAsync("ClearEditor");
			if (SelectedFile != null)
			{
				await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.Body);
				SearchInput = string.Empty;
				SearchFile();
			}
		}

		protected async Task OnDeleteDialog()
		{
			await DeleteFileCallback.InvokeAsync(null);
			await JsRuntime.InvokeVoidAsync("ClearEditor");
			SearchInput = string.Empty;
			SearchFile();
		}


	}
}
