using Blazored.TextEditor;
using Entities.Contracts;
using Entities.DTO;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MudBlazor;
using System.Text.RegularExpressions;
using TechHelper.Client.AI;
using TechHelper.Client.Exam;
using TechHelper.Services;
using static Org.BouncyCastle.Crypto.Engines.SM2Engine;

namespace TechHelper.Client.Pages.Editor
{
	public enum ProcessingStage
	{
		Idle,               // 初始或完成状态
		FetchingContent,    // 正在获取编辑器内容
		DividingExam,       // 正在分割题组 (AI返回原始XML)
		ConvertingDividedXml, // 正在将分割XML转换为StringsList
		ParsingGroups,      // 正在解析单个题组 (AI返回原始XML)
		ConvertingParsedXmls, // 正在将解析后的XML转换为QuestionGroup对象
		Completed,          // 所有处理完成
		ErrorOccurred,       // 发生错误
		Saving
	}

	public partial class EditorMain
	{
		[Inject]
		public IExamService ExamService { get; set; } = default!;
		[Inject]
		public ISnackbar Snackbar { get; set; } = default!;

		// --- UI 绑定和状态变量 ---
		private BlazoredTextEditor? _quillHtmlEditor; // 富文本编辑器实例
		private string _editorHtmlContent = string.Empty; // 存储编辑器获取到的 HTML/文本内容
		private bool _isProcessing = false; // 控制加载状态的标志
		private string _processingStatusMessage = "等待操作..."; // 显示给用户的当前处理状态信息

		// --- 内部数据结构 (存储每一步的结果，包括原始文本) ---
		// 1. AI 分割原始响应 (XML 文本)
		private string? _rawDividedExamXmlContent;
		// 2. 将 _rawDividedExamXmlContent 转换后的 StringsList
		private StringsList? _dividedQuestionGroupList;

		// 3. AI 解析每个题组后的原始响应 (XML 文本列表)
		private List<string> _rawParsedQuestionXmls = new();
		// 4. 将 _rawParsedQuestionXmls 转换后的 QuestionGroup 对象列表
		private List<QuestionGroup> _finalQuestionGroups = new();


		// --- Blazor 生命周期方法 ---
		protected override void OnInitialized()
		{
			_processingStatusMessage = ProcessingStage.Idle.ToString();
		}

		// --- 辅助方法 ---

		// 统一处理错误并更新 UI
		private void HandleProcessError(string errorMessage, Exception? ex = null)
		{
			_processingStatusMessage = $"{ProcessingStage.ErrorOccurred}: {errorMessage}";
			Snackbar.Add(errorMessage, Severity.Error);
			_isProcessing = false;
			StateHasChanged();
			if (ex != null)
			{
				// 记录更详细的错误日志到控制台或日志系统
				Console.Error.WriteLine($"错误详情: {ex.Message}\n{ex.StackTrace}\n内部异常: {ex.InnerException?.Message}");
			}
		}

		// 更新处理状态和 UI
		private void UpdateProcessingStatus(ProcessingStage stage, string message)
		{
			_processingStatusMessage = $"{stage}: {message}";
			Snackbar.Add(message, Severity.Info);
			StateHasChanged();
		}

		// --- 公共工具方法 (可手动触发，用于获取编辑器内容) ---

		// 获取编辑器 HTML 内容
		public async Task GetEditorHtmlContentAsync()
		{
			if (_isProcessing) return;
			_isProcessing = true;
			UpdateProcessingStatus(ProcessingStage.FetchingContent, "正在获取编辑器HTML内容...");

			try
			{
				if (_quillHtmlEditor != null)
				{
					_editorHtmlContent = await _quillHtmlEditor.GetHTML();
					UpdateProcessingStatus(ProcessingStage.FetchingContent, "编辑器HTML内容已成功获取。");
				}
				else
				{
					HandleProcessError("编辑器实例未准备好，无法获取内容。");
				}
			}
			catch (Exception ex)
			{
				HandleProcessError($"获取编辑器内容时发生错误: {ex.Message}", ex);
			}
			finally
			{
				_isProcessing = false;
				StateHasChanged();
			}
		}

