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

namespace Tiku.Application.Content;

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

public sealed record AdminLimitFilter(
    Guid? RegionId = null,
    Guid? EntryId = null,
    Guid? ContentNodeId = null,
    Guid? ParentId = null,
    Guid? SubjectId = null,
    Guid? ChapterId = null,
    Guid? UnitId = null,
    Guid? SchoolId = null,
    Guid? MajorId = null,
    Guid? QuestionId = null,
    string? Status = null,
    string? Keyword = null,
    int? Year = null,
    int? Limit = null);

public sealed record QuestionWriteCommand(
    Guid? QuestionId,
    Guid? QuestionBankId,
    Guid? SubjectId,
    Guid? CategoryId,
    Guid? NodeId,
    Guid? EntryId,
    Guid? ContentNodeId,
    Guid? PrimaryCollectionId,
    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,
    bool CreateVersion);

public sealed record QuestionManagementItem(
    Guid Id,
    Guid? VersionId,
    Guid? QuestionBankId,
    Guid? SubjectId,
    Guid? CategoryId,
    Guid? NodeId,
    Guid? EntryId,
    Guid? ContentNodeId,
    Guid? PrimaryCollectionId,
    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,
    bool HasVideoExplanation,
    QuestionStatus Status);

public sealed record VocabularyUnitCommand(
    Guid? Id,
    Guid? RegionId,
    Guid? EntryId,
    Guid? ContentNodeId,
    string? LegacyId,
    string Name,
    string? Description,
    int? WordCount,
    int? Order,
    bool? IsActive,
    JsonElement Metadata);

public sealed record VocabularyWordCommand(
    Guid? Id,
    Guid? UnitId,
    Guid? EntryId,
    Guid? ContentNodeId,
    string? LegacyId,
    string Word,
    string? Phonetic,
    string? Meaning,
    string? Example,
    string? ExampleTranslation,
    int? Difficulty,
    JsonElement Tags,
    int? Order,
    bool? IsActive,
    JsonElement Metadata);

public sealed record HandbookSubjectCommand(
    Guid? Id,
    Guid? RegionId,
    Guid? SchoolId,
    Guid? MajorId,
    Guid? EntryId,
    Guid? ContentNodeId,
    string? LegacyId,
    string Name,
    string? Type,
    string? Icon,
    string? Color,
    string? Description,
    int? Order,
    bool? IsActive,
    JsonElement Metadata);

public sealed record HandbookChapterCommand(
    Guid? Id,
    Guid? SubjectId,
    Guid? EntryId,
    Guid? ContentNodeId,
    string? LegacyId,
    string Name,
    string? Description,
    int? Order,
    bool? IsActive,
    JsonElement Metadata);

public sealed record HandbookEntryCommand(
    Guid? Id,
    Guid? ChapterId,
    Guid? EntryId,
    Guid? ContentNodeId,
    string? LegacyId,
    string Title,
    string? Summary,
    string? Content,
    JsonElement Tags,
    int? Order,
    bool? IsActive,
    JsonElement Metadata);

public sealed record SchoolCommand(
    Guid? Id,
    Guid? RegionId,
    string? LegacyId,
    string Name,
    string? ProfessionalExamDate,
    JsonElement Metadata);

public sealed record MajorCommand(
    Guid? Id,
    Guid? RegionId,
    Guid? SchoolId,
    string? LegacyId,
    string Name,
    string? Description,
    string? StudyTips,
    int? Order,
    bool? IsActive);

public sealed record ScorelineFieldCommand(
    Guid? Id,
    Guid? RegionId,
    string? LegacyId,
    string FieldKey,
    string FieldName,
    string? FieldType,
    string? Unit,
    bool? IsFilter,
    bool? IsRequired,
    bool? IsVisible,
    bool? IsTrend,
    JsonElement Options,
    string? Placeholder,
    string? Description,
    int? Order);

