using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using DramaLing.Api.Data;
using DramaLing.Api.Models.Entities;
using DramaLing.Api.Models.DTOs;
using DramaLing.Api.Models.DTOs.SpacedRepetition;
using DramaLing.Api.Services;
using DramaLing.Api.Services.Storage;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;

namespace DramaLing.Api.Controllers;

[ApiController]
[Route("api/flashcards")]
[AllowAnonymous] // 暫時移除認證要求，修復網路錯誤
public class FlashcardsController : ControllerBase
{
    private readonly DramaLingDbContext _context;
    private readonly ILogger<FlashcardsController> _logger;
    private readonly IImageStorageService _imageStorageService;
    // 🆕 智能複習服務依賴
    private readonly ISpacedRepetitionService _spacedRepetitionService;
    private readonly IReviewTypeSelectorService _reviewTypeSelectorService;
    private readonly IQuestionGeneratorService _questionGeneratorService;

    public FlashcardsController(
        DramaLingDbContext context,
        ILogger<FlashcardsController> logger,
        IImageStorageService imageStorageService,
        ISpacedRepetitionService spacedRepetitionService,
        IReviewTypeSelectorService reviewTypeSelectorService,
        IQuestionGeneratorService questionGeneratorService)
    {
        _context = context;
        _logger = logger;
        _imageStorageService = imageStorageService;
        _spacedRepetitionService = spacedRepetitionService;
        _reviewTypeSelectorService = reviewTypeSelectorService;
        _questionGeneratorService = questionGeneratorService;
    }

    private Guid GetUserId()
    {
        // 暫時使用固定測試用戶 ID，避免認證問題
        // TODO: 恢復真實認證後改回 JWT Token 解析
        return Guid.Parse("00000000-0000-0000-0000-000000000001");

        // var userIdString = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ??
        //                   User.FindFirst("sub")?.Value;
        //
        // if (Guid.TryParse(userIdString, out var userId))
        //     return userId;
        //
        // throw new UnauthorizedAccessException("Invalid user ID in token");
    }

