using System.Text.Json;
using Tiku.Application.Catalog;

namespace Tiku.Application.Assets;

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

public sealed record VideoSearchQuery(
    string? Keyword = null,
    Guid? SubjectId = null,
    int? Limit = null);

public sealed record QuestionVideoQuery(
    Guid? QuestionId = null,
    IReadOnlyCollection<Guid>? QuestionIds = null,
    int? Limit = null);

public sealed record VideoPlayCommand(Guid VideoId, Guid? QuestionId = null);

public sealed record VideoProgressCommand(
    Guid VideoId,
    Guid? QuestionId,
    int PositionSeconds,
    int? DurationSeconds,
    int? WatchedSeconds,
    bool? IsCompleted,
    JsonElement Metadata);

public sealed record VideoPlaybackItem(
    Guid VideoId,
    Guid? QuestionId,
    string Title,
    string? Description,
    string? PlayUrl,
    string? ThumbnailUrl,
    int? DurationSeconds,
    VideoProgressItem? Progress,
    JsonElement Metadata);

public sealed record VideoProgressItem(
    Guid Id,
    Guid VideoId,
    Guid? QuestionId,
    int PositionSeconds,
    int? DurationSeconds,
    int WatchedSeconds,
    bool IsCompleted,
    DateTimeOffset? CompletedAt,
    DateTimeOffset LastPlayedAt,
    int PlayCount,
    JsonElement Metadata);

public interface IVideoPlaybackService
{
    Task<CatalogList<VideoExplanationCatalogItem>> SearchAsync(
        VideoPlaybackActor actor,
        VideoSearchQuery query,
        CancellationToken cancellationToken = default);

    Task<VideoPlaybackItem> PlayAsync(
        VideoPlaybackActor actor,
        VideoPlayCommand command,
        CancellationToken cancellationToken = default);

    Task<VideoProgressItem> ReportProgressAsync(
        VideoPlaybackActor actor,
        VideoProgressCommand command,
        CancellationToken cancellationToken = default);

    Task<CatalogList<QuestionVideoCatalogItem>> GetQuestionVideosAsync(
        VideoPlaybackActor actor,
        QuestionVideoQuery query,
        CancellationToken cancellationToken = default);
}

public sealed class VideoPlaybackException(string message, string code) : Exception(message)
{
    public string Code { get; } = code;
}