#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.9"
# dependencies = ["resend"]
# ///
"""
ROUND DEMO "triage" (presentation du systeme) — contact@ / quote@ / sales@ via Resend.

Contrairement a send_postmaster_tests.py (couverture technique des filtres, marqueur PMFLOW),
ce round envoie des emails REALISTES type prospects bijouterie B2B (marque etablie cherchant
une usine : vermeil, MOQ, sampling fees...) pour DEMONTRER le systeme de bout en bout :

  boite         scenario                                    resultat attendu
  ------------- ------------------------------------------- ----------------------------------
  quote@        RFQ directe (marque vermeil, Milan)         Quote par ADRESSE -> "Quote — to handle"
  quote@        notification no-reply                       Quote + tag 'auto' + prio LOW (filtre 50)
  sales@        RFQ mal adressee (sujet "RFQ: pricing...")  re-route Quote + tag 'rerouted:auto' (41)
  sales@        vrai mail commercial (partenariat retail)   RESTE Sales (aucun mot-cle RFQ)
  sales@        "Re: Quotation Q-2214 ..."                  RESTE Sales (reponses exclues du re-route)
  contact@      email vermeil SANS mot-cle (ex. client)     RESTE Triage -> "Triage — to sort" (tri manuel)
  contact@      sujet "Quotation for 1000 ..."              TRIAGE sujet -> Quote (30x)
  contact@      sujet "Invoice ... payment"                 TRIAGE sujet -> Accounting (31x)
  contact@      sujet neutre, corps shipping/delivery       TRIAGE corps -> Logistics (22x)
  contact@      sujet neutre, corps technical drawing/STEP  TRIAGE corps -> Engineering/CAD (23x)
  contact@      sujet "Price request", corps "invoice"      SUJET > CORPS -> Quote
  contact@      sujet "Warranty claim — broken clasp"       TRIAGE sujet -> After-sales (34x)
  contact@      corps en francais (devis vermeil)           RESTE Triage + tag 'non-english' (60)

Interet demo : les files hybrides (option C, branche Dev-Hybride) se remplissent en live —
"Quote — to handle" recoit 5 tickets (dont 1 prio low groupe a part), "Triage — to sort" 2
tickets a trier manuellement (dont l'email vermeil, le cas d'ecole du client).

Chaque corps porte le marqueur "DEMO-R1" -> verification ciblee :
  docker exec -u zammad zammad-zammad-railsserver-1 bin/rails r /tmp/verify_routing.rb DEMO-R1

Aucun secret dans le repo : cle API via variable d'env RESEND_TEST.

Usage :
  export RESEND_TEST=re_xxx
  uv run tests/routing-sim/send_demo_round.py --dry-run   # affiche sans envoyer
  uv run tests/routing-sim/send_demo_round.py             # envoie (batch)
  uv run tests/routing-sim/send_demo_round.py --only contact
"""
import argparse
import os
import sys

DEFAULT_DOMAINS = ["elevaseo.com", "ceoinsight.dev", "seoinsight.app"]
MARKER = "DEMO-R1"  # marqueur discret dans le corps (aucun mot-cle de routage)

