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

namespace Tiku.Domain.Learning;

public sealed class ExamDate : AuditableTenantEntity
{
    public Guid? RegionId { get; set; }
    public Guid? SchoolId { get; set; }
    public string? LegacyId { get; set; }
    public string ExamName { get; set; } = string.Empty;
    public DateTimeOffset? ExamAt { get; set; }
    public string? ExamType { get; set; }
    public string? Description { get; set; }
    public int SortOrder { get; set; }
    public bool IsActive { get; set; } = true;
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class Report : AuditableTenantEntity
{
    public Guid? QuestionId { get; set; }
    public Guid? UserId { get; set; }
    public Guid? HandledBy { get; set; }
    public string? LegacyId { get; set; }
    public ReportType? Type { get; set; }
    public string? Title { get; set; }
    public string? Category { get; set; }
    public string? Description { get; set; }
    public ReportStatus Status { get; set; } = ReportStatus.Pending;
    public ReportPriority Priority { get; set; } = ReportPriority.Normal;
    public DateTimeOffset? HandledAt { get; set; }
    public string? Resolution { get; set; }
    public string? Contact { get; set; }
    public JsonElement Attachments { get; set; } = JsonDefaults.Array();
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class ReportStatusEvent : Entity, ITenantOwned
{
    public Guid ReportId { get; set; }
    public ReportStatus? FromStatus { get; set; }
    public ReportStatus ToStatus { get; set; } = ReportStatus.Pending;
    public string? Note { get; set; }
    public Guid? ActorUserId { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public sealed class UserScoreEvent : Entity, ITenantOwned
{
    public Guid UserId { get; set; }
    public UserScoreEventType EventType { get; set; } = UserScoreEventType.ManualAdjust;
    public int Points { get; set; }
    public int BalanceAfter { get; set; }
    public string? SourceType { get; set; }
    public Guid? SourceId { get; set; }
    public string? IdempotencyKey { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public sealed class PracticeDailyUsage : AuditableTenantEntity
{
    public Guid UserId { get; set; }
    public DateOnly UsageDate { get; set; } = DateOnly.FromDateTime(DateTime.UtcNow);
    public PracticeUsageScopeType ScopeType { get; set; } = PracticeUsageScopeType.Tenant;
    public Guid? ScopeId { get; set; }
    public int FreeLimit { get; set; } = 25;
    public int UsedCount { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class PracticeAccessEvent : Entity, ITenantOwned
{
    public Guid? UserId { get; set; }
    public Guid? PracticeSessionId { get; set; }
    public PracticeAccessEventType EventType { get; set; } = PracticeAccessEventType.SessionCreated;
    public PracticeAccessEventMode AccessMode { get; set; } = PracticeAccessEventMode.Free;
    public int RequestedCount { get; set; }
    public int GrantedCount { get; set; }
    public int ConsumedFreeQuota { get; set; }
    public string? Reason { get; set; }
    public PracticeUsageScopeType? ScopeType { get; set; }
    public Guid? ScopeId { get; set; }
    public Guid? EntitlementId { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public Guid TenantId { get; set; }
}

public sealed class PracticeSessionReport : AuditableTenantEntity
{
    public Guid UserId { get; set; }
    public Guid PracticeSessionId { get; set; }
    public Guid? BlueprintId { get; set; }
    public Guid? CollectionId { get; set; }
    public string Mode { get; set; } = "mock_exam";
    public int TotalQuestions { get; set; }
    public int AnsweredCount { get; set; }
    public int CorrectCount { get; set; }
    public int WrongCount { get; set; }
    public int UnansweredCount { get; set; }
    public decimal Score { get; set; }
    public decimal TotalScore { get; set; }
    public decimal Accuracy { get; set; }
    public int DurationSeconds { get; set; }
    public DateTimeOffset? StartedAt { get; set; }
    public DateTimeOffset SubmittedAt { get; set; } = DateTimeOffset.UtcNow;
    public PracticeReportStatus Status { get; set; } = PracticeReportStatus.Final;
    public int Version { get; set; } = 1;
    public bool IsFinal { get; set; } = true;
    public int PendingReviewCount { get; set; }
    public int ScoringVersion { get; set; } = 1;
    public JsonElement SectionStats { get; set; } = JsonDefaults.Array();
    public JsonElement QuestionResults { get; set; } = JsonDefaults.Array();
    public JsonElement WrongQuestionIds { get; set; } = JsonDefaults.Array();
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public enum PracticeReportStatus
{
    Final,
    PendingReview,
    LegacyUnverified
}

public sealed class PracticeSessionReportSection : AuditableTenantEntity
{
    public Guid ReportId { get; set; }
    public Guid PracticeSessionId { get; set; }
    public string SectionKey { get; set; } = string.Empty;
    public string? SectionName { get; set; }
    public string? QuestionType { get; set; }
    public int QuestionCount { get; set; }
    public int AnsweredCount { get; set; }
    public int CorrectCount { get; set; }
    public int WrongCount { get; set; }
    public int UnansweredCount { get; set; }
    public decimal Score { get; set; }
    public decimal TotalScore { get; set; }
    public decimal Accuracy { get; set; }
    public int SortOrder { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class DashboardDailyStat : AuditableTenantEntity
{
    public Guid? RegionId { get; set; }
    public string? LegacyId { get; set; }
    public string? LegacyRegionId { get; set; }
    public DateOnly StatDate { get; set; }
    public int NewUsers { get; set; }
    public int NewQuestions { get; set; }
    public int NewOrders { get; set; }
    public int NewRevenueCents { get; set; }
    public int ActiveUsers { get; set; }
    public DateTimeOffset? RebuiltAt { get; set; }
}

public sealed class RevenueDailyStat : AuditableTenantEntity
{
    public Guid? RegionId { get; set; }
    public string? LegacyId { get; set; }
    public string? LegacyRegionId { get; set; }
    public DateOnly StatDate { get; set; }
    public string? SaleType { get; set; }
    public int RealRevenueCents { get; set; }
    public int OrderCount { get; set; }
    public int CodeCount { get; set; }
    public int CodeUsed { get; set; }
    public int CodeEstimated { get; set; }
    public int EstimatedRevenueCents { get; set; }
    public DateTimeOffset? RebuiltAt { get; set; }
}

public enum ReportType
{
    QuestionError,
    ContentError,
    VideoError,
    AssetError,
    SystemBug,
    Suggestion,
    Other
}

public enum ReportStatus
{
    Pending,
    Accepted,
    Rejected,
    Resolved,
    Closed
}

public enum ReportPriority
{
    Low,
    Normal,
    High,
    Urgent
}

public enum UserScoreEventType
{
    CheckIn,
    ManualAdjust,
    FeedbackReward,
    ActivityReward,
    RedeemCost
}

public enum PracticeUsageScopeType
{
    Tenant,
    Region,
    Subject,
    QuestionBank,
    ContentEntry,
    ContentNode,
    Collection,
    Blueprint
}

public enum PracticeAccessEventType
{
    SessionCreated,
    SessionDenied,
    QuotaConsumed
}

public enum PracticeAccessEventMode
{
    Free,
    Svip,
    Staff,
    Denied
}