using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Tiku.Application.Learning;
using Tiku.Application.QuestionBanks;
using Tiku.Domain.Common;
using Tiku.Domain.Content;

namespace Tiku.Api.Contracts;

/// <summary>
/// 学习Limit查询参数。
/// </summary>
public sealed class LearningLimitQueryDto
{
    /// <summary>
    /// 返回数量上限。
    /// </summary>
    [Range(1, 500)]
    public int? Limit { get; set; }

    /// <summary>
    /// 状态。
    /// </summary>
    [StringLength(50)]
    public string? Status { get; set; }

    /// <summary>
    /// 单元 ID。
    /// </summary>
    public Guid? UnitId { get; set; }

    public LearningLimitFilter ToFilter()
    {
        return new LearningLimitFilter(Limit, Status, UnitId);
    }
}

/// <summary>
/// 练习会话查询参数。
/// </summary>
public sealed class PracticeSessionQueryDto
{
    /// <summary>
    /// 练习会话 ID。
    /// </summary>
    public Guid? PracticeSessionId { get; set; }

    /// <summary>
    /// 练习蓝图 ID。
    /// </summary>
    public Guid? BlueprintId { get; set; }

    /// <summary>
    /// 模式。
    /// </summary>
    [StringLength(50)]
    public string? Mode { get; set; }

    /// <summary>
    /// 状态。
    /// </summary>
    [StringLength(50)]
    public string? Status { get; set; }

    /// <summary>
    /// 返回数量上限。
    /// </summary>
    [Range(1, 200)]
    public int? Limit { get; set; }

    public PracticeSessionFilter ToFilter(Guid? routePracticeSessionId = null)
    {
        return new PracticeSessionFilter(
            routePracticeSessionId ?? PracticeSessionId,
            BlueprintId,
            Mode,
            Status,
            Limit);
    }
}

/// <summary>
/// 创建练习会话请求 DTO。
/// </summary>
public sealed class CreatePracticeSessionDto
{
    /// <summary>
    /// 模式。
    /// </summary>
    [StringLength(50)]
    public string? Mode { get; set; }

    /// <summary>
    /// 目标类型。
    /// </summary>
    [StringLength(50)]
    public string? TargetType { get; set; }

    /// <summary>
    /// 目标 ID。
    /// </summary>
    public Guid? TargetId { get; set; }

    /// <summary>
    /// 练习蓝图 ID。
    /// </summary>
    public Guid? BlueprintId { get; set; }

    /// <summary>
    /// 题集 ID。
    /// </summary>
    public Guid? CollectionId { get; set; }

    /// <summary>
    /// 内容入口 ID。
    /// </summary>
    public Guid? EntryId { get; set; }

    /// <summary>
    /// 内容节点 ID。
    /// </summary>
    public Guid? ContentNodeId { get; set; }

    /// <summary>
    /// 题目数量上限。
    /// </summary>
    [Range(1, 500)]
    public int? QuestionLimit { get; set; }

    /// <summary>
    /// 时长，单位为分钟。
    /// </summary>
    [Range(1, 1440)]
    public int? DurationMinutes { get; set; }

    /// <summary>
    /// 总分。
    /// </summary>
    [Range(typeof(decimal), "0", "99999")]
    public decimal? TotalScore { get; set; }

    /// <summary>
    /// 扩展元数据。
    /// </summary>
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();

    public PracticeSessionCommand ToCommand()
    {
        return new PracticeSessionCommand(
            Mode,
            TargetType,
            TargetId,
            BlueprintId,
            CollectionId,
            EntryId,
            ContentNodeId,
            QuestionLimit,
            DurationMinutes,
            TotalScore,
            Metadata);
    }
}

/// <summary>
/// 提交练习会话请求 DTO。
/// </summary>
public sealed class SubmitPracticeSessionDto
{
    /// <summary>
    /// 练习会话 ID。
    /// </summary>
    [Required]
    public Guid PracticeSessionId { get; set; }

