"""CLI mode implementations: manual, auto, and suggest frame selection."""

import argparse
import os
import sys

from .crop_selector import CROP_POSITIONS, select_crop_with_ai
from .extractor import extract_single_frame_highres
from .ai_selector import select_frame_with_ai
from .utils import open_image
from .cli_helpers import (
    EXIT_SUCCESS,
    EXIT_ERROR,
    EXIT_NO_SELECTION,
    EXIT_AI_FAILED,
    _finalize_frame,
)


def _ask_crop_position_manual(highres_path: str) -> str:
    """Show the frame and prompt the user for a crop position."""
    open_image(highres_path)
    positions_str = " / ".join(CROP_POSITIONS)
    try:
        raw = input(f"\n   Crop-Position wählen [{positions_str}]: ").strip().lower()
    except (EOFError, KeyboardInterrupt):
        return "center"
    return raw if raw in CROP_POSITIONS else "center"


def _run_manual(args: argparse.Namespace, frame_paths: list, mosaic_path: str, tmpdir: str) -> int:
    print("   🖼️  Mosaikbild geöffnet in Vorschau.", file=sys.stderr)
    open_image(mosaic_path)

    try:
        raw = input("\n   Wähle Frame 0–19 oder [ENTER] zum Abbrechen: ").strip()
    except (EOFError, KeyboardInterrupt):
        print("\n   Abgebrochen.", file=sys.stderr)
        return EXIT_NO_SELECTION

    if raw == "":
        print("   Keine Auswahl getroffen.", file=sys.stderr)
        return EXIT_NO_SELECTION

    try:
        frame_index = int(raw)
        if not (0 <= frame_index <= 19):
            raise ValueError
    except ValueError:
        print(f"   Ungültige Eingabe: '{raw}'. Bitte Zahl 0–19 eingeben.", file=sys.stderr)
        return EXIT_ERROR

    highres_path = os.path.join(tmpdir, "highres.jpg")
    try:
        extract_single_frame_highres(
            args.input_path, frame_index, highres_path,
            ffmpeg=args.ffmpeg_bin, ffprobe=args.ffprobe_bin
        )
    except Exception as exc:
        print(f"   Error extracting high-res frame: {exc}", file=sys.stderr)
        return EXIT_ERROR

    crop_position = ""
    if args.format == "poster":
        cli_crop = getattr(args, "crop_position", None)
        if cli_crop:
            crop_position = cli_crop
            print(f"   ✅ Crop-Position (vorgegeben): {crop_position}", file=sys.stderr)
        else:
            crop_position = _ask_crop_position_manual(highres_path)

    return _finalize_frame(args, frame_index, "manual", "", highres_path, crop_position)


def _run_auto(args: argparse.Namespace, frame_paths: list, mosaic_path: str, tmpdir: str) -> int:
    api_key = args.claude_api_key
    if not api_key:
        print(
            "   Error: Claude API key required for auto mode. "
            "Set the CLAUDE_API_KEY env variable "
            "or run: video-thumbnail-creator config set claude.api_key <key>",
            file=sys.stderr,
        )
        return EXIT_AI_FAILED

    print("   🤖 K.I. analysiert Frames…", file=sys.stderr)
    try:
        frame_index, reasoning = select_frame_with_ai(
            mosaic_path,
            api_key=api_key,
            model=args.claude_model,
            description=args.description,
        )
    except RuntimeError as exc:
        print(f"   Error: {exc}", file=sys.stderr)
        return EXIT_AI_FAILED

    print(
        f'   ✅ K.I. Auswahl: Frame {frame_index} – "{reasoning}"',
        file=sys.stderr,
    )

    highres_path = os.path.join(tmpdir, "highres.jpg")
    try:
        extract_single_frame_highres(
            args.input_path, frame_index, highres_path,
            ffmpeg=args.ffmpeg_bin, ffprobe=args.ffprobe_bin
        )
    except Exception as exc:
        print(f"   Error extracting high-res frame: {exc}", file=sys.stderr)
        return EXIT_ERROR

    crop_position = ""
    if args.format == "poster":
        cli_crop = getattr(args, "crop_position", None)
        if cli_crop:
            crop_position = cli_crop
            print(f"   ✅ Crop-Position (vorgegeben): {crop_position}", file=sys.stderr)
        else:
            print("   🤖 K.I. bestimmt Crop-Position…", file=sys.stderr)
            try:
                crop_position, crop_reasoning = select_crop_with_ai(
                    highres_path, api_key=api_key, model=args.claude_model
                )
                reasoning = f"{reasoning} | Crop: {crop_reasoning}"
                print(
                    f'   ✅ Crop-Position: {crop_position} – "{crop_reasoning}"',
                    file=sys.stderr,
                )
            except RuntimeError as exc:
                print(f"   Error: {exc}", file=sys.stderr)
                return EXIT_AI_FAILED

    return _finalize_frame(args, frame_index, "auto", reasoning, highres_path, crop_position)


