#!/usr/bin/env python3
"""
Banc de vérification du moteur de prix sur les 21 clients réels.

Rejoue chaque client (volumétries déclarées de `calculette projet .xlsx`) à
travers pricing_engine, compare le forfait modèle au CA réel du cockpit et au
taux implicite sur les heures réelles. Les clients "métier" (sur-mesure cadré en
RDV) sont marqués: leur prix n'est pas censé être auto-calculé.
"""
import os
import re
import sys

sys.path.insert(0, "/root/aios/data/ca_dashboard")
import dashboard_data as dd  # noqa: E402
import pandas as pd  # noqa: E402
from pricing_engine import estimate, load_config  # noqa: E402

XLSX = "/root/aios/data/chat-attachments/2026-07-07/4dedf2ef2bc34da19e98a641994f1540/calculette projet .xlsx"
KEY = {
    "BENELYON": "BENELYON", "Hivy": "HIVY", "Asgard Motors": "ASGARD MOTORS",
    "AFPAC": "AFPAC", "Credipro France": "CREDIPRO", "Assur&Sens": "ASSUR&SENS",
    "CELERYS CONSEIL": "CELERYS Conseil", "MARMELADZ": "MARMELADZ", "Flowlity": "FLOWLITY",
    "GAC IP": "GAC IP", "Gac Technology": "GAC TECHNOLOGY", "GAMAR": "GAMAR",
    "IN SITU": "IN SITU", "Inspiire": "INSPIIRE", "MEDIANE": "MEDIANE (NOUVEAU REGARD)",
    "NEORIZONS": "NEORIZONS", "QUI VEUT RAFRAICHIR SA VILLE": "QVRSV",
    "Red Apple School": "RED APPLE SCHOOL", "SACCINTO": "SACCINTO",
    "Innovation Foods And Drinks": "STAR NUTRITION INNOVATION", "Proxity": "PROXITY",
}
# Clients dont l'essentiel de la charge est du sur-mesure métier -> bloc RDV.
METIER = {"IN SITU", "NEORIZONS", "MARMELADZ", "CELERYS CONSEIL",
          "QUI VEUT RAFRAICHIR SA VILLE"}
# Type de clientèle déclaré -> code Calculoid (1..5).
TYPE_MAP = {"BTOB": 1, "BTOC": 2}


def band(x):
    s = str(x).strip().lower()
    if "non concern" in s or s in ("nan", "") or "pas de" in s:
        return 0.0
    m = re.search(r"(\d[\d ]*)", s.replace(" ", ""))
    v = float(re.sub(r"\D", "", m.group(1))) if m else 0.0
    if v == 0:
        return 0.0
    if s.startswith("<") or "moins" in s:
        return v * 0.6
    if s.startswith(">") or "+" in s or "plus" in s:
        return v * 1.2
    return v


def type_code(txt):
    t = str(txt).upper()
    if "PUBLI" in t and "BTOB" in t:
        return 5
    if "PUBLI" in t:
        return 4
    if "BTOB" in t and "BTOC" in t:
        return 3
    if "BTOC" in t:
        return 2
    return 1


def main():
    cfg = load_config()
    proj = pd.read_excel(XLSX)
    hist, _ = dd.history_avg("2026-07", n=6)

    # Colonnes: h_std = heures standard estimées par le moteur ; taux_std = taux
    # implicite sur ce périmètre standard (garanti >=70 par construction) ;
    # h_réel = heures totales réelles (standard + métier) ; %métier = part des
    # heures réelles NON couverte par le standard (surface RDV/options).
    print("%-16s %5s %6s %6s %7s %8s %7s" % (
        "client", "mét.", "h_std", "taux", "h_réel", "%métier", "PRIX_std"))
    n_std = n_ok = 0
    for _, r in proj.iterrows():
        name = r["nom du client"]
        key = KEY.get(name)
        v = hist.get(key) or {}
        real_h = v.get("hours") or 0
        is_metier = name in METIER
        inp = {
            "nb_factures_vente": band(r["Nombre de facture de vente   / mois"]),
            "nb_depenses": band(r["nomrbe de dépense / mois"]),
            "nb_collaborateurs": band(r["Nombre collaborateur"]),
            "nb_lignes_bancaires": band(r["Nombre Ligne bancaire"]),
            "type_client": type_code(r["Type de clientele"]),
            "secteur": 1,  # secteur à mapper client par client (défaut Services)
            "metier_adaptation": is_metier,
        }
        res = estimate(inp, cfg)
        price = res["forfait_mensuel_ht"]
        h_std = res["heures_standard_estimees"]
        taux_std = res["taux_implicite"]
        pct_metier = (100 * (real_h - h_std) / real_h) if real_h and real_h > h_std else 0
        if not is_metier:
            n_std += 1
            if taux_std and taux_std >= 70:
                n_ok += 1
        print("%-16s %5s %6.1f %6s %7.1f %7d%% %7d" % (
            name[:16], "oui" if is_metier else "-", h_std,
            ("%.0f" % taux_std) if taux_std else "-", real_h,
            round(pct_metier), price))

    print("\nPérimètre standard facturé >=70 EUR/h par construction: %d/%d" % (n_ok, n_std))
    print("Clients métier (sur-mesure cadré en RDV): %d" % len(METIER))
    print("Note: %métier = part des heures réelles au-delà du standard -> options / RDV.")


if __name__ == "__main__":
    main()