# "to" = boite destinataire (local part). "from_local" = expediteur (domaine par rotation).
# "expected" = comportement attendu, affiche pour la verification.
SCENARIOS = [
    # --- quote@ : baseline par adresse -------------------------------------------------
    dict(to="quote", name="Isabella Ferretti", from_local="isabella.ferretti",
         subject="Quotation request — new gold vermeil collection (300+ pcs)",
         body=("Dear Team,\n\nWe are an established fine jewelry brand based in Milan, currently "
               "looking for a new manufacturing partner for our upcoming vermeil collection. "
               "Could you send us details about your factory capabilities and business terms — "
               "MOQ, sampling fees, and typical production timelines?\n\nBest regards,\nIsabella"),
         expected="Par ADRESSE -> Quote/Estimating. Visible dans 'Quote — to handle'."),
    dict(to="quote", name="Website Forms", from_local="no-reply",
         subject="Automated: your contact form submission was received",
         body="This is an automated confirmation. Please do not reply to this message.",
         expected="Quote (adresse) + tag 'auto' + prio LOW (filtre 50) -> groupe a part dans la file."),

    # --- sales@ : re-route mal-adressage + exclusion Re: -------------------------------
    dict(to="sales", name="Amelia Hart", from_local="amelia.hart",
         subject="RFQ: pricing for 250 vermeil pendants",
         body=("Hello,\n\nWe are refreshing our autumn line and would like your pricing for 250 "
               "gold vermeil pendants, stone-set. Could you also share your MOQ and sampling "
               "terms?\n\nThanks,\nAmelia"),
         expected="MAL-ADRESSE -> re-route Quote + tag 'rerouted:auto' (filtre 41 sales->quote)."),
    dict(to="sales", name="Omar Al-Rashid", from_local="omar.alrashid",
         subject="Partnership opportunity — jewelry retail chain (12 stores)",
         body=("Dear Sales Team,\n\nWe operate 12 retail stores across the Gulf region and are "
               "interested in carrying your collections. Who would be the right person to "
               "discuss wholesale terms and exclusivity?\n\nRegards,\nOmar"),
         expected="RESTE Sales (aucun mot-cle RFQ dans le sujet -> pas de re-route)."),
    dict(to="sales", name="Amelia Hart", from_local="amelia.hart",
         subject="Re: Quotation Q-2214 — updated stone specifications",
         body=("Hi,\n\nFollowing up on our discussion: we confirm the switch to lab-grown "
               "sapphires on ref Q-2214. Same settings as before.\n\nAmelia"),
         expected="RESTE Sales ('Re:' exclu du re-route -> le suivi reste a l'equipe)."),

    # --- contact@ : le round de triage -------------------------------------------------
    dict(to="contact", name="Grace Osei", from_local="grace.osei",
         subject="Looking for a new factory — vermeil collection",
         body=("Dear Team, I'm an establish brand and I am looking for a new factory to produce "
               "my new vermeil collection. Pls send me details regarding your factories "
               "capabilities and busineem term requirmments like MOQ sampling fees etc."),
         expected="RESTE Triage (aucun mot-cle) -> 'Triage — to sort', tri MANUEL par un agent. "
                  "Cas d'ecole du client : la demande reelle sans vocabulaire RFQ."),
    dict(to="contact", name="Lena Fischer", from_local="lena.fischer",
         subject="Quotation for 1000 sterling silver charm bracelets",
         body=("Hi,\n\nCould I get a quotation for 1000 sterling silver charm bracelets, "
               "3 charm designs, rhodium plated? Target delivery is early November.\n\nLena"),
         expected="TRIAGE sujet -> Quote/Estimating (filtre 30x)."),
    dict(to="contact", name="Kenji Watanabe", from_local="kenji.watanabe",
         subject="Invoice INV-0088 — payment not going through",
         body=("Hello,\n\nOur wire transfer for INV-0088 was rejected by the bank yesterday. "
               "Could you confirm your account details so we can retry?\n\nKenji"),
         expected="TRIAGE sujet -> Accounting (filtre 31x)."),
    dict(to="contact", name="Fatima Zahra", from_local="fatima.zahra",
         subject="Following up on our last production run",
         body=("Hi,\n\nCould you confirm the shipping status and expected delivery date of our "
               "last batch to Dubai? A tracking number would be great.\n\nFatima"),
         expected="TRIAGE corps -> Logistics (filtre 22x) : sujet neutre, mots-cles dans le corps."),
    dict(to="contact", name="Viktor Novak", from_local="viktor.novak",
         subject="Feasibility check for a new ring model",
         body=("Hello,\n\nPlease find attached our technical drawing and STEP file for a new "
               "ring model. Can your workshop hold a 0.05 mm tolerance on the setting?\n\nViktor"),
         expected="TRIAGE corps -> Engineering/CAD (filtre 23x) : sujet neutre, mots-cles dans le corps."),
    dict(to="contact", name="Chloe Bernard", from_local="chloe.bernard",
         subject="Price request for our new bridal line",
         body=("Hi,\n\nWe are planning a bridal line for next spring and would like your terms. "
               "Separately, we still have an open invoice from March we would like to settle."),
         expected="SUJET > CORPS -> Quote : sujet 'price request' l'emporte sur corps 'invoice'."),
    dict(to="contact", name="Daniel Kim", from_local="daniel.kim",
         subject="Warranty claim — broken clasp on bracelet order B-2205",
         body=("Hello,\n\nThree bracelets from order B-2205 arrived with a broken clasp. "
               "How do we proceed for replacement?\n\nDaniel"),
         expected="TRIAGE sujet -> After-sales (filtre 34x)."),
    dict(to="contact", name="Camille Petit", from_local="camille.petit",
         subject="Demande d'information",
         body=("Bonjour,\n\nJe souhaiterais un devis pour une collection de bagues en vermeil, "
               "environ 200 pieces. Merci d'avance.\n\nCordialement,\nCamille"),
         expected="RESTE Triage + tag 'non-english' (filtre 60) : regex EN ne matche pas 'devis'."),
]