    public PracticeSessionFilter ToFilter()
    {
        return new PracticeSessionFilter(PracticeSessionId);
    }
}

/// <summary>
/// 提交答案请求 DTO。
/// </summary>
public sealed class SubmitAnswerDto
{
    /// <summary>
    /// 会话题目 ID。
    /// </summary>
    [Required]
    public Guid SessionQuestionId { get; set; }

    /// <summary>
    /// 已选选项。
    /// </summary>
    public IReadOnlyCollection<string>? SelectedOptions { get; set; }

    /// <summary>
    /// 文字答案。
    /// </summary>
    [StringLength(10000)]
    public string? AnswerText { get; set; }

    /// <summary>
    /// 主观题自评是否正确。
    /// </summary>
    public bool? SelfJudgedCorrect { get; set; }

    public SubmitAnswerCommand ToCommand()
    {
        return new SubmitAnswerCommand(
            SessionQuestionId,
            SelectedOptions,
            AnswerText,
            SelfJudgedCorrect);
    }
}

/// <summary>
/// 题目Action请求 DTO。
/// </summary>
public sealed class QuestionActionDto
{
    /// <summary>
    /// 题目 ID。
    /// </summary>
    [Required]
    public Guid QuestionId { get; set; }

    /// <summary>
    /// 来源。
    /// </summary>
    [Required]
    public QuestionSource Source { get; set; } = QuestionSource.Tenant;

    /// <summary>
    /// 是否收藏。
    /// </summary>
    public bool? Favorite { get; set; }

    public QuestionActionCommand ToCommand()
    {
        return new QuestionActionCommand(new QuestionLocator(Source, QuestionId), Favorite);
    }
}

/// <summary>
/// 单词Progress请求 DTO。
/// </summary>
public sealed class WordProgressDto
{
    /// <summary>
    /// 单词 ID。
    /// </summary>
    [Required]
    public Guid WordId { get; set; }

    /// <summary>
    /// 状态。
    /// </summary>
    [StringLength(50)]
    public string? Status { get; set; }

    /// <summary>
    /// 答对数量变化。
    /// </summary>
    [Range(0, 100)]
    public int? CorrectDelta { get; set; }

    /// <summary>
    /// 答错数量变化。
    /// </summary>
    [Range(0, 100)]
    public int? WrongDelta { get; set; }

    /// <summary>
    /// 下次复习时间。
    /// </summary>
    public DateTimeOffset? NextReviewAt { get; set; }

    public WordProgressCommand ToCommand()
    {
        return new WordProgressCommand(
            WordId,
            Status,
            CorrectDelta,
            WrongDelta,
            NextReviewAt);
    }
}

/// <summary>
/// 收藏单词请求 DTO。
/// </summary>
public sealed class FavoriteWordDto
{
    /// <summary>
    /// 单词 ID。
    /// </summary>
    [Required]
    public Guid WordId { get; set; }

    /// <summary>
    /// 是否收藏。
    /// </summary>
    public bool? Favorite { get; set; }

    /// <summary>
    /// 备注。
    /// </summary>
    [StringLength(1000)]
    public string? Note { get; set; }

    public FavoriteWordCommand ToCommand()
    {
        return new FavoriteWordCommand(WordId, Favorite, Note);
    }
}

/// <summary>
/// 单词Review请求 DTO。
/// </summary>
public sealed class WordReviewDto
{
    /// <summary>
    /// 单词 ID。
    /// </summary>
    [Required]
    public Guid WordId { get; set; }

    /// <summary>
    /// 结果。
    /// </summary>
    [StringLength(50)]
    public string? Result { get; set; }

    /// <summary>
    /// 下次复习时间。
    /// </summary>
    public DateTimeOffset? NextReviewAt { get; set; }

    public WordReviewCommand ToCommand()
    {
        return new WordReviewCommand(WordId, Result, NextReviewAt);
    }
}
