using Microsoft.AspNetCore.Mvc; using DramaLing.Api.Models.Entities; using DramaLing.Api.Repositories; using Microsoft.AspNetCore.Authorization; namespace DramaLing.Api.Controllers; [ApiController] [Route("api/flashcards")] [AllowAnonymous] public class FlashcardsController : ControllerBase { private readonly IFlashcardRepository _flashcardRepository; private readonly ILogger _logger; public FlashcardsController( IFlashcardRepository flashcardRepository, ILogger logger) { _flashcardRepository = flashcardRepository; _logger = logger; } private Guid GetUserId() { // 暫時使用固定測試用戶 ID return Guid.Parse("00000000-0000-0000-0000-000000000001"); } [HttpGet] public async Task GetFlashcards( [FromQuery] string? search = null, [FromQuery] bool favoritesOnly = false) { try { var userId = GetUserId(); var flashcards = await _flashcardRepository.GetByUserIdAsync(userId, search, favoritesOnly); return Ok(new { Success = true, Data = new { Flashcards = flashcards.Select(f => new { f.Id, f.Word, f.Translation, f.Definition, f.PartOfSpeech, f.Pronunciation, f.Example, f.ExampleTranslation, f.IsFavorite, f.DifficultyLevel, f.CreatedAt, f.UpdatedAt }), Count = flashcards.Count() } }); } catch (Exception ex) { _logger.LogError(ex, "Error getting flashcards"); return StatusCode(500, new { Success = false, Error = "Failed to load flashcards" }); } } [HttpPost] public async Task CreateFlashcard([FromBody] CreateFlashcardRequest request) { try { var userId = GetUserId(); var flashcard = new Flashcard { Id = Guid.NewGuid(), UserId = userId, Word = request.Word, Translation = request.Translation, Definition = request.Definition ?? "", PartOfSpeech = request.PartOfSpeech, Pronunciation = request.Pronunciation, Example = request.Example, ExampleTranslation = request.ExampleTranslation, DifficultyLevel = "A2", // 預設等級 CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; await _flashcardRepository.AddAsync(flashcard); return Ok(new { Success = true, Data = flashcard, Message = "詞卡創建成功" }); } catch (Exception ex) { _logger.LogError(ex, "Error creating flashcard"); return StatusCode(500, new { Success = false, Error = "Failed to create flashcard" }); } } [HttpGet("{id}")] public async Task GetFlashcard(Guid id) { try { var userId = GetUserId(); var flashcard = await _flashcardRepository.GetByUserIdAndFlashcardIdAsync(userId, id); if (flashcard == null) { return NotFound(new { Success = false, Error = "Flashcard not found" }); } return Ok(new { Success = true, Data = flashcard }); } catch (Exception ex) { _logger.LogError(ex, "Error getting flashcard {FlashcardId}", id); return StatusCode(500, new { Success = false, Error = "Failed to get flashcard" }); } } [HttpPut("{id}")] public async Task UpdateFlashcard(Guid id, [FromBody] CreateFlashcardRequest request) { try { var userId = GetUserId(); var flashcard = await _flashcardRepository.GetByUserIdAndFlashcardIdAsync(userId, id); if (flashcard == null) { return NotFound(new { Success = false, Error = "Flashcard not found" }); } // 更新詞卡資訊 flashcard.Word = request.Word; flashcard.Translation = request.Translation; flashcard.Definition = request.Definition ?? ""; flashcard.PartOfSpeech = request.PartOfSpeech; flashcard.Pronunciation = request.Pronunciation; flashcard.Example = request.Example; flashcard.ExampleTranslation = request.ExampleTranslation; flashcard.UpdatedAt = DateTime.UtcNow; await _flashcardRepository.UpdateAsync(flashcard); return Ok(new { Success = true, Data = flashcard, Message = "詞卡更新成功" }); } catch (Exception ex) { _logger.LogError(ex, "Error updating flashcard {FlashcardId}", id); return StatusCode(500, new { Success = false, Error = "Failed to update flashcard" }); } } [HttpDelete("{id}")] public async Task DeleteFlashcard(Guid id) { try { var userId = GetUserId(); var flashcard = await _flashcardRepository.GetByUserIdAndFlashcardIdAsync(userId, id); if (flashcard == null) { return NotFound(new { Success = false, Error = "Flashcard not found" }); } await _flashcardRepository.DeleteAsync(flashcard); return Ok(new { Success = true, Message = "詞卡已刪除" }); } catch (Exception ex) { _logger.LogError(ex, "Error deleting flashcard {FlashcardId}", id); return StatusCode(500, new { Success = false, Error = "Failed to delete flashcard" }); } } [HttpPost("{id}/favorite")] public async Task ToggleFavorite(Guid id) { try { var userId = GetUserId(); var flashcard = await _flashcardRepository.GetByUserIdAndFlashcardIdAsync(userId, id); if (flashcard == null) { return NotFound(new { Success = false, Error = "Flashcard not found" }); } flashcard.IsFavorite = !flashcard.IsFavorite; flashcard.UpdatedAt = DateTime.UtcNow; await _flashcardRepository.UpdateAsync(flashcard); return Ok(new { Success = true, IsFavorite = flashcard.IsFavorite, Message = flashcard.IsFavorite ? "已加入收藏" : "已取消收藏" }); } catch (Exception ex) { _logger.LogError(ex, "Error toggling favorite for flashcard {FlashcardId}", id); return StatusCode(500, new { Success = false, Error = "Failed to toggle favorite" }); } } } // DTO 類別 public class CreateFlashcardRequest { public string Word { get; set; } = string.Empty; public string Translation { get; set; } = string.Empty; public string Definition { get; set; } = string.Empty; public string PartOfSpeech { get; set; } = string.Empty; public string Pronunciation { get; set; } = string.Empty; public string Example { get; set; } = string.Empty; public string? ExampleTranslation { get; set; } }