using DramaLing.Api.Services;

namespace DramaLing.Api.Services.Domain.Learning;

/// <summary>
/// 間隔重複學習服務介面
/// </summary>
public interface ISpacedRepetitionService
{
    /// <summary>
    /// 計算下次複習時間
    /// </summary>
    Task<ReviewSchedule> CalculateNextReviewAsync(ReviewInput input);

    /// <summary>
    /// 更新學習進度
    /// </summary>
    Task<StudyProgress> UpdateStudyProgressAsync(Guid flashcardId, int qualityRating, Guid userId);

    /// <summary>
    /// 取得今日應複習的詞卡
    /// </summary>
    Task<IEnumerable<ReviewCard>> GetDueCardsAsync(Guid userId, int limit = 20);

    /// <summary>
    /// 取得學習統計
    /// </summary>
    Task<LearningAnalytics> GetLearningAnalyticsAsync(Guid userId);

    /// <summary>
    /// 優化學習序列
    /// </summary>
    Task<OptimizedStudyPlan> GenerateStudyPlanAsync(Guid userId, int targetMinutes);
}

/// <summary>
/// 複習輸入參數
/// </summary>
public class ReviewInput
{
    public Guid FlashcardId { get; set; }
    public Guid UserId { get; set; }
    public int QualityRating { get; set; } // 1-5 (SM2 標準)
    public int CurrentRepetitions { get; set; }
    public float CurrentEasinessFactor { get; set; }
    public int CurrentIntervalDays { get; set; }
    public DateTime LastReviewDate { get; set; }
}

/// <summary>
/// 複習排程結果
/// </summary>
public class ReviewSchedule
{
    public DateTime NextReviewDate { get; set; }
    public int NewIntervalDays { get; set; }
    public float NewEasinessFactor { get; set; }
    public int NewRepetitions { get; set; }
    public int NewMasteryLevel { get; set; }
    public string RecommendedAction { get; set; } = string.Empty;
}

/// <summary>
/// 學習進度
/// </summary>
public class StudyProgress
{
    public Guid FlashcardId { get; set; }
    public bool IsImproved { get; set; }
    public int PreviousMasteryLevel { get; set; }
    public int NewMasteryLevel { get; set; }
    public DateTime NextReviewDate { get; set; }
    public string ProgressMessage { get; set; } = string.Empty;
}

/// <summary>
/// 複習卡片
/// </summary>
public class ReviewCard
{
    public Guid Id { get; set; }
    public string Word { get; set; } = string.Empty;
    public string Translation { get; set; } = string.Empty;
    public string DifficultyLevel { get; set; } = string.Empty;
    public int MasteryLevel { get; set; }
    public DateTime NextReviewDate { get; set; }
    public int DaysSinceLastReview { get; set; }
    public int ReviewPriority { get; set; } // 1-5 (5 最高)
}

/// <summary>
/// 學習分析
/// </summary>
public class LearningAnalytics
{
    public int TotalCards { get; set; }
    public int DueCards { get; set; }
    public int OverdueCards { get; set; }
    public int MasteredCards { get; set; }
    public double RetentionRate { get; set; }
    public TimeSpan AverageStudyInterval { get; set; }
    public Dictionary<string, int> DifficultyDistribution { get; set; } = new();
    public List<DailyStudyStats> RecentPerformance { get; set; } = new();
}

/// <summary>
/// 每日學習統計
/// </summary>
public class DailyStudyStats
{
    public DateOnly Date { get; set; }
    public int CardsReviewed { get; set; }
    public int CorrectAnswers { get; set; }
    public double AccuracyRate => CardsReviewed > 0 ? (double)CorrectAnswers / CardsReviewed : 0;
    public TimeSpan StudyDuration { get; set; }
}

/// <summary>
/// 優化學習計劃
/// </summary>
public class OptimizedStudyPlan
{
    public IEnumerable<ReviewCard> RecommendedCards { get; set; } = new List<ReviewCard>();
    public int EstimatedMinutes { get; set; }
    public string StudyFocus { get; set; } = string.Empty; // "複習", "新學習", "加強練習"
    public Dictionary<string, int> LevelBreakdown { get; set; } = new();
    public string RecommendationReason { get; set; } = string.Empty;
}

