"""Small async helpers shared by tests."""

from __future__ import annotations

import uuid
from datetime import timedelta

from app.context import AppContext
from app.database.base import utcnow
from app.database.models import MediaStatus, Post, PublishChannel
from app.services.media_service import IncomingMedia, IngestResult


async def add_source(ctx: AppContext, chat_id: int = -100_100_100) -> int:
    source, _ = await ctx.repos.media.add_source(
        chat_id,
        title="Test Source",
        chat_type="supergroup",
        added_by=111_000_001,
    )
    return source.id


async def ingest(
    ctx: AppContext,
    incoming: IncomingMedia,
    *,
    register_source: bool = True,
) -> IngestResult:
    if register_source:
        await add_source(ctx, incoming.chat_id)
    return await ctx.media.ingest(incoming)


async def add_channel(
    ctx: AppContext,
    chat_id: int = -100_200_200,
    *,
    title: str = "Test Channel",
    default: bool = True,
) -> PublishChannel:
    channel, _ = await ctx.repos.channels.add(
        chat_id,
        title=title,
        username=None,
        chat_type="channel",
        added_by=111_000_001,
        can_post=True,
    )
    if default:
        await ctx.repos.channels.set_default(channel.id)
    return channel


async def create_ready_post(
    ctx: AppContext,
    *,
    channel_ids: list[int] | None = None,
    title: str = "Test video",
    description: str = "Description",
) -> Post:
    if channel_ids is None:
        channel = await add_channel(ctx)
        channel_ids = [channel.id]
    suffix = uuid.uuid4().hex
    media = await ctx.repos.media.add(
        source_chat_id=await add_source(ctx),
        source_message_id=int(suffix[:12], 16),
        file_id=f"post-file-id-{suffix}",
        file_unique_id=f"post-file-unique-{suffix}",
        media_type="video",
        mime_type="video/mp4",
        file_name="post.mp4",
        file_size=2048,
        duration_seconds=30,
        width=1280,
        height=720,
        thumbnail_file_id="post-thumb",
        original_caption="Original",
        status=MediaStatus.READY,
    )
    post = await ctx.posts.create_from_media(media.id, 111_000_001)
    await ctx.posts.set_title(post.id, title)
    await ctx.posts.set_description(post.id, description)
    await ctx.posts.set_destinations(post.id, channel_ids)
    await ctx.posts.prepare(post.id)
    return await ctx.repos.posts.get(post.id)  # type: ignore[return-value]


async def publish_post(ctx: AppContext, post_id: int) -> Post:
    await ctx.publishing.publish(post_id, actor_id=111_000_001)
    return await ctx.repos.posts.get(post_id)  # type: ignore[return-value]


def seconds_from_now(seconds: int):
    return utcnow() + timedelta(seconds=seconds)