def main() -> None:
    ap = argparse.ArgumentParser(description="Round demo triage (contact/quote/sales) via Resend.")
    ap.add_argument("--dry-run", action="store_true", help="affiche sans envoyer")
    ap.add_argument("--only", help="ne traiter que les scenarios vers cette boite (local part)")
    args = ap.parse_args()

    zammad_domain = os.environ.get("ZAMMAD_DOMAIN", "vivacoda.com")
    domains = [d.strip() for d in os.environ.get(
        "RESEND_DOMAINS", ",".join(DEFAULT_DOMAINS)).split(",") if d.strip()]
    if not domains:
        sys.exit("RESEND_DOMAINS vide.")

    scenarios = [s for s in SCENARIOS if not args.only or s["to"] == args.only]
    if not scenarios:
        sys.exit(f"Aucun scenario pour --only {args.only}")

    params, meta = [], []
    for i, s in enumerate(scenarios):
        domain = domains[i % len(domains)]
        from_addr = f"{s['name']} <{s['from_local']}@{domain}>"
        to_addr = f"{s['to']}@{zammad_domain}"
        body = f"{s['body']}\n\n-- ref {MARKER}"  # marqueur pour la verification
        params.append({"from": from_addr, "to": [to_addr], "subject": s["subject"], "text": body})
        meta.append((s, from_addr, to_addr))

    print(f"Destinataire: @{zammad_domain} | expediteurs (rotation): {', '.join(domains)} | "
          f"{'DRY-RUN' if args.dry_run else 'ENVOI (batch)'} | {len(params)} email(s) | marqueur: {MARKER}\n")

    if args.dry_run:
        for s, from_addr, to_addr in meta:
            print(f"[DRY] {to_addr:26} <- {from_addr}\n        subj: {s['subject']}")
    else:
        import resend  # SDK officiel (installe par uv via PEP 723)
        api_key = os.environ.get("RESEND_TEST")
        if not api_key:
            sys.exit("RESEND_TEST manquant (export RESEND_TEST=re_xxx).")
        resend.api_key = api_key
        try:
            result = resend.Batch.send(params)
        except Exception as e:  # noqa: BLE001
            sys.exit(f"Echec du batch Resend : {e}")
        ids = [e.get("id", "(no id)") for e in result.get("data", [])]
        for idx, (s, from_addr, to_addr) in enumerate(meta):
            eid = ids[idx] if idx < len(ids) else "(no id)"
            print(f"[OK {eid}] {to_addr:26} <- {from_addr}\n        subj: {s['subject']}")

    print("\n==== FLOW ATTENDU (verifier ~1 min apres, verify_routing.rb DEMO-R1) ====")
    for s, from_addr, to_addr in meta:
        print(f"- {to_addr:26} <- {s['from_local']}@...\n    {s['subject'][:58]!r}\n    => {s['expected']}")


if __name__ == "__main__":
    main()
