using System.Text.Json;

namespace Tiku.Application.Profile;

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

public sealed record ProfileQuery(int? RecentLimit = null, int? Limit = null);

public sealed record ProfileScoreEventQuery(
    int? Limit = null,
    string? SourceType = null,
    DateTimeOffset? From = null,
    DateTimeOffset? To = null);

public sealed record UpdateProfileCommand(
    string? Name,
    string? AvatarPreset,
    Guid? RegionId,
    Guid? SelectedSchoolId,
    Guid? SelectedMajorId,
    JsonElement? Stats,
    JsonElement? Progress,
    JsonElement? ModuleSelections,
    JsonElement? RecentActivities);

public sealed record StudentProfileItem(
    Guid ProfileId,
    Guid UserId,
    string? Username,
    string? Phone,
    string? Email,
    string? Name,
    string AvatarPreset,
    string AvatarDisplayUrl,
    string PrimaryRole,
    int Score,
    Guid? RegionId,
    string? RegionName,
    Guid? SelectedSchoolId,
    string? SelectedSchoolName,
    Guid? SelectedMajorId,
    string? SelectedMajorName,
    int QuestionsAnsweredToday,
    int MasteredWordsCount,
    DateOnly? LastCheckInDate,
    JsonElement Stats,
    JsonElement Progress,
    JsonElement ModuleSelections,
    JsonElement RecentActivities,
    IReadOnlyCollection<RecentPracticeItem> RecentPractices,
    StudentMembershipItem Membership);

public sealed record RecentPracticeItem(
    Guid Id,
    string? PracticeType,
    string? TargetName,
    int Progress,
    DateTimeOffset? LastAccessAt,
    DateTimeOffset? LastPracticeAt);

public sealed record StudentMembershipItem(bool IsSvip, DateTimeOffset? ExpiresAt);

public sealed record ExamCountdownItem(
    Guid Id,
    string? LegacyId,
    Guid? RegionId,
    Guid? SchoolId,
    string ExamName,
    DateTimeOffset? ExamAt,
    string? ExamType,
    string? Description,
    JsonElement Metadata,
    int Order,
    bool IsActive,
    int? DaysLeft);

public sealed record ExamCountdownList(
    IReadOnlyCollection<ExamCountdownItem> Items,
    Guid? RegionId,
    Guid? SchoolId);

public sealed record ProfileNotificationQuery(string? Status = null, int? Limit = null);

public sealed record ProfileNotificationItem(
    Guid Id,
    string NotificationType,
    string Status,
    string Severity,
    string Title,
    string Message,
    string? ActionLabel,
    string? ActionPath,
    string? SourceType,
    Guid? SourceId,
    JsonElement Metadata,
    DateTimeOffset? ReadAt,
    DateTimeOffset CreatedAt);

public sealed record ProfileNotificationList(
    IReadOnlyCollection<ProfileNotificationItem> Items,
    IReadOnlyDictionary<string, int> Summary);

public sealed record UpdateNotificationStatusCommand(
    IReadOnlyCollection<Guid> NotificationIds,
    string? Status);

public sealed record BadgeQuery(bool IncludeLocked = false, string? Category = null, int? Limit = null);

public sealed record BadgeItem(
    Guid Id,
    string Name,
    string? Description,
    string? Category,
    string? IconUrl,
    int? Level,
    string? UnlockType,
    JsonElement ConditionExtra,
    bool IsUnlocked,
    DateTimeOffset? GrantedAt,
    string? Note,
    int Order);

public sealed record BadgeList(IReadOnlyCollection<BadgeItem> Items, int Total, int Unlocked, bool IncludeLocked);

public sealed record FeedbackQuery(string? Status = null, string? Type = null, int? Limit = null);

public sealed record FeedbackItem(
    Guid Id,
    Guid? QuestionId,
    string? Type,
    string? Title,
    string? Category,
    string? Description,
    string Status,
    string Priority,
    string? Contact,
    JsonElement Attachments,
    JsonElement Metadata,
    DateTimeOffset CreatedAt,
    DateTimeOffset UpdatedAt);

public sealed record SubmitFeedbackCommand(
    Guid? QuestionId,
    string? Type,
    string? Category,
    string? Title,
    string Description,
    string? Priority,
    string? Contact,
    JsonElement Attachments,
    JsonElement Metadata);

public sealed record CheckInResult(
    DateOnly CheckInDate,
    bool AlreadyCheckedIn,
    int Points,
    int BalanceAfter,
    Guid? ClaimId,
    Guid? ScoreEventId);

public sealed record ProfileScoreEventItem(
    Guid Id,
    string EventType,
    int Points,
    int BalanceAfter,
    string? SourceType,
    Guid? SourceId,
    JsonElement Metadata,
    DateTimeOffset CreatedAt);

public sealed record ProfileScoreEventList(IReadOnlyCollection<ProfileScoreEventItem> Items);

public interface IProfileService
{
    Task<StudentProfileItem> GetMeAsync(ProfileActor actor, ProfileQuery query,
        CancellationToken cancellationToken = default);

    Task<StudentProfileItem> UpdateMeAsync(ProfileActor actor, UpdateProfileCommand command,
        CancellationToken cancellationToken = default);

    Task<ExamCountdownList> GetExamCountdownsAsync(ProfileActor actor, ProfileQuery query,
        CancellationToken cancellationToken = default);

    Task<ProfileNotificationList> GetNotificationsAsync(ProfileActor actor, ProfileNotificationQuery query,
        CancellationToken cancellationToken = default);

    Task<ProfileNotificationList> UpdateNotificationStatusAsync(ProfileActor actor,
        UpdateNotificationStatusCommand command, CancellationToken cancellationToken = default);

    Task<BadgeList> GetBadgesAsync(ProfileActor actor, BadgeQuery query, CancellationToken cancellationToken = default);

    Task<IReadOnlyCollection<FeedbackItem>> GetFeedbacksAsync(ProfileActor actor, FeedbackQuery query,
        CancellationToken cancellationToken = default);

    Task<FeedbackItem> SubmitFeedbackAsync(ProfileActor actor, SubmitFeedbackCommand command,
        CancellationToken cancellationToken = default);

    Task<CheckInResult> CheckInAsync(ProfileActor actor, CancellationToken cancellationToken = default);

    Task<ProfileScoreEventList> GetScoreEventsAsync(ProfileActor actor, ProfileScoreEventQuery query,
        CancellationToken cancellationToken = default);
}