		// 获取编辑器纯文本内容 (根据需求决定是否保留)
		public async Task GetEditorTextContentAsync()
		{
			if (_isProcessing) return;
			_isProcessing = true;
			UpdateProcessingStatus(ProcessingStage.FetchingContent, "正在获取编辑器纯文本内容...");

			try
			{
				if (_quillHtmlEditor != null)
				{
					_editorHtmlContent = await _quillHtmlEditor.GetText();
					UpdateProcessingStatus(ProcessingStage.FetchingContent, "编辑器纯文本内容已成功获取。");
				}
				else
				{
					HandleProcessError("编辑器实例未准备好，无法获取内容。");
				}
			}
			catch (Exception ex)
			{
				HandleProcessError($"获取编辑器纯文本内容时发生错误: {ex.Message}", ex);
			}
			finally
			{
				_isProcessing = false;
				StateHasChanged();
			}
		}


		// --- 核心业务逻辑步骤 (每个步骤都可手动触发) ---

		// 步骤 1: 调用 AI 服务分割题组 (只获取原始 XML 文本)
		public async Task DivideExamContentByAIAsync()
		{
			if (_isProcessing) return;
			_isProcessing = true;
			// 清空所有依赖于此步骤的结果
			_rawDividedExamXmlContent = null;
			_dividedQuestionGroupList = null;
			_rawParsedQuestionXmls.Clear();
			_finalQuestionGroups.Clear();

			UpdateProcessingStatus(ProcessingStage.DividingExam, "正在请求 AI 分割题组，请等待...");

			if (string.IsNullOrWhiteSpace(_editorHtmlContent))
			{
				HandleProcessError("编辑器内容为空，请先获取内容。");
				return;
			}

			try
			{
				var response = await ExamService.DividExam(_editorHtmlContent);
				if (!response.Status)
				{
					HandleProcessError(response.Message ?? "AI题组分割失败。", response.Result as Exception);
					return;
				}

				// **仅保存原始的 XML 文本，不在此步进行转换**
				_rawDividedExamXmlContent = response.Result as string;

				if (string.IsNullOrWhiteSpace(_rawDividedExamXmlContent))
				{
					HandleProcessError("AI 服务返回的分割内容为空。");
					return;
				}
				UpdateProcessingStatus(ProcessingStage.DividingExam, response.Message ?? "AI题组分割成功，原始XML已保存。");
			}
			catch (Exception ex)
			{
				HandleProcessError($"分割题组时发生错误: {ex.Message}", ex);
			}
			finally
			{
				_isProcessing = false;
				StateHasChanged();
			}
		}

		// 步骤 2: 将原始分割 XML 文本转换为 StringsList
		public void ConvertDividedXmlToQuestionList()
		{
			if (_isProcessing) return; // 这是一个同步方法，但为了UI禁用按钮，仍检查
			_isProcessing = true;
			_dividedQuestionGroupList = null; // 清空上次结果
			_rawParsedQuestionXmls.Clear();
			_finalQuestionGroups.Clear();

			UpdateProcessingStatus(ProcessingStage.ConvertingDividedXml, "正在将分割XML转换为题组列表...");

			if (string.IsNullOrWhiteSpace(_rawDividedExamXmlContent))
			{
				HandleProcessError("没有原始分割XML文本可供转换。请先执行 '分割题组 (AI)' 步骤。");
				return;
			}

			try
			{
				// 调用 ExamService 的同步方法进行转换
				var xmlConversionResponse = ExamService.ConvertToXML<StringsList>(_rawDividedExamXmlContent);

				if (!xmlConversionResponse.Status)
				{
					// 如果从原始XML转换为StringsList失败，但原始XML仍然保留
					HandleProcessError(xmlConversionResponse.Message ?? "AI返回的XML无法转换为题组列表。", xmlConversionResponse.Result as Exception);
					return;
				}

				_dividedQuestionGroupList = xmlConversionResponse.Result as StringsList;
				if (_dividedQuestionGroupList == null || !_dividedQuestionGroupList.Items.Any())
				{
					HandleProcessError("AI 服务返回的XML已转换，但题组列表为空。");
					return;
				}
				UpdateProcessingStatus(ProcessingStage.ConvertingDividedXml, "分割XML已成功转换为题组列表。");
			}
			catch (Exception ex)
			{
				HandleProcessError($"转换分割XML到列表时发生错误: {ex.Message}", ex);
			}
			finally
			{
				_isProcessing = false;
				StateHasChanged();
			}
		}