def _run_suggest(args: argparse.Namespace, frame_paths: list, mosaic_path: str, tmpdir: str) -> int:
    api_key = args.claude_api_key
    if not api_key:
        print(
            "   Error: Claude API key required for suggest mode. "
            "Set the CLAUDE_API_KEY env variable "
            "or run: video-thumbnail-creator config set claude.api_key <key>",
            file=sys.stderr,
        )
        return EXIT_AI_FAILED

    print("   🤖 K.I. analysiert Frames…", file=sys.stderr)
    try:
        ai_index, reasoning = select_frame_with_ai(
            mosaic_path,
            api_key=api_key,
            model=args.claude_model,
            description=args.description,
        )
    except RuntimeError as exc:
        print(f"   Error: {exc}", file=sys.stderr)
        return EXIT_AI_FAILED

    print(
        f'   🤖 K.I. Empfehlung: Frame {ai_index} – "{reasoning}"',
        file=sys.stderr,
    )
    print("   🖼️  Mosaikbild geöffnet in Vorschau.", file=sys.stderr)
    open_image(mosaic_path)

    try:
        raw = input(
            f"\n   [ENTER] = K.I.-Auswahl übernehmen (Frame {ai_index}), "
            "oder Zahl 0–19 eingeben: "
        ).strip()
    except (EOFError, KeyboardInterrupt):
        print("\n   Abgebrochen.", file=sys.stderr)
        return EXIT_NO_SELECTION

    if raw == "":
        frame_index = ai_index
        final_reasoning = reasoning
    else:
        try:
            frame_index = int(raw)
            if not (0 <= frame_index <= 19):
                raise ValueError
            final_reasoning = f"User overrode AI suggestion (AI: {ai_index})"
        except ValueError:
            print(
                f"   Ungültige Eingabe: '{raw}'. Bitte Zahl 0–19 eingeben.",
                file=sys.stderr,
            )
            return EXIT_ERROR

    highres_path = os.path.join(tmpdir, "highres.jpg")
    try:
        extract_single_frame_highres(
            args.input_path, frame_index, highres_path,
            ffmpeg=args.ffmpeg_bin, ffprobe=args.ffprobe_bin
        )
    except Exception as exc:
        print(f"   Error extracting high-res frame: {exc}", file=sys.stderr)
        return EXIT_ERROR

    crop_position = ""
    if args.format == "poster":
        cli_crop = getattr(args, "crop_position", None)
        if cli_crop:
            crop_position = cli_crop
            print(f"   ✅ Crop-Position (vorgegeben): {crop_position}", file=sys.stderr)
            final_reasoning = f"{final_reasoning} | Crop position provided via --crop-position."
        else:
            print("   🤖 K.I. bestimmt Crop-Position…", file=sys.stderr)
            try:
                ai_crop, crop_reasoning = select_crop_with_ai(
                    highres_path, api_key=api_key, model=args.claude_model
                )
                print(
                    f'   🤖 K.I. Crop-Empfehlung: {ai_crop} – "{crop_reasoning}"',
                    file=sys.stderr,
                )
            except RuntimeError as exc:
                print(f"   Error: {exc}", file=sys.stderr)
                return EXIT_AI_FAILED

            crop_position = _ask_crop_position_manual(highres_path)
            if not crop_position:
                crop_position = ai_crop

            if crop_position != ai_crop:
                final_reasoning = f"{final_reasoning} | Crop overridden by user (AI: {ai_crop})"
            else:
                final_reasoning = f"{final_reasoning} | Crop: {crop_reasoning}"

    return _finalize_frame(args, frame_index, "suggest", final_reasoning, highres_path, crop_position)