public sealed record ScorelineRecordCommand(
    Guid? Id,
    Guid? RegionId,
    Guid? SchoolId,
    Guid? MajorId,
    string? LegacyId,
    int Year,
    string? SchoolName,
    string? MajorName,
    JsonElement FieldValues);

public sealed record VideoExplanationCommand(
    Guid? Id,
    Guid? SubjectId,
    string? LegacyId,
    string Title,
    string? Description,
    string? VideoUrl,
    string? ThumbnailUrl,
    int? DurationSeconds,
    JsonElement KnowledgeTags,
    bool? IsGeneral,
    int? Difficulty,
    int? Order,
    bool? IsActive,
    JsonElement Metadata);

public sealed record QuestionVideoCommand(
    Guid QuestionId,
    Guid VideoId,
    string? LegacyId,
    string? VideoType,
    int? Order,
    JsonElement Metadata);

public sealed record OperationContentCommand(
    Guid? Id,
    Guid? RegionId,
    Guid? SchoolId,
    string? LegacyId,
    string? Title,
    string? Subtitle,
    string? Content,
    string? Question,
    string? Answer,
    string? Link,
    string? ButtonText,
    string? ButtonLink,
    string? BackgroundColor,
    string? BorderColor,
    string? ExamName,
    DateTimeOffset? ExamAt,
    string? ExamType,
    string? Description,
    int? Order,
    bool? IsActive,
    JsonElement Metadata);

public sealed record SimpleImportCommand(
    string ImportType,
    string? SourceFormat,
    string? SourceName,
    Guid? RegionId,
    Guid? EntryId,
    Guid? ContentNodeId,
    Guid? SubjectId,
    Guid? CategoryId,
    Guid? QuestionBankId,
    Guid? CollectionId,
    IReadOnlyCollection<JsonElement> Items,
    bool DryRun);

public sealed record SimpleImportResult(
    ContentImportJobItem Job,
    IReadOnlyCollection<ContentImportItemModel> Items,
    IReadOnlyCollection<ContentImportIssueModel> Issues);

public sealed record ImportPostCheckResult(
    Guid JobId,
    string Status,
    JsonElement Counts,
    IReadOnlyCollection<ContentImportIssueModel> Issues);

public sealed record VideoManagementItem(
    Guid Id,
    Guid? SubjectId,
    string? LegacyId,
    string Title,
    string? Description,
    string? VideoUrl,
    string? ThumbnailUrl,
    int? DurationSeconds,
    JsonElement KnowledgeTags,
    bool IsGeneral,
    int? Difficulty,
    int Order,
    bool IsActive,
    JsonElement Metadata);

public sealed record QuestionVideoManagementItem(
    Guid Id,
    Guid? QuestionId,
    Guid? VideoId,
    string? LegacyId,
    QuestionVideoType VideoType,
    int Order,
    JsonElement Metadata);

public sealed record OperationContentItem(
    Guid Id,
    string Kind,
    Guid? RegionId,
    Guid? SchoolId,
    string? LegacyId,
    string? Title,
    string? Content,
    string? Question,
    string? Answer,
    DateTimeOffset? ExamAt,
    string? ExamType,
    int Order,
    bool IsActive,
    JsonElement Metadata);

public sealed record ScorelineTrendItem(int Year, int SchoolCount, int MajorCount);

public interface IDirectContentService
{
    Task<ContentManagementResult<QuestionManagementItem>> CreateQuestionAsync(DirectContentActor actor,
        QuestionWriteCommand command, CancellationToken cancellationToken = default);

    Task<ContentManagementResult<QuestionManagementItem>> UpdateQuestionAsync(DirectContentActor actor,
        QuestionWriteCommand command, CancellationToken cancellationToken = default);

    Task<CatalogList<VocabularyUnit>> GetVocabularyUnitsAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<VocabularyUnit>> UpsertVocabularyUnitAsync(DirectContentActor actor,
        VocabularyUnitCommand command, CancellationToken cancellationToken = default);