		// 步骤 3: 循环调用 AI 服务解析每个分割后的题组 (只获取原始 XML 文本)
		public async Task ParseEachQuestionGroupAsync()
		{
			if (_isProcessing) return;
			_isProcessing = true;
			_rawParsedQuestionXmls.Clear(); // 清空上次结果
			_finalQuestionGroups.Clear();

			UpdateProcessingStatus(ProcessingStage.ParsingGroups, "正在解析每个题组，请等待...");

			if (_dividedQuestionGroupList == null || !_dividedQuestionGroupList.Items.Any())
			{
				HandleProcessError("没有可解析的题组列表。请先执行 '转换为题组列表' 步骤。");
				return;
			}

			try
			{
				int currentGroupIndex = 1;
				foreach (var itemXml in _dividedQuestionGroupList.Items)
				{
					UpdateProcessingStatus(ProcessingStage.ParsingGroups, $"正在解析第 {currentGroupIndex} 个题组...");

					var parseResponse = await ExamService.ParseSingleQuestionGroup(itemXml);
					if (!parseResponse.Status)
					{
						// 即使解析失败，原始的 _dividedQuestionGroupList 仍然保留
						HandleProcessError($"解析第 {currentGroupIndex} 个题组失败: {parseResponse.Message}", parseResponse.Result as Exception);
						// 可以选择跳过当前失败的项并继续，这里选择停止
						return;
					}
					// **仅保存原始的 XML 文本，不在此步进行转换**
					_rawParsedQuestionXmls.Add(parseResponse.Result as string ?? string.Empty);
					UpdateProcessingStatus(ProcessingStage.ParsingGroups, $"第 {currentGroupIndex} 个题组解析成功。");
					currentGroupIndex++;
				}
				UpdateProcessingStatus(ProcessingStage.ParsingGroups, "所有题组已成功解析。原始XML已保存。");
			}
			catch (Exception ex)
			{
				HandleProcessError($"解析题组时发生错误: {ex.Message}", ex);
			}
			finally
			{
				_isProcessing = false;
				StateHasChanged();
			}
		}

		// 步骤 4: 将原始解析 XML 文本转换为 QuestionGroup 对象
		public void ConvertParsedXmlsToQuestionGroups()
		{
			if (_isProcessing) return; // 这是一个同步方法
			_isProcessing = true;
			_finalQuestionGroups.Clear(); // 清空上次结果

			UpdateProcessingStatus(ProcessingStage.ConvertingParsedXmls, "正在将解析后的XML转换为对象，请等待...");

			if (!_rawParsedQuestionXmls.Any())
			{
				HandleProcessError("没有可转换的原始解析XML数据。请先执行 '解析每个题组 (AI)' 步骤。");
				return;
			}

			try
			{
				foreach (var xmlString in _rawParsedQuestionXmls)
				{
					// 调用 ExamService 的同步方法进行转换
					ApiResponse xmlConversionResponse = ExamService.ConvertToXML<QuestionGroup>(xmlString);

					if (!xmlConversionResponse.Status)
					{
						// 如果单个转换失败，但原始XML仍然保留
						HandleProcessError($"XML 转换为 QuestionGroup 失败: {xmlConversionResponse.Message}", xmlConversionResponse.Result as Exception);
						// 可以选择跳过当前失败的项并继续，这里选择停止
						return;
					}

					QuestionGroup? questionGroup = xmlConversionResponse.Result as QuestionGroup;
					if (questionGroup != null)
					{
						_finalQuestionGroups.Add(questionGroup);
					}
					else
					{
						// 即使 Status 为 true，Result 也可能不是预期的类型
						HandleProcessError("XML 转换成功，但返回结果类型不匹配 QuestionGroup。");
						return;
					}
				}
				UpdateProcessingStatus(ProcessingStage.ConvertingParsedXmls, "所有题组的XML已成功转换为对象。");
			}
			catch (Exception ex)
			{
				HandleProcessError($"转换解析XML到对象时发生错误: {ex.Message}", ex);
			}
			finally
			{
				if (_finalQuestionGroups.Count > 0)
					OrderQuestionGroup(_finalQuestionGroups);
				_isProcessing = false;
				StateHasChanged();
			}
		}



