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

namespace Tiku.Application.PlatformAdmin;

public sealed record PlatformQuestionBankFilter(
    Guid? QuestionBankId = null,
    Guid? ContentNodeId = null,
    string? Keyword = null,
    string? Type = null,
    int? Difficulty = null,
    string? Status = null,
    int Page = 1,
    int PageSize = 20);

public sealed record PlatformQuestionBankItem(
    Guid Id,
    Guid? ContentEntryId,
    string Name,
    QuestionBankStatus Status,
    int NodeCount,
    int QuestionCount,
    JsonElement Metadata,
    DateTimeOffset CreatedAt,
    DateTimeOffset? UpdatedAt);

public sealed record UpsertPlatformQuestionBankCommand(
    Guid? Id,
    string Name,
    JsonElement Metadata);

public sealed record PlatformQuestionBankNodeItem(
    Guid Id,
    Guid QuestionBankId,
    Guid EntryId,
    Guid? ParentId,
    string? NodeKey,
    string Name,
    ContentNodeType NodeType,
    int Depth,
    int SortOrder,
    bool IsActive,
    bool IsSelectable,
    bool IsLeaf,
    int QuestionCount,
    JsonElement Metadata);

public sealed record UpsertPlatformQuestionBankNodeCommand(
    Guid? Id,
    Guid QuestionBankId,
    Guid? ParentId,
    string? NodeKey,
    string Name,
    ContentNodeType NodeType,
    int SortOrder,
    bool IsSelectable,
    JsonElement Metadata);

public sealed record BatchCreatePlatformQuestionBankNodesCommand(
    Guid QuestionBankId,
    Guid? ParentId,
    ContentNodeType NodeType,
    IReadOnlyCollection<string> Names);

public sealed record PlatformQuestionItem(
    Guid Id,
    Guid? VersionId,
    Guid QuestionBankId,
    Guid EntryId,
    Guid ContentNodeId,
    string? LegacyId,
    string Type,
    string? TypeLabel,
    int? Difficulty,
    JsonElement Tags,
    string? Content,
    JsonElement Options,
    int? CorrectOptionIndex,
    JsonElement CorrectOptionIndices,
    string? AnswerText,
    string? Explanation,
    JsonElement SubQuestions,
    string? CodeLang,
    string? CodeTemplate,
    string? MediaUrl,
    QuestionStatus Status,
    int VersionNo,
    DateTimeOffset CreatedAt,
    DateTimeOffset? UpdatedAt);

public sealed record PlatformQuestionPage(
    IReadOnlyCollection<PlatformQuestionItem> Items,
    int Total,
    int Page,
    int PageSize);

public sealed record UpsertPlatformQuestionCommand(
    Guid? Id,
    Guid QuestionBankId,
    Guid ContentNodeId,
    string? LegacyId,
    string? Type,
    string? TypeLabel,
    int? Difficulty,
    JsonElement Tags,
    string? Content,
    JsonElement Options,
    int? CorrectOptionIndex,
    JsonElement CorrectOptionIndices,
    string? AnswerText,
    string? Explanation,
    JsonElement SubQuestions,
    string? CodeLang,
    string? CodeTemplate,
    string? MediaUrl,
    string? Status,
    JsonElement ExamMarkers,
    string? SourceHash);

public sealed record ArchivePlatformQuestionsCommand(IReadOnlyCollection<Guid> QuestionIds);

public sealed record PlatformQuestionImportCommand(
    Guid QuestionBankId,
    Guid? ContentNodeId,
    string Format,
    string? SourceName,
    JsonElement Payload);

public sealed record PlatformQuestionImportResult(
    ContentImportJobDetail Detail,
    int CreatedNodeCount,
    int InsertedQuestionCount,
    int UpdatedQuestionCount,
    int SkippedQuestionCount);

public interface IPlatformQuestionBankService
{
    Task<IReadOnlyCollection<PlatformQuestionBankItem>> GetBanksAsync(PlatformAdminActor actor, PlatformQuestionBankFilter filter, CancellationToken cancellationToken = default);
    Task<PlatformQuestionBankItem> UpsertBankAsync(PlatformAdminActor actor, UpsertPlatformQuestionBankCommand command, CancellationToken cancellationToken = default);
    Task<PlatformQuestionBankItem> ArchiveBankAsync(PlatformAdminActor actor, Guid bankId, CancellationToken cancellationToken = default);
    Task<IReadOnlyCollection<PlatformQuestionBankNodeItem>> GetNodesAsync(PlatformAdminActor actor, Guid bankId, CancellationToken cancellationToken = default);
    Task<PlatformQuestionBankNodeItem> UpsertNodeAsync(PlatformAdminActor actor, UpsertPlatformQuestionBankNodeCommand command, CancellationToken cancellationToken = default);
    Task<IReadOnlyCollection<PlatformQuestionBankNodeItem>> BatchCreateNodesAsync(PlatformAdminActor actor, BatchCreatePlatformQuestionBankNodesCommand command, CancellationToken cancellationToken = default);
    Task<PlatformQuestionBankNodeItem> ArchiveNodeAsync(PlatformAdminActor actor, Guid nodeId, CancellationToken cancellationToken = default);
    Task<PlatformQuestionPage> GetQuestionsAsync(PlatformAdminActor actor, PlatformQuestionBankFilter filter, CancellationToken cancellationToken = default);
    Task<PlatformQuestionItem> UpsertQuestionAsync(PlatformAdminActor actor, UpsertPlatformQuestionCommand command, CancellationToken cancellationToken = default);
    Task<int> ArchiveQuestionsAsync(PlatformAdminActor actor, ArchivePlatformQuestionsCommand command, CancellationToken cancellationToken = default);
    Task<PlatformQuestionImportResult> PreviewImportAsync(PlatformAdminActor actor, PlatformQuestionImportCommand command, CancellationToken cancellationToken = default);
    Task<PlatformQuestionImportResult> ExecuteImportAsync(PlatformAdminActor actor, PlatformQuestionImportCommand command, CancellationToken cancellationToken = default);
    Task<ContentImportJobDetail> GetImportAsync(PlatformAdminActor actor, Guid jobId, CancellationToken cancellationToken = default);
    Task<AssetUploadSignResult> SignQuestionAssetUploadAsync(PlatformAdminActor actor, AssetUploadSignCommand command, CancellationToken cancellationToken = default);
    Task<AssetUploadConfirmResult> ConfirmQuestionAssetUploadAsync(PlatformAdminActor actor, AssetUploadConfirmCommand command, CancellationToken cancellationToken = default);
}
