"""Command-line interface for the translator module.

Provides argument parsing, CLI handlers, and the main entry point
for the offline translator using Argos Translate.
"""

from __future__ import annotations

import argparse
from pathlib import Path
import sys
from typing import TYPE_CHECKING

import python_pkg.word_frequency.translator as _trans

if TYPE_CHECKING:
    from collections.abc import Sequence

logger = __import__("logging").getLogger(__name__)


def _build_parser() -> argparse.ArgumentParser:
    """Build the argument parser for the translator CLI."""
    parser = argparse.ArgumentParser(
        description="Offline translator using Argos Translate.",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )

    action_group = parser.add_mutually_exclusive_group()
    action_group.add_argument(
        "--list-languages",
        "-l",
        action="store_true",
        help="List installed languages",
    )
    action_group.add_argument(
        "--list-available",
        "-L",
        action="store_true",
        help="List available language packages for download",
    )
    action_group.add_argument(
        "--download",
        "-d",
        nargs="+",
        metavar="LANG",
        help=("Download language packs (e.g., --download en es pl)"),
    )

    input_group = parser.add_mutually_exclusive_group()
    input_group.add_argument(
        "--text",
        "-t",
        type=str,
        help="Single text/word to translate",
    )
    input_group.add_argument(
        "--words",
        "-w",
        nargs="+",
        help="Words to translate",
    )
    input_group.add_argument(
        "--words-file",
        "-W",
        type=str,
        help="File with words to translate (one per line)",
    )

    parser.add_argument(
        "--from",
        "-f",
        dest="from_lang",
        type=str,
        default="en",
        help="Source language code (default: en)",
    )
    parser.add_argument(
        "--to",
        "-T",
        dest="to_lang",
        type=str,
        default="en",
        help="Target language code (default: en)",
    )
    parser.add_argument(
        "--output",
        "-o",
        type=str,
        help="Output file path",
    )

    return parser


def _handle_list_languages() -> int:
    """Handle --list-languages command."""
    langs = _trans.get_installed_languages()
    if not langs:
        sys.stdout.write("No languages installed.\n")
        sys.stdout.write(
            "Download some with: --download en es pl de fr\n",
        )
    else:
        sys.stdout.write("Installed languages:\n")
        for code, name in sorted(langs):
            sys.stdout.write(f"  {code}: {name}\n")
    return 0


def _handle_list_available() -> int:
    """Handle --list-available command."""
    packages = _trans.get_available_packages()
    if not packages:
        sys.stdout.write(
            "No packages available (check internet connection).\n",
        )
    else:
        sys.stdout.write("Available language packages:\n")
        for from_code, from_name, to_code, to_name in sorted(
            packages,
        ):
            sys.stdout.write(
                f"  {from_code} ({from_name}) -> {to_code} ({to_name})\n",
            )
    return 0


def _handle_download(lang_codes: list[str]) -> int:
    """Handle --download command."""
    download_results = _trans.download_languages(lang_codes)
    success_count = sum(1 for v in download_results.values() if v)
    sys.stdout.write(
        f"\nDownloaded {success_count}/{len(download_results)} language pairs.\n",
    )
    return 0 if success_count > 0 else 1


def _collect_words(
    args: argparse.Namespace,
) -> list[str] | None:
    """Collect words from args. Returns None on error."""
    if args.text:
        return [args.text]
    if args.words:
        return args.words
    if args.words_file:
        try:
            content = _trans.read_file(args.words_file)
        except FileNotFoundError:
            sys.stderr.write(
                f"Error: File not found: {args.words_file}\n",
            )
            return None
        return [w.strip() for w in content.splitlines() if w.strip()]
    return []


def _handle_translation(args: argparse.Namespace) -> int:
    """Handle the translation action."""
    try:
        results = _trans.translate_words_batch(
            args.words,
            args.from_lang,
            args.to_lang,
        )
    except ImportError:
        logger.exception("Translation import error")
        return 1

    output = _trans.format_translations(results)

    if args.output:
        Path(args.output).write_text(output, encoding="utf-8")
        sys.stdout.write(
            f"Translations written to {args.output}\n",
        )
    else:
        sys.stdout.write(output + "\n")

    if any(not r.success for r in results):
        return 1

    return 0


def main(argv: Sequence[str] | None = None) -> int:
    """Main entry point for the translator.

    Args:
        argv: Command line arguments.

    Returns:
        Exit code.
    """
    parser = _build_parser()
    args = parser.parse_args(argv)

    if not _trans.check_argos():
        sys.stderr.write(
            "Error: argostranslate is not installed.\n"
            "Install it with: pip install argostranslate\n",
        )
        return 1

    if args.list_languages:
        return _handle_list_languages()
    if args.list_available:
        return _handle_list_available()
    if args.download:
        return _handle_download(args.download)

    words = _collect_words(args)
    if not words:
        if words is not None:
            parser.print_help()
        return 1

    args.words = words
    return _handle_translation(args)