		private void OrderQuestionGroup(List<QuestionGroup> QG)
		{
			int index = 1;
			QG.ForEach(qg =>
			{
				qg.Id = (byte)index++;
				int sqIndex = 1;
				qg.SubQuestions.ForEach(sq => sq.SubId = (byte)sqIndex++);

			});

			QG.ForEach(qg => OrderQuestionGroup(qg.SubQuestionGroups));
		}

		private ExamDto MapToCreateExamDto(List<QuestionGroup> questionGroups)
		{
			var createDto = new ExamDto();
			createDto.QuestionGroups = MapQuestionGroupsToDto(questionGroups);
			// 如果您需要为这次保存指定一个AssignmentId，可以在这里设置
			// createDto.AssignmentId = YourCurrentAssignmentId;
			return createDto;
		}

		private List<QuestionGroupDto> MapQuestionGroupsToDto(List<QuestionGroup> qgs)
		{
			var dtos = new List<QuestionGroupDto>();
			foreach (var qg in qgs)
			{
				var qgDto = new QuestionGroupDto
				{
					Title = qg.Title,
					Score = qg.Score,
					QuestionReference = qg.QuestionReference,
					SubQuestions = MapSubQuestionsToDto(qg.SubQuestions),
					SubQuestionGroups = MapQuestionGroupsToDto(qg.SubQuestionGroups)
				};
				dtos.Add(qgDto);
			}
			return dtos;
		}

		private List<SubQuestionDto> MapSubQuestionsToDto(List<SubQuestion> sqs)
		{
			var dtos = new List<SubQuestionDto>();
			foreach (var sq in sqs)
			{
				var sqDto = new SubQuestionDto
				{
					Index = sq.SubId,
					Stem = sq.Stem,
					Score = sq.Score,
					SampleAnswer = sq.SampleAnswer,
					Options = sq.Options.Select(o => new OptionDto { Value = o.Value }).ToList(),
					// TODO: 假设这些值能从AI结果或某个默认配置中获取
					// 例如：QuestionType = "SingleChoice",
					// DifficultyLevel = "Medium",
					// SubjectArea = "Math"
				};
				dtos.Add(sqDto);
			}
			return dtos;
		}

		public async Task Save()
		{
			if (_isProcessing) return;
			_isProcessing = true;
			UpdateProcessingStatus(ProcessingStage.Saving, "正在准备发送试题数据到服务器...");

			if (!_finalQuestionGroups.Any())
			{
				HandleProcessError("没有可保存的最终题组数据。请先完成前面的所有解析步骤。");
				return;
			}

			try
			{
				// 确保 _finalQuestionGroups 已经按照 Index 排序 (这在之前的 ConvertParsedXmlsToQuestionGroups 之后或 Save 开始时完成)
				_finalQuestionGroups = _finalQuestionGroups.OrderBy(qg => qg.Id).ToList();

				// 映射到 DTO
				var createExamDto = MapToCreateExamDto(_finalQuestionGroups);

				// 调用 ExamService 发送 DTO
				// 假设 ExamService 有一个方法来接收这个 DTO
				var response = await ExamService.SaveParsedExam(createExamDto);

				if (!response.Status)
				{
					HandleProcessError(response.Message ?? "保存试题到服务器失败。", response.Result as Exception);
					return;
				}

				UpdateProcessingStatus(ProcessingStage.Saving, response.Message ?? "试题数据已成功保存到服务器。");
				Snackbar.Add("试题数据已成功保存。", Severity.Success);
			}
			catch (Exception ex)
			{
				HandleProcessError($"发送数据到服务器时发生错误: {ex.Message}", ex);
			}
			finally
			{
				_isProcessing = false;
				StateHasChanged();
			}
		}



