using System.Text.Json;
using Tiku.Domain.Common;

namespace Tiku.Domain.Learning;

public sealed class PracticeSession : TenantEntity
{
    public Guid UserId { get; set; }
    public Guid? BlueprintId { get; set; }
    public Guid? CollectionId { get; set; }
    public Guid? EntryId { get; set; }
    public Guid? ContentNodeId { get; set; }
    public string Mode { get; set; } = "chapter";
    public string? TargetType { get; set; }
    public Guid? TargetId { get; set; }
    public DateTimeOffset StartedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? FinishedAt { get; set; }
    public int QuestionCount { get; set; }
    public int? DurationMinutes { get; set; }
    public decimal? TotalScore { get; set; }
    public DateTimeOffset? ExpiresAt { get; set; }
    public PracticeSessionStatus Status { get; set; } = PracticeSessionStatus.Active;
    public long Version { get; set; } = 1;
    public long LastClientSequence { get; set; }
    public PracticeAccessMode AccessMode { get; set; } = PracticeAccessMode.Free;
    public Guid? AccessEntitlementId { get; set; }
    public int ConsumedFreeQuota { get; set; }
    public JsonElement AccessSnapshot { get; set; } = JsonDefaults.Object();
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class PracticeSessionQuestion : TenantEntity
{
    public Guid PracticeSessionId { get; set; }
    public Guid QuestionReferenceId { get; set; }
    public Guid QuestionOwnerTenantId { get; set; }
    public Guid QuestionId { get; set; }
    public Guid QuestionVersionId { get; set; }
    public int Position { get; set; }
    public decimal? Score { get; set; }
    public string QuestionType { get; set; } = "choice";
    public string? TypeLabelSnapshot { get; set; }
    public int? DifficultySnapshot { get; set; }
    public JsonElement TagsSnapshot { get; set; } = JsonDefaults.Array();
    public string? ContentSnapshot { get; set; }
    public JsonElement OptionsSnapshot { get; set; } = JsonDefaults.Array();
    public int? CorrectOptionIndexSnapshot { get; set; }
    public JsonElement CorrectOptionIndicesSnapshot { get; set; } = JsonDefaults.Array();
    public string? AnswerTextSnapshot { get; set; }
    public string? ExplanationSnapshot { get; set; }
    public JsonElement GradingRulesSnapshot { get; set; } = JsonDefaults.Object();
    public int SnapshotVersion { get; set; } = 1;
}

public enum PracticeSessionStatus
{
    Active,
    Scoring,
    PendingReview,
    Submitted,
    Expired,
    Cancelled
}

public enum PracticeAccessMode
{
    Free,
    Svip,
    Staff
}

public sealed class AnswerRecord : TenantEntity
{
    public Guid UserId { get; set; }
    public Guid PracticeSessionId { get; set; }
    public Guid SessionQuestionId { get; set; }
    public string? LegacyId { get; set; }
    public string? LegacyQuestionId { get; set; }
    public string? LegacyCategoryId { get; set; }
    public JsonElement SelectedOptions { get; set; } = JsonDefaults.Array();
    public string? AnswerText { get; set; }
    public bool? IsCorrect { get; set; }
    public AnswerGradingStatus GradingStatus { get; set; } = AnswerGradingStatus.PendingReview;
    public decimal? AwardedScore { get; set; }
    public int Revision { get; set; } = 1;
    public long ClientSequence { get; set; }
    public string IdempotencyKey { get; set; } = string.Empty;
    public string RequestHash { get; set; } = string.Empty;
    public bool IsCurrent { get; set; } = true;
    public DateTimeOffset AnsweredAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public enum AnswerGradingStatus
{
    PendingReview,
    Correct,
    Incorrect,
    LegacyUnverified
}

public sealed class LearningOperationIdempotency : Entity, ITenantOwned
{
    public Guid UserId { get; set; }
    public Guid PracticeSessionId { get; set; }
    public string OperationType { get; set; } = string.Empty;
    public string IdempotencyKey { get; set; } = string.Empty;
    public string RequestHash { get; set; } = string.Empty;
    public JsonElement ResponseSnapshot { get; set; } = JsonDefaults.Object();
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? CompletedAt { get; set; }
    public Guid TenantId { get; set; }
}

public sealed class FavoriteQuestion : ITenantOwned
{
    public Guid UserId { get; set; }
    public Guid QuestionReferenceId { get; set; }
    public Guid QuestionOwnerTenantId { get; set; }
    public Guid QuestionId { get; set; }
    public string Source { get; set; } = "imported";
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public sealed class WrongQuestion : ITenantOwned
{
    public Guid UserId { get; set; }
    public Guid QuestionReferenceId { get; set; }
    public Guid QuestionOwnerTenantId { get; set; }
    public Guid QuestionId { get; set; }
    public int WrongCount { get; set; } = 1;
    public DateTimeOffset LastWrongAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? ResolvedAt { get; set; }
    public Guid TenantId { get; set; }
}

public sealed class RecentPractice : AuditableTenantEntity
{
    public Guid? UserId { get; set; }
    public string? LegacyId { get; set; }
    public string? PracticeType { get; set; }
    public string? TargetLegacyId { get; set; }
    public string? TargetName { get; set; }
    public int Progress { get; set; }
    public string? Color { get; set; }
    public DateTimeOffset? LastAccessAt { get; set; }
    public DateTimeOffset? LastPracticeAt { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}