using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using DramaLing.Api.Models.DTOs; using DramaLing.Api.Services; using System.Diagnostics; namespace DramaLing.Api.Controllers; [ApiController] [Route("api/ai")] public class AIController : ControllerBase { private readonly IGeminiService _geminiService; private readonly ILogger _logger; public AIController( IGeminiService geminiService, ILogger logger) { _geminiService = geminiService; _logger = logger; } /// /// 智能分析英文句子 /// /// 分析請求 /// 分析結果 [HttpPost("analyze-sentence")] [AllowAnonymous] public async Task> AnalyzeSentence( [FromBody] SentenceAnalysisRequest request) { var requestId = Guid.NewGuid().ToString(); var stopwatch = Stopwatch.StartNew(); try { // For testing without auth - use dummy user ID var userId = "test-user-id"; _logger.LogInformation("Processing sentence analysis request {RequestId} for user {UserId}", requestId, userId); // Input validation if (!ModelState.IsValid) { return BadRequest(CreateErrorResponse("INVALID_INPUT", "輸入格式錯誤", ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList(), requestId)); } // 直接執行 AI 分析,不使用快取 var options = request.Options ?? new AnalysisOptions(); var analysisData = await _geminiService.AnalyzeSentenceAsync( request.InputText, request.UserLevel, options); stopwatch.Stop(); analysisData.Metadata.ProcessingDate = DateTime.UtcNow; _logger.LogInformation("Sentence analysis completed for request {RequestId} in {ElapsedMs}ms", requestId, stopwatch.ElapsedMilliseconds); return Ok(new SentenceAnalysisResponse { Success = true, ProcessingTime = stopwatch.Elapsed.TotalSeconds, Data = analysisData }); } catch (ArgumentException ex) { _logger.LogWarning(ex, "Invalid input for request {RequestId}", requestId); return BadRequest(CreateErrorResponse("INVALID_INPUT", ex.Message, null, requestId)); } catch (InvalidOperationException ex) { _logger.LogError(ex, "AI service error for request {RequestId}", requestId); return StatusCode(500, CreateErrorResponse("AI_SERVICE_ERROR", "AI服務暫時不可用", null, requestId)); } catch (Exception ex) { _logger.LogError(ex, "Unexpected error processing request {RequestId}", requestId); return StatusCode(500, CreateErrorResponse("INTERNAL_ERROR", "伺服器內部錯誤", null, requestId)); } } /// /// 健康檢查端點 /// [HttpGet("health")] [AllowAnonymous] public ActionResult GetHealth() { return Ok(new { Status = "Healthy", Service = "AI Analysis Service", Timestamp = DateTime.UtcNow, Version = "1.0" }); } private ApiErrorResponse CreateErrorResponse(string code, string message, object? details, string requestId) { var suggestions = GetSuggestionsForError(code); return new ApiErrorResponse { Success = false, Error = new ApiError { Code = code, Message = message, Details = details, Suggestions = suggestions }, RequestId = requestId, Timestamp = DateTime.UtcNow }; } private List GetSuggestionsForError(string errorCode) { return errorCode switch { "INVALID_INPUT" => new List { "請檢查輸入格式", "確保文本長度在限制內" }, "RATE_LIMIT_EXCEEDED" => new List { "升級到Premium帳戶以獲得無限使用", "明天重新嘗試" }, "AI_SERVICE_ERROR" => new List { "請稍後重試", "如果問題持續,請聯繫客服" }, _ => new List { "請稍後重試" } }; } }