		// --- 全自动流程 ---

		// 触发 AI 题组解析的完整流程 (全自动)
		public async Task TriggerFullAIParsingProcessAsync()
		{
			if (_isProcessing) return;
			_isProcessing = true; // 开始加载状态
								  // 全局清空所有结果
			_rawDividedExamXmlContent = null;
			_dividedQuestionGroupList = null;
			_rawParsedQuestionXmls.Clear();
			_finalQuestionGroups.Clear();

			UpdateProcessingStatus(ProcessingStage.Idle, "开始全自动解析流程...");

			try
			{
				// 1. 获取编辑器内容
				await GetEditorTextContentAsync();
				if (_processingStatusMessage.Contains(ProcessingStage.ErrorOccurred.ToString())) return;

				// 2. 调用 AI 分割题组 (获取原始 XML)
				await DivideExamContentByAIAsync();
				if (_processingStatusMessage.Contains(ProcessingStage.ErrorOccurred.ToString())) return;

				// 3. 转换分割 XML 为 StringsList
				ConvertDividedXmlToQuestionList(); // 注意这里是同步调用
				if (_processingStatusMessage.Contains(ProcessingStage.ErrorOccurred.ToString())) return;

				// 4. 循环解析每个题组 (获取原始 XML)
				await ParseEachQuestionGroupAsync();
				if (_processingStatusMessage.Contains(ProcessingStage.ErrorOccurred.ToString())) return;

				// 5. 转换解析 XML 为 QuestionGroup 对象
				ConvertParsedXmlsToQuestionGroups(); // 注意这里是同步调用
				if (_processingStatusMessage.Contains(ProcessingStage.ErrorOccurred.ToString())) return;

				UpdateProcessingStatus(ProcessingStage.Completed, "全自动题组解析流程已全部完成！");
			}
			catch (Exception ex)
			{
				HandleProcessError($"全自动解析流程中发生未预期错误: {ex.Message}", ex);
			}
			finally
			{
				_isProcessing = false; // 结束加载状态
				StateHasChanged();
			}
		}



		private void DeleteFromParse(int index)
		{
			if (index >= 0 && index < _finalQuestionGroups.Count)
			{
				_finalQuestionGroups.RemoveAt(index);
				StateHasChanged();
			}
		}


		#region JS
		[Inject]
		public IJSRuntime JSRuntime { get; set; }

		private IJSObjectReference jSObjectReference { get; set; }
		protected override async Task OnInitializedAsync()
		{
			jSObjectReference = await JSRuntime.InvokeAsync<IJSObjectReference>("import",
				"./scripts/jsTools.js");
		}

		private async Task CopyToClipboard()
		{
			try
			{
				// 调用 JavaScript 函数
				bool success = await jSObjectReference.InvokeAsync<bool>("copyTextToClipboard", AIConfiguration.ParseSignelQuestion2);

				if (success)
				{
					Snackbar.Add("文本已成功复制到剪贴板！");
				}
				else
				{
					Snackbar.Add("复制文本到剪贴板失败。");
				}
			}
			catch (Exception ex)
			{
				Snackbar.Add($"发生错误: {ex.Message}");
				Console.WriteLine($"复制到剪贴板时出错: {ex.Message}");
			}
		}
		#endregion

	}
}