from __future__ import annotations

from pathlib import Path

from app.excel_import.config import CONTEXT_ORDER, REPORTS_DIR
from app.excel_import.contexts import autres, copropriete, lots, personnes, roles
from app.database_profiles import PROFILE_IMPORT, PROFILE_PROD
from app.excel_import.db import prepare_target_database
from app.excel_import.reader import ExcelSource
from app.excel_import.report import ImportReport
from app.models import Copropriete


def run_import(
    *,
    excel_path: Path,
    config: dict,
    contexts: list[str],
    dry_run: bool,
    prod: bool,
    reset: bool,
) -> list[ImportReport]:
    if prod and set(contexts) != set(CONTEXT_ORDER):
        raise SystemExit("--prod nécessite --all (tous les contextes).")

    if dry_run:
        from app import create_app

        app = create_app()
    else:
        db_path = prepare_target_database(prod=prod, reset=reset)
        from app.excel_import.db import create_app_for_db

        app = create_app_for_db(db_path)
        print(f"Base cible : {db_path}")

    reports: list[ImportReport] = []
    profile_key = PROFILE_PROD if prod else PROFILE_IMPORT

    with app.app_context():
        with app.test_request_context():
            from app.database_profiles import set_session_profile

            set_session_profile(profile_key)
            print(f"Excel : {excel_path}")
            if dry_run:
                print("Mode simulation (aucune écriture)")

            source = ExcelSource(excel_path)
            try:
                copro: Copropriete | None = None

                if "copropriete" in contexts:
                    copro, rep = copropriete.run(config, dry_run=dry_run)
                    reports.append(rep)
                else:
                    copro = Copropriete.query_actifs().first()
                    if not copro:
                        raise SystemExit(
                            "Aucune copropriété en base. Lancez d'abord --only copropriete."
                        )

                copro_id = copro.id if copro and not dry_run else 0
                if dry_run:
                    copro_id = 1

                if "personnes" in contexts:
                    reports.append(personnes.run(source, copro_id, dry_run=dry_run))

                if "lots" in contexts:
                    _, rep = lots.run(source, copro_id, dry_run=dry_run)
                    reports.append(rep)

                if "roles" in contexts:
                    reports.append(roles.run(source, copro_id, dry_run=dry_run))

                if "autres" in contexts:
                    reports.append(autres.run(source, copro_id, dry_run=dry_run))

            finally:
                source.close()

    return reports


def print_summary(reports: list[ImportReport], *, save: bool = True) -> None:
    print("\n" + "=" * 50)
    print("RÉCAPITULATIF IMPORT")
    for rep in reports:
        rep.print_report()
    total_errors = sum(len(r.errors) for r in reports)
    total_warnings = sum(len(r.warnings) for r in reports)
    print("=" * 50)
    print(f"Total : {total_warnings} avertissement(s), {total_errors} erreur(s)")
    if save and reports:
        REPORTS_DIR.mkdir(parents=True, exist_ok=True)
        for rep in reports:
            path = rep.save(REPORTS_DIR)
            print(f"Rapport : {path}")
