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

namespace Tiku.Application.Learning;

public sealed record LearningActor(Guid TenantId, Guid UserId);

public sealed record LearningList<TItem>(IReadOnlyCollection<TItem> Items);

public sealed record SubmitAnswerCommand(
    Guid SessionQuestionId,
    long ExpectedSessionVersion,
    long ClientSequence,
    string IdempotencyKey,
    IReadOnlyCollection<int>? SelectedOptionIndices,
    string? AnswerText);

public sealed record SubmitPracticeSessionCommand(
    Guid PracticeSessionId,
    long ExpectedSessionVersion,
    string IdempotencyKey);

public sealed record QuestionActionCommand(QuestionLocator Locator, bool? Favorite);

public sealed record WordProgressCommand(
    Guid WordId,
    string? Status,
    int? CorrectDelta,
    int? WrongDelta,
    DateTimeOffset? NextReviewAt);

public sealed record FavoriteWordCommand(Guid WordId, bool? Favorite, string? Note);

public sealed record LearningLimitFilter(int? Limit = null, string? Status = null, Guid? UnitId = null);

public sealed record LearningStatsItem(
    int AnswerCount,
    int CorrectCount,
    int WrongCount,
    int FavoriteQuestionCount,
    int FavoriteWordCount,
    int WordProgressCount,
    int PracticeSessionCount,
    int PracticeReportCount);

public sealed record LearningTrendItem(DateOnly Date, int AnswerCount, int CorrectCount, int WrongCount);

public sealed record LearningLeaderboardItem(
    Guid UserId,
    string? DisplayName,
    int AnswerCount,
    int CorrectCount,
    int WrongCount,
    decimal Accuracy);

public sealed record LearningLeaderboardResult(
    string Metric,
    string Period,
    IReadOnlyCollection<LearningLeaderboardItem> Items,
    LearningLeaderboardItem? CurrentUser,
    DateTimeOffset GeneratedAt);

public sealed record WrongQuestionReviewPlanItem(
    Guid QuestionReferenceId,
    QuestionLocator Locator,
    int WrongCount,
    DateTimeOffset LastWrongAt);

public sealed record WrongQuestionReviewPlan(
    IReadOnlyCollection<WrongQuestionReviewPlanItem> Items,
    JsonElement NextAction);

public sealed record WordReviewPlanItem(
    Guid WordId,
    WordProgressStatus Status,
    DateTimeOffset? NextReviewAt,
    int CorrectCount,
    int WrongCount,
    WordDueLevel DueLevel);

public sealed record WordReviewPlan(
    IReadOnlyCollection<WordReviewPlanItem> Items,
    JsonElement NextAction);

public sealed record WordReviewCommand(Guid WordId, string? Result, DateTimeOffset? NextReviewAt);

public sealed record WordStatsItem(
    int Total,
    int NewCount,
    int LearningCount,
    int ReviewingCount,
    int MasteredCount,
    int DueCount,
    int FavoriteCount);

public sealed record PracticeSessionCommand(
    string? Mode,
    string? TargetType,
    Guid? TargetId,
    Guid? BlueprintId,
    Guid? CollectionId,
    Guid? EntryId,
    Guid? ContentNodeId,
    int? QuestionLimit,
    int? DurationMinutes,
    decimal? TotalScore,
    JsonElement Metadata);

public sealed record PracticeSessionFilter(
    Guid? PracticeSessionId = null,
    Guid? BlueprintId = null,
    string? Mode = null,
    string? Status = null,
    int? Limit = null);

public sealed record AnswerRecordItem(
    Guid Id,
    Guid SessionQuestionId,
    Guid PracticeSessionId,
    JsonElement SelectedOptionIndices,
    string? AnswerText,
    string Status,
    int Revision,
    long ClientSequence,
    long SessionVersion,
    DateTimeOffset AcceptedAt);

public sealed record FavoriteQuestionItem(
    Guid QuestionReferenceId,
    QuestionLocator Locator,
    DateTimeOffset CreatedAt);

public sealed record WrongQuestionItem(
    Guid QuestionReferenceId,
    QuestionLocator Locator,
    int WrongCount,
    DateTimeOffset LastWrongAt,
    DateTimeOffset? ResolvedAt);

public sealed record WordProgressItem(
    Guid WordId,
    WordProgressStatus Status,
    int CorrectCount,
    int WrongCount,
    DateTimeOffset? LastReviewAt,
    DateTimeOffset? NextReviewAt,
    int ReviewCount,
    int CorrectStreak,
    WordReviewResult? LastResult,
    WordDueLevel DueLevel,
    JsonElement Metadata);

public sealed record FavoriteWordItem(
    Guid WordId,
    string? Note,
    DateTimeOffset? FavoritedAt);

public sealed record LearningActionResult(bool Ok, bool? IsFavorite = null);

public sealed record PracticeSessionItem(
    Guid Id,
    string Mode,
    string? TargetType,
    Guid? TargetId,
    Guid? BlueprintId,
    Guid? CollectionId,
    Guid? EntryId,
    Guid? ContentNodeId,
    int QuestionCount,
    int? DurationMinutes,
    decimal? TotalScore,
    PracticeAccessMode AccessMode,
    Guid? AccessEntitlementId,
    int ConsumedFreeQuota,
    JsonElement AccessSnapshot,
    DateTimeOffset StartedAt,
    DateTimeOffset? FinishedAt,
    DateTimeOffset? ExpiresAt,
    JsonElement Metadata,
    PracticeSessionStatus Status,
    long Version,
    long LastClientSequence);

public sealed record PracticeSessionDetailItem(
    PracticeSessionItem Session,
    IReadOnlyCollection<PracticeSessionQuestionItem> Questions,
    IReadOnlyDictionary<Guid, AnswerRecordItem> AnswersBySessionQuestion);

public sealed record PracticeSessionQuestionItem(
    Guid SessionQuestionId,
    Guid QuestionReferenceId,
    QuestionLocator Locator,
    Guid QuestionId,
    string Type,
    string? TypeLabel,
    int? Difficulty,
    JsonElement Tags,
    Guid? VersionId,
    string? Content,
    JsonElement Options);

public sealed record PracticeSessionReportItem(
    Guid Id,
    Guid PracticeSessionId,
    Guid? BlueprintId,
    Guid? CollectionId,
    string Mode,
    int TotalQuestions,
    int AnsweredCount,
    int CorrectCount,
    int WrongCount,
    int UnansweredCount,
    decimal Score,
    decimal TotalScore,
    decimal Accuracy,
    int DurationSeconds,
    DateTimeOffset? StartedAt,
    DateTimeOffset SubmittedAt,
    PracticeReportStatus Status,
    int Version,
    bool IsFinal,
    int PendingReviewCount,
    int ScoringVersion,
    JsonElement SectionStats,
    JsonElement QuestionResults,
    JsonElement WrongQuestionIds,
    JsonElement Metadata);

public sealed record PracticeHistoryItem(
    Guid Id,
    string Mode,
    string? TargetType,
    Guid? TargetId,
    Guid? BlueprintId,
    Guid? CollectionId,
    Guid? EntryId,
    Guid? ContentNodeId,
    int QuestionCount,
    int AnsweredCount,
    int CorrectCount,
    int WrongCount,
    DateTimeOffset StartedAt,
    DateTimeOffset? FinishedAt,
    DateTimeOffset? ExpiresAt,
    string Status,
    Guid? ReportId,
    decimal? Score,
    decimal? ReportTotalScore,
    decimal? Accuracy);