from __future__ import annotations

import typer

from flow_xhs.contracts.command_inputs import PublishNoteInput
from flow_xhs.cli.spec.runtime_contracts import emit_command_help_if_empty
from flow_xhs.services.publish_note import execute_publish_note
from flow_xhs.cli.context import CliContext
from flow_xhs.cli.runtime import run_async_command
from flow_xhs.cli.utils import load_json_input, parse_csv, pick_cli_or_input, resolve_account_uid


def run_publish_command(
    *,
    ctx: typer.Context,
    command_name: str,
    target: str | None,
    image_list: str | None,
    video: str | None,
    title: str | None,
    content: str | None,
    tags: str | None,
    schedule_at: str | None,
    input_file: str | None,
) -> None:
    """
    发布内容（图文/视频）。

    参数优先级：显式 CLI 参数 > --input JSON > 默认值。
    """
    emit_command_help_if_empty(ctx, ("note", "publish"))

    cli_ctx: CliContext = ctx.obj
    payload = load_json_input(input_file)
    resolved_account_uid: str | None = None

    async def _run():
        nonlocal resolved_account_uid
        resolved_account_uid = resolve_account_uid()

        resolved_target = pick_cli_or_input(
            ctx=ctx,
            param_name="target",
            cli_value=target,
            payload=payload,
            payload_key="target",
        )

        image_source = pick_cli_or_input(
            ctx=ctx,
            param_name="image_list",
            cli_value=image_list,
            payload=payload,
            payload_key="image_list",
        )
        if isinstance(image_source, list):
            raw_images = image_source
        else:
            raw_images = parse_csv(image_source)

        normalized_video = pick_cli_or_input(
            ctx=ctx,
            param_name="video",
            cli_value=video,
            payload=payload,
            payload_key="video",
        )

        tags_source = pick_cli_or_input(
            ctx=ctx,
            param_name="tags",
            cli_value=tags,
            payload=payload,
            payload_key="tags",
        )
        if isinstance(tags_source, list):
            normalized_tags = tags_source
        else:
            normalized_tags = parse_csv(tags_source)

        validated = PublishNoteInput(
            target=resolved_target,
            image_list=raw_images,
            video=normalized_video,
            title=pick_cli_or_input(
                ctx=ctx,
                param_name="title",
                cli_value=title,
                payload=payload,
                payload_key="title",
            ),
            content=pick_cli_or_input(
                ctx=ctx,
                param_name="content",
                cli_value=content,
                payload=payload,
                payload_key="content",
            ),
            tags=normalized_tags,
            schedule_at=pick_cli_or_input(
                ctx=ctx,
                param_name="schedule_at",
                cli_value=schedule_at,
                payload=payload,
                payload_key="schedule_at",
            ),
            account_uid=resolved_account_uid,
        )
        target_text = validated.target.strip().lower()
        if target_text == "video":
            media_list = [validated.video] if validated.video else []
        elif target_text == "image":
            media_list = validated.image_list
        else:
            media_list = validated.image_list

        return await execute_publish_note(
            target=validated.target,
            image_list=media_list,
            title=validated.title,
            content=validated.content,
            tags=validated.tags,
            schedule_at=validated.schedule_at,
            account_uid=validated.account_uid,
        )

    run_async_command(
        ctx=cli_ctx,
        command=command_name,
        func=_run,
        account_uid=lambda: resolved_account_uid,
    )