/// <summary>
/// 間隔重複學習服務實作
/// </summary>
public class SpacedRepetitionService : ISpacedRepetitionService
{
    private readonly ILogger<SpacedRepetitionService> _logger;

    public SpacedRepetitionService(ILogger<SpacedRepetitionService> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public Task<ReviewSchedule> CalculateNextReviewAsync(ReviewInput input)
    {
        try
        {
            // 使用現有的 SM2Algorithm
            var sm2Input = new SM2Input(
                input.QualityRating,
                input.CurrentEasinessFactor,
                input.CurrentRepetitions,
                input.CurrentIntervalDays
            );

            var sm2Result = SM2Algorithm.Calculate(sm2Input);

            var schedule = new ReviewSchedule
            {
                NextReviewDate = sm2Result.NextReviewDate,
                NewIntervalDays = sm2Result.IntervalDays,
                NewEasinessFactor = sm2Result.EasinessFactor,
                NewRepetitions = sm2Result.Repetitions,
                NewMasteryLevel = CalculateMasteryLevel(sm2Result.EasinessFactor, sm2Result.Repetitions),
                RecommendedAction = GetRecommendedAction(input.QualityRating)
            };

            return Task.FromResult(schedule);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error calculating next review for flashcard {FlashcardId}", input.FlashcardId);
            throw;
        }
    }

    public Task<StudyProgress> UpdateStudyProgressAsync(Guid flashcardId, int qualityRating, Guid userId)
    {
        // 這裡應該整合 Repository 來獲取和更新詞卡數據
        // 暫時返回模擬結果
        var progress = new StudyProgress
        {
            FlashcardId = flashcardId,
            IsImproved = qualityRating >= 3,
            ProgressMessage = GetProgressMessage(qualityRating)
        };

        return Task.FromResult(progress);
    }

    public Task<IEnumerable<ReviewCard>> GetDueCardsAsync(Guid userId, int limit = 20)
    {
        // 需要整合 Repository 來實作
        var cards = new List<ReviewCard>();
        return Task.FromResult<IEnumerable<ReviewCard>>(cards);
    }

    public Task<LearningAnalytics> GetLearningAnalyticsAsync(Guid userId)
    {
        // 需要整合 Repository 來實作
        var analytics = new LearningAnalytics();
        return Task.FromResult(analytics);
    }

    public Task<OptimizedStudyPlan> GenerateStudyPlanAsync(Guid userId, int targetMinutes)
    {
        // 需要整合 Repository 和 AI 服務來實作
        var plan = new OptimizedStudyPlan
        {
            EstimatedMinutes = targetMinutes,
            StudyFocus = "複習",
            RecommendationReason = "基於間隔重複算法的個人化推薦"
        };

        return Task.FromResult(plan);
    }

    #region 私有方法

    private int CalculateMasteryLevel(float easinessFactor, int repetitions)
    {
        // 根據難度係數和重複次數計算掌握程度
        if (repetitions >= 5 && easinessFactor >= 2.3f) return 5; // 完全掌握
        if (repetitions >= 3 && easinessFactor >= 2.0f) return 4; // 熟練
        if (repetitions >= 2 && easinessFactor >= 1.8f) return 3; // 理解
        if (repetitions >= 1) return 2; // 認識
        return 1; // 新學習
    }

    private string GetRecommendedAction(int qualityRating)
    {
        return qualityRating switch
        {
            1 => "建議重新學習此詞彙",
            2 => "需要額外練習",
            3 => "繼續複習",
            4 => "掌握良好",
            5 => "完全掌握",
            _ => "繼續學習"
        };
    }

    private string GetProgressMessage(int qualityRating)
    {
        return qualityRating switch
        {
            1 or 2 => "需要加強練習，別氣餒！",
            3 => "不錯的進步！",
            4 => "很好！掌握得不錯",
            5 => "太棒了！完全掌握",
            _ => "繼續努力學習！"
        };
    }

    #endregion
}