"""Claude Code translation provider (uses Claude Agent SDK with subscription auth)."""

import asyncio
import json
import os

from transduck.providers.prompts import build_single_prompt, build_plural_single_prompt


def _ensure_token(config):
    token = os.environ.get(config.token_env)
    if not token:
        raise RuntimeError(
            f"Set {config.token_env} — run 'claude setup-token' to get your OAuth token"
        )


async def _translate_async(prompt):
    try:
        from claude_agent_sdk import query, ClaudeAgentOptions
    except ImportError:
        raise ImportError("Install the required package: pip install transduck[claude-code]")

    async for message in query(
        prompt=prompt,
        options=ClaudeAgentOptions(allowed_tools=[]),
    ):
        if hasattr(message, "result"):
            return message.result.strip()
    raise RuntimeError("No result from Claude Agent SDK")


def translate(source_text, source_lang, target_lang, project_context, string_context, config):
    """Translate a single string using Claude Code (Agent SDK)."""
    _ensure_token(config)
    prompt = build_single_prompt(source_text, source_lang, target_lang, project_context, string_context)
    return asyncio.run(_translate_async(prompt))


def detect_language(text, config):
    """Detect the language of a text string. Returns an uppercase ISO 639-1 code."""
    _ensure_token(config)
    prompt = "What language is this text written in? Return only the uppercase ISO 639-1 code.\n\n" + text
    raw = asyncio.run(_translate_async(prompt))
    return raw.strip().upper()


def translate_plural(one, other, source_lang, target_lang, project_context, string_context, config):
    """Translate plural forms using Claude Code (Agent SDK). Returns {category: translation}."""
    _ensure_token(config)
    prompt = build_plural_single_prompt(one, other, source_lang, target_lang, project_context, string_context)
    raw = asyncio.run(_translate_async(prompt))
    return json.loads(raw)


# --- Batch translation (one agent session per language) ---

supports_batch = True


def translate_batch(strings, source_lang, target_lang, project_context, config):
    """Translate multiple strings in a single Agent SDK session.

    Args:
        strings: list of dicts, each with 'text' and optional 'context'
        source_lang, target_lang, project_context, config: same as translate()

    Returns:
        dict mapping source text to translated text: {"Hello": "Hallo", "Book": "Buchen"}
    """
    _ensure_token(config)

    if not strings:
        return {}

    # Build a batch prompt
    lines = [
        f"You are a professional translator. Translate the following strings from {source_lang} to {target_lang}.",
        f"Return ONLY a JSON object mapping each source string to its translation.",
        f"Do NOT add quotation marks, brackets, or any wrapper characters that are not in the original.",
        f"Preserve any placeholders like {{name}}, {{count}}, %s, ${{value}} exactly as they appear.",
        f"Preserve brand names. Match the tone and formality of the original.",
        f"",
        f"Project context: {project_context}",
        f"",
        f"Strings to translate:",
    ]

    for i, entry in enumerate(strings, 1):
        ctx = f" (context: {entry['context']})" if entry.get('context') else ""
        lines.append(f'{i}. "{entry["text"]}"{ctx}')

    lines.append("")
    lines.append("Return ONLY valid JSON like: {\"Hello\": \"Hallo\", \"Book Now\": \"Jetzt buchen\"}")

    prompt = "\n".join(lines)
    raw = asyncio.run(_translate_async(prompt))

    # Parse JSON — handle markdown code blocks if the model wraps it
    raw = raw.strip()
    if raw.startswith("```"):
        raw = raw.split("\n", 1)[1] if "\n" in raw else raw[3:]
        if raw.endswith("```"):
            raw = raw[:-3]
        raw = raw.strip()

    return json.loads(raw)


def translate_plural_batch(plurals, source_lang, target_lang, project_context, config):
    """Translate multiple plural strings in a single Agent SDK session.

    Args:
        plurals: list of dicts, each with 'one', 'other', and optional 'context'

    Returns:
        list of dicts, each mapping CLDR categories to translations:
        [{"one": "1 Nacht", "other": "{count} Nächte"}, ...]
    """
    _ensure_token(config)

    if not plurals:
        return []

    lines = [
        f"You are a professional translator. For each plural string pair below, generate ALL CLDR plural forms needed in {target_lang}.",
        f"Return ONLY a JSON array, one object per input, each mapping plural categories to translated strings.",
        f"",
        f"CRITICAL: Placeholders like {{count}}, {{name}} are SOFTWARE VARIABLES. Include them exactly as written in EVERY form.",
        f"CLDR categories: zero, one, two, few, many, other. Only include categories {target_lang} actually uses.",
        f"",
        f"Project context: {project_context}",
        f"",
        f"Plural strings to translate:",
    ]

    for i, entry in enumerate(plurals, 1):
        ctx = f" (context: {entry['context']})" if entry.get('context') else ""
        lines.append(f'{i}. one: "{entry["one"]}", other: "{entry["other"]}"{ctx}')

    lines.append("")
    lines.append('Return ONLY valid JSON array like: [{"one": "{count} Nacht", "other": "{count} Nächte"}, ...]')

    prompt = "\n".join(lines)
    raw = asyncio.run(_translate_async(prompt))

    raw = raw.strip()
    if raw.startswith("```"):
        raw = raw.split("\n", 1)[1] if "\n" in raw else raw[3:]
        if raw.endswith("```"):
            raw = raw[:-3]
        raw = raw.strip()

    return json.loads(raw)
