"""
Tests pour l'interface en ligne de commande.
"""

import pytest
import subprocess
import sys
from pathlib import Path

# Chemin vers main.py
MAIN_PY = Path(__file__).parent.parent / "main.py"


def run_cli(*args, stdin_input=None):
    """Exécute main.py avec les arguments donnés et une entrée stdin optionnelle."""
    result = subprocess.run(
        [sys.executable, str(MAIN_PY)] + list(args),
        capture_output=True,
        text=True,
        encoding="utf-8",
        input=stdin_input,
    )
    return result


class TestCLI:
    """Tests de l'interface en ligne de commande."""

    def test_conversion_simple(self):
        """8.1 - Conversion simple."""
        result = run_cli("12.5", "m")
        assert result.returncode == 0
        assert "Longueurs" in result.stdout

    def test_virgule_francaise(self):
        """8.2 - Virgule française acceptée."""
        result = run_cli("1,5", "kg")
        assert result.returncode == 0
        assert "Poids" in result.stdout

    def test_avec_to(self):
        """8.3 - Conversion avec --to."""
        result = run_cli("2.5", "km", "--to", "m")
        assert result.returncode == 0
        assert "2 500" in result.stdout

    def test_list(self):
        """8.4 - Option --list."""
        result = run_cli("--list")
        assert result.returncode == 0
        assert "Longueurs" in result.stdout
        assert "Poids" in result.stdout
        assert "Capacités" in result.stdout

    def test_version(self):
        """8.5 - Option --version."""
        result = run_cli("--version")
        assert result.returncode == 0
        assert "1.0.0" in result.stdout

    def test_help(self):
        """8.6 - Option --help."""
        result = run_cli("--help")
        assert result.returncode == 0
        assert "convertoche" in result.stdout.lower() or "usage" in result.stdout.lower()

    def test_valeur_sans_unite(self):
        """8.8 - Valeur sans unité → erreur."""
        result = run_cli("12.5")
        assert result.returncode == 0  # Pas de sys.exit pour cette erreur
        assert "Erreur" in result.stdout

    def test_unite_inconnue(self):
        """8.9 - Unité inconnue → erreur."""
        result = run_cli("12.5", "xyz")
        assert "Erreur" in result.stdout
        assert "non reconnue" in result.stdout

    def test_valeur_negative(self):
        """8.10 - Valeur négative → erreur."""
        result = run_cli("-5", "m")
        assert result.returncode == 1
        assert "négatives" in result.stdout

    def test_conversion_cross_famille(self):
        """8.11 - Conversion entre familles différentes → erreur."""
        result = run_cli("2", "km", "--to", "g")
        assert "Erreur" in result.stdout
        assert "différentes" in result.stdout

    def test_unite_cible_inconnue(self):
        """8.12 - Unité cible inconnue → erreur."""
        result = run_cli("2", "km", "--to", "xyz")
        assert "Erreur" in result.stdout
        assert "non reconnue" in result.stdout


class TestCLICapacite:
    """Tests supplémentaires pour les capacités."""

    def test_litre_majuscule(self):
        """Litre en majuscule."""
        result = run_cli("2.5", "L")
        assert result.returncode == 0
        assert "Capacités" in result.stdout

    def test_millilitre(self):
        """Millilitre."""
        result = run_cli("250", "mL")
        assert result.returncode == 0
        assert "Capacités" in result.stdout


class TestCLIRead:
    """Tests de l'argument --read (lecture stdin)."""

    def test_read_valeur_simple(self):
        """Lit une valeur simple depuis stdin."""
        result = run_cli("--read", "m", stdin_input="12.5")
        assert result.returncode == 0
        assert "Longueurs" in result.stdout
        assert "12,5" in result.stdout

    def test_read_avec_virgule(self):
        """Accepte la virgule française."""
        result = run_cli("--read", "kg", stdin_input="1,5")
        assert result.returncode == 0
        assert "Poids" in result.stdout
        assert "1,5" in result.stdout

    def test_read_avec_to(self):
        """Combine --read et --to."""
        result = run_cli("--read", "km", "--to", "m", stdin_input="2.5")
        assert result.returncode == 0
        assert "2 500" in result.stdout

    def test_read_stdin_vide(self):
        """Gestion stdin vide."""
        result = run_cli("--read", "m", stdin_input="")
        assert result.returncode == 1
        assert "Aucune valeur" in result.stdout or "Erreur" in result.stdout

    def test_read_valeur_invalide(self):
        """Gestion valeur invalide depuis stdin."""
        result = run_cli("--read", "m", stdin_input="abc")
        assert result.returncode == 1
        assert "Erreur" in result.stdout

    def test_read_unite_inconnue(self):
        """Unité inconnue avec --read."""
        result = run_cli("--read", "xyz", stdin_input="12.5")
        assert "non reconnue" in result.stdout


class TestCLIQuiz:
    """Tests de l'argument --quiz."""

    def test_quiz_dans_aide(self):
        """L'argument --quiz est documenté."""
        result = run_cli("--help")
        assert "--quiz" in result.stdout
        assert "quiz" in result.stdout.lower()

    def test_quiz_shortcut(self):
        """L'alias -q est documenté."""
        result = run_cli("--help")
        assert "-q" in result.stdout


class TestCLICopy:
    """Tests de l'argument --copy."""

    def test_copy_dans_aide(self):
        """L'argument --copy est documenté."""
        result = run_cli("--help")
        assert "--copy" in result.stdout
        assert "presse-papier" in result.stdout.lower() or "clipboard" in result.stdout.lower()

    def test_copy_shortcut(self):
        """L'alias -c est documenté."""
        result = run_cli("--help")
        assert "-c" in result.stdout

    def test_copy_sans_pyperclip(self):
        """--copy fonctionne même sans pyperclip (avec warning)."""
        result = run_cli("12.5", "m", "--copy")
        assert result.returncode == 0
        assert "12,5" in result.stdout


class TestCLIHelp:
    """Vérifie que l'aide contient toutes les options."""

    def test_help_contient_read(self):
        """--read dans l'aide."""
        result = run_cli("--help")
        assert "--read" in result.stdout

    def test_help_contient_copy(self):
        """--copy dans l'aide."""
        result = run_cli("--help")
        assert "--copy" in result.stdout

    def test_help_contient_quiz(self):
        """--quiz dans l'aide."""
        result = run_cli("--help")
        assert "--quiz" in result.stdout

    def test_help_exemples(self):
        """L'aide contient des exemples."""
        result = run_cli("--help")
        assert "Exemples" in result.stdout


class TestCLICombined:
    """Tests de combinaison d'options."""

    def test_read_et_to(self):
        """--read combiné avec --to."""
        result = run_cli("--read", "m", "--to", "cm", stdin_input="1")
        assert result.returncode == 0
        assert "100" in result.stdout

    def test_read_et_copy(self):
        """--read combiné avec --copy."""
        result = run_cli("--read", "m", "--copy", stdin_input="5")
        assert result.returncode == 0
        assert "5" in result.stdout

    def test_valeur_unite_et_copy(self):
        """Valeur/unité combinés avec --copy."""
        result = run_cli("10", "kg", "--copy")
        assert result.returncode == 0
        assert "10" in result.stdout
        assert "Poids" in result.stdout
