from __future__ import annotations

import typer

from flow_xhs.cli.commands.publish import run_publish_command
from flow_xhs.cli.commands.search import run_note_search
from flow_xhs.cli.spec.runtime_contracts import (
    command_description,
    command_option,
    emit_command_help_if_empty,
    emit_group_help_if_empty,
    group_summary,
)
from flow_xhs.contracts.command_inputs import NoteGetInput
from flow_xhs.services.note_get import execute_note_get
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, pick_cli_or_input, resolve_account_uid

app = typer.Typer(
    help=group_summary(("note",)),
    no_args_is_help=False,
    options_metavar="[OPTIONS]",
    subcommand_metavar="<COMMAND>",
)


def run_note_get_command(
    *,
    ctx: typer.Context,
    note_url: str | None,
    comment_size: int,
    sub_comment_size: int,
    input_file: str | None,
) -> None:
    emit_command_help_if_empty(ctx, ("note", "get"))

    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()
        validated = NoteGetInput(
            note_url=pick_cli_or_input(
                ctx=ctx,
                param_name="note_url",
                cli_value=note_url,
                payload=payload,
                payload_key="note_url",
            ),
            comment_size=pick_cli_or_input(
                ctx=ctx,
                param_name="comment_size",
                cli_value=comment_size,
                payload=payload,
                payload_key="comment_size",
            ),
            sub_comment_size=pick_cli_or_input(
                ctx=ctx,
                param_name="sub_comment_size",
                cli_value=sub_comment_size,
                payload=payload,
                payload_key="sub_comment_size",
            ),
            account_uid=resolved_account_uid,
        )
        return await execute_note_get(
            note_id=validated.note_id,
            xsec_token=validated.xsec_token,
            xsec_source=validated.xsec_source,
            comment_size=validated.comment_size,
            sub_comment_size=validated.sub_comment_size,
            account_uid=validated.account_uid,
        )

    run_async_command(
        ctx=cli_ctx,
        command="note.get",
        func=_run,
        account_uid=lambda: resolved_account_uid,
    )


@app.callback(invoke_without_command=True)
def note_group(ctx: typer.Context):
    if ctx.invoked_subcommand:
        return
    emit_group_help_if_empty(ctx, ("note",))


@app.command("get")
def note_get(
    ctx: typer.Context,
    note_url: str | None = command_option(("note", "get"), "note_url", None),
    comment_size: int = command_option(("note", "get"), "comment_size"),
    sub_comment_size: int = command_option(("note", "get"), "sub_comment_size"),
    input_file: str | None = command_option(("note", "get"), "input", None),
):
    """Canonical 路径：`flow-xhs note get`。"""
    run_note_get_command(
        ctx=ctx,
        note_url=note_url,
        comment_size=comment_size,
        sub_comment_size=sub_comment_size,
        input_file=input_file,
    )


note_get.__doc__ = command_description(("note", "get"))


@app.command("search")
def note_search(
    ctx: typer.Context,
    keyword: str | None = command_option(("note", "search"), "keyword", None),
    size: int | None = command_option(("note", "search"), "size"),
    sort_by: str | None = command_option(("note", "search"), "sort_by", None),
    note_type: str | None = command_option(("note", "search"), "note_type", None),
    publish_time: str | None = command_option(("note", "search"), "publish_time", None),
    search_scope: str | None = command_option(("note", "search"), "search_scope", None),
    location: str | None = command_option(("note", "search"), "location", None),
    input_file: str | None = command_option(("note", "search"), "input", None),
):
    run_note_search(
        ctx=ctx,
        keyword=keyword,
        size=size,
        sort_by=sort_by,
        note_type=note_type,
        publish_time=publish_time,
        search_scope=search_scope,
        location=location,
        input_file=input_file,
    )


note_search.__doc__ = command_description(("note", "search"))


@app.command("publish")
def note_publish(
    ctx: typer.Context,
    target: str | None = command_option(("note", "publish"), "target", None),
    image_list: str | None = command_option(("note", "publish"), "image_list", None),
    video: str | None = command_option(("note", "publish"), "video", None),
    title: str | None = command_option(("note", "publish"), "title", None),
    content: str | None = command_option(("note", "publish"), "content", None),
    tags: str | None = command_option(("note", "publish"), "tags", None),
    schedule_at: str | None = command_option(("note", "publish"), "schedule_at", None),
    input_file: str | None = command_option(("note", "publish"), "input", None),
):
    """Canonical 路径：`flow-xhs note publish`。"""
    run_publish_command(
        ctx=ctx,
        command_name="note.publish",
        target=target,
        image_list=image_list,
        video=video,
        title=title,
        content=content,
        tags=tags,
        schedule_at=schedule_at,
        input_file=input_file,
    )
