# scripts/run_all_plots.py
from __future__ import annotations

import argparse
import subprocess
import sys
from typing import Iterable


PLOT_MODULES: tuple[str, ...] = (
    "scripts.plot_temperature",
    "scripts.plot_calendar_overview",
    "scripts.plot_all_pairwise_scatter",
    "scripts.plot_correlation_heatmap",
    "scripts.plot_diurnal_cycle",
    "scripts.plot_hexbin_explorations",
    "scripts.plot_illuminance_focus",
    "scripts.plot_lagged_correlations",
    "scripts.plot_monthly_patterns",
    "scripts.plot_rain_event_composites",
    "scripts.plot_rain_hyetograph",
    "scripts.plot_rolling_correlation_heatmap",
    "scripts.plot_seasonal_overview",
    "scripts.plot_sun_elevation_relationships",
    "scripts.plot_wind_conditionals",
    "scripts.plot_wind_rose",
    "scripts.plot_wind_rose_rain",
)


def _normalize_module(name: str) -> str:
    name = name.strip()
    if not name:
        raise ValueError("Nom de module vide.")
    return name if name.startswith("scripts.") else f"scripts.{name}"


def iter_modules(selected: Iterable[str] | None) -> list[str]:
    if not selected:
        return list(PLOT_MODULES)

    normalized = [_normalize_module(name) for name in selected]
    modules: list[str] = []
    missing: list[str] = []
    for module in normalized:
        if module in PLOT_MODULES:
            modules.append(module)
        else:
            missing.append(module)

    if missing:
        available = "\n  - ".join(("",) + PLOT_MODULES)
        missing_list = "\n  - ".join(("",) + tuple(missing))
        raise SystemExit(
            "\n".join(
                [
                    "Les modules suivants ne sont pas reconnus :",
                    missing_list,
                    "",
                    "Modules disponibles :",
                    available,
                ]
            )
        )

    return modules


def run_module(module: str) -> bool:
    cmd = [sys.executable, "-m", module]
    print(f"\n=== {module} ===")
    result = subprocess.run(cmd, check=False)

    if result.returncode == 0:
        print(f"✔ {module} terminé avec succès.")
        return True

    print(f"✘ {module} a échoué (code {result.returncode}).")
    return False


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Lance tous les scripts de tracé météorologiques.")
    parser.add_argument(
        "--only",
        nargs="*",
        help="Limiter l'exécution à certains modules (ex: plot_temperature).",
    )
    args = parser.parse_args(argv)

    modules = iter_modules(args.only)
    print(f"Exécution de {len(modules)} script(s) de tracé…")

    success_count = 0
    for module in modules:
        if run_module(module):
            success_count += 1

    print()
    print(f"Scripts réussis : {success_count}/{len(modules)}")
    failed = len(modules) - success_count
    if failed:
        print(f"⚠ {failed} script(s) ont échoué. Consultez les messages ci-dessus.")
        return 1

    print("✔ Tous les scripts ont été exécutés avec succès.")
    return 0


if __name__ == "__main__":  # pragma: no cover
    raise SystemExit(main())