    Task<CatalogList<VocabularyWord>> GetVocabularyWordsAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<VocabularyWord>> UpsertVocabularyWordAsync(DirectContentActor actor,
        VocabularyWordCommand command, CancellationToken cancellationToken = default);

    Task<CatalogList<HandbookSubject>> GetHandbookSubjectsAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<HandbookSubject>> UpsertHandbookSubjectAsync(DirectContentActor actor,
        HandbookSubjectCommand command, CancellationToken cancellationToken = default);

    Task<CatalogList<HandbookChapter>> GetHandbookChaptersAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<HandbookChapter>> UpsertHandbookChapterAsync(DirectContentActor actor,
        HandbookChapterCommand command, CancellationToken cancellationToken = default);

    Task<CatalogList<HandbookEntry>> GetHandbookEntriesAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<HandbookEntry>> UpsertHandbookEntryAsync(DirectContentActor actor,
        HandbookEntryCommand command, CancellationToken cancellationToken = default);

    Task<CatalogList<School>> GetSchoolsAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<School>> UpsertSchoolAsync(DirectContentActor actor, SchoolCommand command,
        CancellationToken cancellationToken = default);

    Task<CatalogList<Major>> GetMajorsAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<Major>> UpsertMajorAsync(DirectContentActor actor, MajorCommand command,
        CancellationToken cancellationToken = default);

    Task<CatalogList<ScorelineField>> GetScorelineFieldsAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<ScorelineField>> UpsertScorelineFieldAsync(DirectContentActor actor,
        ScorelineFieldCommand command, CancellationToken cancellationToken = default);

    Task<CatalogList<ScorelineRecord>> GetScorelineRecordsAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<ScorelineRecord>> UpsertScorelineRecordAsync(DirectContentActor actor,
        ScorelineRecordCommand command, CancellationToken cancellationToken = default);

    Task<CatalogList<int>> GetScorelineYearsAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<CatalogList<ScorelineTrendItem>> GetScorelineTrendAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<CatalogList<VideoManagementItem>> GetVideosAsync(DirectContentActor actor, AdminLimitFilter filter,
        CancellationToken cancellationToken = default);

    Task<ContentManagementResult<VideoManagementItem>> UpsertVideoAsync(DirectContentActor actor,
        VideoExplanationCommand command, CancellationToken cancellationToken = default);

    Task<ContentManagementResult<QuestionVideoManagementItem>> BindQuestionVideoAsync(DirectContentActor actor,
        QuestionVideoCommand command, CancellationToken cancellationToken = default);

    Task<CatalogList<OperationContentItem>> GetOperationContentAsync(DirectContentActor actor, string kind,
        AdminLimitFilter filter, CancellationToken cancellationToken = default);

    Task<ContentManagementResult<OperationContentItem>> UpsertOperationContentAsync(DirectContentActor actor,
        string kind, OperationContentCommand command, CancellationToken cancellationToken = default);

    Task<SimpleImportResult> PreviewImportAsync(DirectContentActor actor, SimpleImportCommand command,
        CancellationToken cancellationToken = default);

    Task<SimpleImportResult> ExecuteImportAsync(DirectContentActor actor, SimpleImportCommand command,
        CancellationToken cancellationToken = default);

    Task<ContentImportJobDetail> GetImportJobAsync(DirectContentActor actor, Guid jobId,
        CancellationToken cancellationToken = default);

    Task<CatalogList<ContentImportIssueModel>> GetImportIssuesAsync(DirectContentActor actor, Guid jobId,
        CancellationToken cancellationToken = default);

    Task<ImportPostCheckResult> RunImportPostCheckAsync(DirectContentActor actor, Guid jobId,
        CancellationToken cancellationToken = default);

    Task<ImportPostCheckResult> GetImportPostCheckAsync(DirectContentActor actor, Guid jobId,
        CancellationToken cancellationToken = default);
}