    [HttpGet]
    public async Task<ActionResult> GetFlashcards(
        [FromQuery] string? search = null,
        [FromQuery] bool favoritesOnly = false,
        [FromQuery] string? cefrLevel = null,
        [FromQuery] string? partOfSpeech = null,
        [FromQuery] string? masteryLevel = null)
    {
        try
        {
            var userId = GetUserId();

            var query = _context.Flashcards
                .Include(f => f.FlashcardExampleImages)
                    .ThenInclude(fei => fei.ExampleImage)
                .Where(f => f.UserId == userId && !f.IsArchived)
                .AsQueryable();

            // 搜尋篩選 (擴展支援例句內容)
            if (!string.IsNullOrEmpty(search))
            {
                query = query.Where(f =>
                    f.Word.Contains(search) ||
                    f.Translation.Contains(search) ||
                    (f.Definition != null && f.Definition.Contains(search)) ||
                    (f.Example != null && f.Example.Contains(search)) ||
                    (f.ExampleTranslation != null && f.ExampleTranslation.Contains(search)));
            }

            // 收藏篩選
            if (favoritesOnly)
            {
                query = query.Where(f => f.IsFavorite);
            }

            // CEFR 等級篩選
            if (!string.IsNullOrEmpty(cefrLevel))
            {
                query = query.Where(f => f.DifficultyLevel == cefrLevel);
            }

            // 詞性篩選
            if (!string.IsNullOrEmpty(partOfSpeech))
            {
                query = query.Where(f => f.PartOfSpeech == partOfSpeech);
            }

            // 掌握度篩選
            if (!string.IsNullOrEmpty(masteryLevel))
            {
                switch (masteryLevel.ToLower())
                {
                    case "high":
                        query = query.Where(f => f.MasteryLevel >= 80);
                        break;
                    case "medium":
                        query = query.Where(f => f.MasteryLevel >= 60 && f.MasteryLevel < 80);
                        break;
                    case "low":
                        query = query.Where(f => f.MasteryLevel < 60);
                        break;
                }
            }

            var flashcards = await query
                .AsNoTracking() // 效能優化：只讀查詢
                .OrderByDescending(f => f.CreatedAt)
                .ToListAsync();

            // 生成圖片資訊
            var flashcardDtos = new List<object>();
            foreach (var flashcard in flashcards)
            {
                // 獲取例句圖片資料 (與 GetFlashcard 方法保持一致)
                var exampleImages = flashcard.FlashcardExampleImages?
                    .Select(fei => new
                    {
                        Id = fei.ExampleImage.Id,
                        ImageUrl = $"http://localhost:5008/images/examples/{fei.ExampleImage.RelativePath}",
                        IsPrimary = fei.IsPrimary,
                        QualityScore = fei.ExampleImage.QualityScore,
                        FileSize = fei.ExampleImage.FileSize,
                        CreatedAt = fei.ExampleImage.CreatedAt
                    })
                    .ToList();

                flashcardDtos.Add(new
                {
                    flashcard.Id,
                    flashcard.Word,
                    flashcard.Translation,
                    flashcard.Definition,
                    flashcard.PartOfSpeech,
                    flashcard.Pronunciation,
                    flashcard.Example,
                    flashcard.ExampleTranslation,
                    flashcard.MasteryLevel,
                    flashcard.TimesReviewed,
                    flashcard.IsFavorite,
                    flashcard.NextReviewDate,
                    flashcard.DifficultyLevel,
                    flashcard.CreatedAt,
                    flashcard.UpdatedAt,
                    // 新增圖片相關欄位
                    ExampleImages = exampleImages ?? (object)new List<object>(),
                    HasExampleImage = exampleImages?.Any() ?? false,
                    PrimaryImageUrl = exampleImages?.FirstOrDefault(img => img.IsPrimary)?.ImageUrl
                });
            }

            return Ok(new
            {
                Success = true,
                Data = new
                {
                    Flashcards = flashcardDtos,
                    Count = flashcardDtos.Count
                }
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting flashcards for user");
            return StatusCode(500, new { Success = false, Error = "Failed to load flashcards" });
        }
    }

    [HttpPost]
    public async Task<ActionResult> CreateFlashcard([FromBody] CreateFlashcardRequest request)
    {
        try
        {
            var userId = GetUserId();

            // 確保測試用戶存在
            var testUser = await _context.Users.FirstOrDefaultAsync(u => u.Id == userId);
            if (testUser == null)
            {
                testUser = new User
                {
                    Id = userId,
                    Username = "testuser",
                    Email = "test@example.com",
                    PasswordHash = "test_hash",
                    DisplayName = "測試用戶",
                    SubscriptionType = "free",
                    Preferences = new Dictionary<string, object>(),
                    EnglishLevel = "A2",
                    LevelUpdatedAt = DateTime.UtcNow,
                    IsLevelVerified = false,
                    CreatedAt = DateTime.UtcNow,
                    UpdatedAt = DateTime.UtcNow
                };
                _context.Users.Add(testUser);
                await _context.SaveChangesAsync();
            }

            // 檢測重複詞卡
            var existing = await _context.Flashcards
                .FirstOrDefaultAsync(f => f.UserId == userId &&
                    f.Word.ToLower() == request.Word.ToLower() &&
                    !f.IsArchived);

            if (existing != null)
            {
                return Ok(new
                {
                    Success = false,
                    Error = "詞卡已存在",
                    IsDuplicate = true,
                    ExistingCard = new
                    {
                        existing.Id,
                        existing.Word,
                        existing.Translation,
                        existing.CreatedAt
                    }
                });
            }

            var flashcard = new Flashcard
            {
                Id = Guid.NewGuid(),
                UserId = userId,
                CardSetId = null, // 暫時不使用 CardSet
                Word = request.Word,
                Translation = request.Translation,
                Definition = request.Definition ?? "",
                PartOfSpeech = request.PartOfSpeech,
                Pronunciation = request.Pronunciation,
                Example = request.Example,
                ExampleTranslation = request.ExampleTranslation,
                MasteryLevel = 0,
                TimesReviewed = 0,
                IsFavorite = false,
                NextReviewDate = DateTime.Today,
                DifficultyLevel = "A2", // 預設等級
                EasinessFactor = 2.5f,
                IntervalDays = 1,
                CreatedAt = DateTime.UtcNow,
                UpdatedAt = DateTime.UtcNow
            };

            _context.Flashcards.Add(flashcard);
            await _context.SaveChangesAsync();

            return Ok(new
            {
                Success = true,
                Data = new
                {
                    flashcard.Id,
                    flashcard.Word,
                    flashcard.Translation,
                    flashcard.Definition,
                    flashcard.CreatedAt
                },
                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<ActionResult> GetFlashcard(Guid id)
    {
        try
        {
            var userId = GetUserId();

            var flashcard = await _context.Flashcards
                .Include(f => f.FlashcardExampleImages)
                    .ThenInclude(fei => fei.ExampleImage)
                .FirstOrDefaultAsync(f => f.Id == id && f.UserId == userId);

            if (flashcard == null)
            {
                return NotFound(new { Success = false, Error = "Flashcard not found" });
            }

            // 獲取例句圖片資料
            var exampleImages = flashcard.FlashcardExampleImages
                ?.Select(fei => new
                {
                    Id = fei.ExampleImage.Id,
                    ImageUrl = $"http://localhost:5008/images/examples/{fei.ExampleImage.RelativePath}",
                    IsPrimary = fei.IsPrimary,
                    QualityScore = fei.ExampleImage.QualityScore,
                    FileSize = fei.ExampleImage.FileSize,
                    CreatedAt = fei.ExampleImage.CreatedAt
                })
                .ToList();

            return Ok(new
            {
                Success = true,
                Data = new
                {
                    flashcard.Id,
                    flashcard.Word,
                    flashcard.Translation,
                    flashcard.Definition,
                    flashcard.PartOfSpeech,
                    flashcard.Pronunciation,
                    flashcard.Example,
                    flashcard.ExampleTranslation,
                    flashcard.MasteryLevel,
                    flashcard.TimesReviewed,
                    flashcard.IsFavorite,
                    flashcard.NextReviewDate,
                    flashcard.DifficultyLevel,
                    flashcard.CreatedAt,
                    flashcard.UpdatedAt,
                    // 新增圖片相關欄位
                    ExampleImages = exampleImages ?? (object)new List<object>(),
                    HasExampleImage = exampleImages?.Any() ?? false,
                    PrimaryImageUrl = flashcard.FlashcardExampleImages?
                        .Where(fei => fei.IsPrimary)
                        .Select(fei => $"http://localhost:5008/images/examples/{fei.ExampleImage.RelativePath}")
                        .FirstOrDefault()
                }
            });
        }
        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<ActionResult> UpdateFlashcard(Guid id, [FromBody] CreateFlashcardRequest request)
    {
        try
        {
            var userId = GetUserId();

            var flashcard = await _context.Flashcards
                .FirstOrDefaultAsync(f => f.Id == id && f.UserId == userId);

            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 _context.SaveChangesAsync();

            return Ok(new
            {
                Success = true,
                Data = new
                {
                    flashcard.Id,
                    flashcard.Word,
                    flashcard.Translation,
                    flashcard.Definition,
                    flashcard.CreatedAt,
                    flashcard.UpdatedAt
                },
                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<ActionResult> DeleteFlashcard(Guid id)
    {
        try
        {
            var userId = GetUserId();

            var flashcard = await _context.Flashcards
                .FirstOrDefaultAsync(f => f.Id == id && f.UserId == userId);

            if (flashcard == null)
            {
                return NotFound(new { Success = false, Error = "Flashcard not found" });
            }

            _context.Flashcards.Remove(flashcard);
            await _context.SaveChangesAsync();

            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<ActionResult> ToggleFavorite(Guid id)
    {
        try
        {
            var userId = GetUserId();

            var flashcard = await _context.Flashcards
                .FirstOrDefaultAsync(f => f.Id == id && f.UserId == userId);

            if (flashcard == null)
            {
                return NotFound(new { Success = false, Error = "Flashcard not found" });
            }

            flashcard.IsFavorite = !flashcard.IsFavorite;
            flashcard.UpdatedAt = DateTime.UtcNow;

            await _context.SaveChangesAsync();

            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" });
        }
    }

    // ================== 🆕 智能複習API端點 ==================

    /// <summary>
    /// 取得到期詞卡列表
    /// </summary>
    [HttpGet("due")]
    public async Task<ActionResult> GetDueFlashcards(
        [FromQuery] string? date = null,
        [FromQuery] int limit = 50)
    {
        try
        {
            var userId = GetUserId();
            var queryDate = DateTime.TryParse(date, out var parsed) ? parsed : DateTime.Now.Date;

            var dueCards = await _spacedRepetitionService.GetDueFlashcardsAsync(userId, queryDate, limit);

            _logger.LogInformation("Retrieved {Count} due flashcards for user {UserId}", dueCards.Count, userId);

            return Ok(new { success = true, data = dueCards, count = dueCards.Count });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting due flashcards");
            return StatusCode(500, new { success = false, error = "Failed to get due flashcards" });
        }
    }

    /// <summary>
    /// 取得下一張需要復習的詞卡 (最高優先級)
    /// </summary>
    [HttpGet("next-review")]
    public async Task<ActionResult> GetNextReviewCard()
    {
        try
        {
            var userId = GetUserId();
            var nextCard = await _spacedRepetitionService.GetNextReviewCardAsync(userId);

            if (nextCard == null)
            {
                return Ok(new { success = true, data = (object?)null, message = "沒有到期的詞卡" });
            }

            // 計算當前熟悉度
            var currentMasteryLevel = _spacedRepetitionService.CalculateCurrentMasteryLevel(nextCard);

            // 設置UserLevel和WordLevel (如果是舊資料)
            if (nextCard.UserLevel == 0)
                nextCard.UserLevel = CEFRMappingService.GetDefaultUserLevel();
            if (nextCard.WordLevel == 0)
                nextCard.WordLevel = CEFRMappingService.GetWordLevel(nextCard.DifficultyLevel);

            var response = new
            {
                nextCard.Id,
                nextCard.Word,
                nextCard.Translation,
                nextCard.Definition,
                nextCard.Pronunciation,
                nextCard.PartOfSpeech,
                nextCard.Example,
                nextCard.ExampleTranslation,
                nextCard.MasteryLevel,
                nextCard.TimesReviewed,
                nextCard.IsFavorite,
                nextCard.NextReviewDate,
                nextCard.DifficultyLevel,
                // 智能複習擴展欄位
                nextCard.UserLevel,
                nextCard.WordLevel,
                BaseMasteryLevel = nextCard.MasteryLevel,
                LastReviewDate = nextCard.LastReviewedAt,
                CurrentInterval = nextCard.IntervalDays,
                IsOverdue = DateTime.Now.Date > nextCard.NextReviewDate.Date,
                OverdueDays = Math.Max(0, (DateTime.Now.Date - nextCard.NextReviewDate.Date).Days),
                CurrentMasteryLevel = currentMasteryLevel
            };

            _logger.LogInformation("Retrieved next review card: {Word} for user {UserId}", nextCard.Word, userId);

            return Ok(new { success = true, data = response });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting next review card");
            return StatusCode(500, new { success = false, error = "Failed to get next review card" });
        }
    }

    /// <summary>
    /// 系統自動選擇最適合的複習題型
    /// </summary>
    [HttpPost("{id}/optimal-review-mode")]
    public async Task<ActionResult> GetOptimalReviewMode(Guid id, [FromBody] OptimalModeRequest request)
    {
        try
        {
            var result = await _reviewTypeSelectorService.SelectOptimalReviewModeAsync(
                id, request.UserLevel, request.WordLevel);

            _logger.LogInformation("Selected optimal review mode {SelectedMode} for flashcard {FlashcardId}",
                result.SelectedMode, id);

            return Ok(new { success = true, data = result });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error selecting optimal review mode for flashcard {FlashcardId}", id);
            return StatusCode(500, new { success = false, error = "Failed to select optimal review mode" });
        }
    }

    /// <summary>
    /// 生成指定題型的題目選項
    /// </summary>
    [HttpPost("{id}/question")]
    public async Task<ActionResult> GenerateQuestion(Guid id, [FromBody] QuestionRequest request)
    {
        try
        {
            var questionData = await _questionGeneratorService.GenerateQuestionAsync(id, request.QuestionType);

            _logger.LogInformation("Generated {QuestionType} question for flashcard {FlashcardId}",
                request.QuestionType, id);

            return Ok(new { success = true, data = questionData });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error generating {QuestionType} question for flashcard {FlashcardId}",
                request.QuestionType, id);
            return StatusCode(500, new { success = false, error = "Failed to generate question" });
        }
    }

    /// <summary>
    /// 提交復習結果並更新間隔重複算法
    /// </summary>
    [HttpPost("{id}/review")]
    public async Task<ActionResult> SubmitReview(Guid id, [FromBody] ReviewRequest request)
    {
        try
        {
            var result = await _spacedRepetitionService.ProcessReviewAsync(id, request);

            _logger.LogInformation("Processed review for flashcard {FlashcardId}, questionType: {QuestionType}, isCorrect: {IsCorrect}",
                id, request.QuestionType, request.IsCorrect);

            return Ok(new { success = true, data = result });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error processing review for flashcard {FlashcardId}", id);
            return StatusCode(500, new { success = false, error = "Failed to process review" });
        }
    }
}

// 請求 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; }
}