using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using DramaLing.Api.Data;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;

namespace DramaLing.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class StatsController : ControllerBase
{
    private readonly DramaLingDbContext _context;

    public StatsController(DramaLingDbContext context)
    {
        _context = context;
    }

    private Guid GetUserId()
    {
        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");
    }

    [HttpGet("dashboard")]
    public async Task<ActionResult> GetDashboardStats()
    {
        try
        {
            var userId = GetUserId();
            var today = DateOnly.FromDateTime(DateTime.Today);

            // 並行獲取統計數據
            var totalWordsTask = _context.Flashcards.CountAsync(f => f.UserId == userId);
            var cardSetsTask = _context.CardSets
                .Where(cs => cs.UserId == userId)
                .OrderByDescending(cs => cs.CreatedAt)
                .Take(5)
                .Select(cs => new
                {
                    cs.Id,
                    cs.Name,
                    Count = cs.CardCount,
                    Progress = cs.CardCount > 0 ?
                        _context.Flashcards
                            .Where(f => f.CardSetId == cs.Id)
                            .Average(f => (double?)f.MasteryLevel) ?? 0 : 0,
                    LastStudied = cs.CreatedAt
                })
                .ToListAsync();

            var recentCardsTask = _context.Flashcards
                .Where(f => f.UserId == userId)
                .OrderByDescending(f => f.LastReviewedAt ?? f.CreatedAt)
                .Take(4)
                .Select(f => new
                {
                    f.Word,
                    f.Translation,
                    Status = f.MasteryLevel >= 80 ? "learned" :
                            f.MasteryLevel >= 40 ? "learning" : "new"
                })
                .ToListAsync();

            var todayStatsTask = _context.DailyStats
                .FirstOrDefaultAsync(ds => ds.UserId == userId && ds.Date == today);

            // 等待所有查詢完成
            await Task.WhenAll(totalWordsTask, cardSetsTask, recentCardsTask, todayStatsTask);

            var totalWords = await totalWordsTask;
            var cardSets = await cardSetsTask;
            var recentCards = await recentCardsTask;
            var todayStats = await todayStatsTask;

            // 計算統計數據
            var wordsToday = todayStats?.WordsStudied ?? 0;
            var wordsCorrect = todayStats?.WordsCorrect ?? 0;
            var accuracy = wordsToday > 0 ? (int)Math.Round((double)wordsCorrect / wordsToday * 100) : 85;

            // 模擬連續天數 (Phase 1 簡化)
            var streakDays = 7;
            var todayReviewCount = 23; // 模擬數據

            return Ok(new
            {
                Success = true,
                Data = new
                {
                    TotalWords = totalWords,
                    WordsToday = wordsToday,
                    StreakDays = streakDays,
                    AccuracyPercentage = accuracy,
                    TodayReviewCount = todayReviewCount,
                    CompletedToday = wordsToday,
                    RecentWords = recentCards.Count > 0 ? recentCards.Cast<object>().ToList() : new List<object>
                    {
                        new { Word = "negotiate", Translation = "協商", Status = "learned" },
                        new { Word = "accomplish", Translation = "完成", Status = "learning" },
                        new { Word = "perspective", Translation = "觀點", Status = "new" },
                        new { Word = "substantial", Translation = "大量的", Status = "learned" }
                    },
                    CardSets = cardSets
                }
            });
        }
        catch (UnauthorizedAccessException)
        {
            return Unauthorized(new { Success = false, Error = "Unauthorized" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new
            {
                Success = false,
                Error = "Failed to fetch dashboard stats",
                Timestamp = DateTime.UtcNow
            });
        }
    }

    [HttpGet("trends")]
    public async Task<ActionResult> GetTrends([FromQuery] string period = "week")
    {
        try
        {
            var userId = GetUserId();
            var days = period switch
            {
                "week" => 7,
                "month" => 30,
                "year" => 365,
                _ => 7
            };

            var endDate = DateOnly.FromDateTime(DateTime.Today);
            var startDate = endDate.AddDays(-days + 1);

            var dailyStats = await _context.DailyStats
                .Where(ds => ds.UserId == userId && ds.Date >= startDate && ds.Date <= endDate)
                .OrderBy(ds => ds.Date)
                .ToListAsync();

            // 生成完整的日期序列
            var dateRange = Enumerable.Range(0, days)
                .Select(i => startDate.AddDays(i))
                .ToList();

            var statsMap = dailyStats.ToDictionary(ds => ds.Date, ds => ds);

            var completeStats = dateRange.Select(date =>
            {
                var stat = statsMap.GetValueOrDefault(date);
                return new
                {
                    Date = date.ToString("yyyy-MM-dd"),
                    WordsStudied = stat?.WordsStudied ?? 0,
                    WordsCorrect = stat?.WordsCorrect ?? 0,
                    StudyTimeSeconds = stat?.StudyTimeSeconds ?? 0,
                    SessionCount = stat?.SessionCount ?? 0,
                    CardsGenerated = stat?.CardsGenerated ?? 0,
                    Accuracy = stat != null && stat.WordsStudied > 0
                        ? (int)Math.Round((double)stat.WordsCorrect / stat.WordsStudied * 100)
                        : 0
                };
            }).ToList();

            // 計算總結數據
            var totalWordsStudied = completeStats.Sum(s => s.WordsStudied);
            var totalCorrect = completeStats.Sum(s => s.WordsCorrect);
            var totalStudyTime = completeStats.Sum(s => s.StudyTimeSeconds);
            var totalSessions = completeStats.Sum(s => s.SessionCount);

            var averageAccuracy = totalWordsStudied > 0
                ? (int)Math.Round((double)totalCorrect / totalWordsStudied * 100)
                : 0;

            return Ok(new
            {
                Success = true,
                Data = new
                {
                    Period = period,
                    DateRange = new
                    {
                        Start = startDate.ToString("yyyy-MM-dd"),
                        End = endDate.ToString("yyyy-MM-dd")
                    },
                    DailyCounts = completeStats,
                    Summary = new
                    {
                        TotalWordsStudied = totalWordsStudied,
                        TotalCorrect = totalCorrect,
                        TotalStudyTimeSeconds = totalStudyTime,
                        TotalSessions = totalSessions,
                        AverageAccuracy = averageAccuracy,
                        AverageDailyWords = (int)Math.Round((double)totalWordsStudied / days),
                        AverageSessionDuration = totalSessions > 0
                            ? totalStudyTime / totalSessions
                            : 0
                    }
                }
            });
        }
        catch (UnauthorizedAccessException)
        {
            return Unauthorized(new { Success = false, Error = "Unauthorized" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new
            {
                Success = false,
                Error = "Failed to fetch learning trends",
                Timestamp = DateTime.UtcNow
            });
        }
    }

    [HttpGet("detailed")]
    public async Task<ActionResult> GetDetailedStats()
    {
        try
        {
            var userId = GetUserId();

            // 獲取詞卡統計
            var flashcards = await _context.Flashcards
                .Where(f => f.UserId == userId)
                .ToListAsync();

            // 按難度分類
            var difficultyStats = flashcards
                .GroupBy(f => f.DifficultyLevel ?? "unknown")
                .ToDictionary(g => g.Key, g => g.Count());

            // 按詞性分類
            var partOfSpeechStats = flashcards
                .GroupBy(f => f.PartOfSpeech ?? "unknown")
                .ToDictionary(g => g.Key, g => g.Count());

            // 掌握度分布
            var masteryDistribution = new
            {
                Mastered = flashcards.Count(f => f.MasteryLevel >= 80),
                Learning = flashcards.Count(f => f.MasteryLevel >= 40 && f.MasteryLevel < 80),
                New = flashcards.Count(f => f.MasteryLevel < 40)
            };

            // 最近30天的學習記錄 (模擬數據)
            var learningCurve = Enumerable.Range(0, 30)
                .Select(i =>
                {
                    var date = DateTime.Today.AddDays(-29 + i);
                    var accuracy = 70 + new Random(date.DayOfYear).Next(-15, 25); // 模擬準確率
                    return new
                    {
                        Date = date.ToString("yyyy-MM-dd"),
                        Accuracy = Math.Clamp(accuracy, 0, 100),
                        Count = new Random(date.DayOfYear).Next(0, 15)
                    };
                }).ToList();

            return Ok(new
            {
                Success = true,
                Data = new
                {
                    ByDifficulty = difficultyStats,
                    ByPartOfSpeech = partOfSpeechStats,
                    MasteryDistribution = masteryDistribution,
                    LearningCurve = learningCurve,
                    Summary = new
                    {
                        TotalCards = flashcards.Count,
                        AverageMastery = flashcards.Count > 0
                            ? (int)flashcards.Average(f => f.MasteryLevel)
                            : 0,
                        OverallAccuracy = flashcards.Count > 0 && flashcards.Sum(f => f.TimesReviewed) > 0
                            ? (int)Math.Round((double)flashcards.Sum(f => f.TimesCorrect) / flashcards.Sum(f => f.TimesReviewed) * 100)
                            : 0
                    }
                }
            });
        }
        catch (UnauthorizedAccessException)
        {
            return Unauthorized(new { Success = false, Error = "Unauthorized" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new
            {
                Success = false,
                Error = "Failed to fetch detailed statistics",
                Timestamp = DateTime.UtcNow
            });
        }
    }
}