"""
Génère les deux manuels ACX en format Word professionnel.
Exécuter : python generate_manuals.py
"""

from docx import Document
from docx.shared import Pt, Cm, RGBColor, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_ALIGN_VERTICAL
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
import datetime

# ── Palette couleurs ACREMAC ───────────────────────────────────────────────
NAVY       = RGBColor(0x1a, 0x35, 0x78)   # #1a3578
TEAL       = RGBColor(0x2d, 0x90, 0x73)   # #2d9073
LIGHT_TEAL = RGBColor(0x4d, 0xba, 0x96)   # #4dba96
GRAY_DARK  = RGBColor(0x1e, 0x29, 0x3b)   # #1e293b
GRAY_MID   = RGBColor(0x64, 0x74, 0x8b)   # #64748b
GRAY_LIGHT = RGBColor(0xf1, 0xf5, 0xf9)   # #f1f5f9
WHITE      = RGBColor(0xFF, 0xFF, 0xFF)
BLACK      = RGBColor(0x00, 0x00, 0x00)
RED_WARN   = RGBColor(0xef, 0x44, 0x44)
AMBER      = RGBColor(0xf5, 0x9e, 0x0b)

TODAY = datetime.date.today().strftime("%d %B %Y")


# ══════════════════════════════════════════════════════════════════════════════
# HELPERS
# ══════════════════════════════════════════════════════════════════════════════

def set_cell_bg(cell, hex_color: str):
    """Colorier le fond d'une cellule."""
    tc = cell._tc
    tcPr = tc.get_or_add_tcPr()
    shd = OxmlElement("w:shd")
    shd.set(qn("w:val"), "clear")
    shd.set(qn("w:color"), "auto")
    shd.set(qn("w:fill"), hex_color)
    tcPr.append(shd)


def set_cell_borders(table, color="D1D5DB"):
    """Appliquer des bordures fines à toutes les cellules du tableau."""
    for row in table.rows:
        for cell in row.cells:
            tc = cell._tc
            tcPr = tc.get_or_add_tcPr()
            tcBorders = OxmlElement("w:tcBorders")
            for side in ("top", "left", "bottom", "right", "insideH", "insideV"):
                border = OxmlElement(f"w:{side}")
                border.set(qn("w:val"), "single")
                border.set(qn("w:sz"), "4")
                border.set(qn("w:space"), "0")
                border.set(qn("w:color"), color)
                tcBorders.append(border)
            tcPr.append(tcBorders)


def add_page_break(doc):
    doc.add_page_break()


def set_margins(doc, top=2.5, bottom=2.5, left=2.8, right=2.8):
    for section in doc.sections:
        section.top_margin    = Cm(top)
        section.bottom_margin = Cm(bottom)
        section.left_margin   = Cm(left)
        section.right_margin  = Cm(right)


def add_heading(doc, text, level=1, color=None, space_before=18, space_after=8):
    p = doc.add_heading(text, level=level)
    p.paragraph_format.space_before = Pt(space_before)
    p.paragraph_format.space_after  = Pt(space_after)
    run = p.runs[0] if p.runs else p.add_run(text)
    if color:
        run.font.color.rgb = color
    return p


def add_paragraph(doc, text="", bold=False, italic=False, color=None,
                  size=11, space_before=0, space_after=6, align=None):
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(space_before)
    p.paragraph_format.space_after  = Pt(space_after)
    p.paragraph_format.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE
    if align:
        p.alignment = align
    if text:
        run = p.add_run(text)
        run.bold   = bold
        run.italic = italic
        run.font.size = Pt(size)
        if color:
            run.font.color.rgb = color
    return p


def add_bullet(doc, text, level=0, color=None):
    p = doc.add_paragraph(style="List Bullet")
    p.paragraph_format.space_before = Pt(1)
    p.paragraph_format.space_after  = Pt(3)
    p.paragraph_format.left_indent  = Cm(0.5 + level * 0.5)
    run = p.add_run(text)
    run.font.size = Pt(11)
    if color:
        run.font.color.rgb = color
    return p


def add_numbered(doc, text, color=None):
    p = doc.add_paragraph(style="List Number")
    p.paragraph_format.space_before = Pt(1)
    p.paragraph_format.space_after  = Pt(3)
    run = p.add_run(text)
    run.font.size = Pt(11)
    if color:
        run.font.color.rgb = color
    return p


def add_table(doc, headers, rows, header_bg="1a3578", header_fg=WHITE,
              stripe=True):
    """Tableau professionnel avec en-tête colorée."""
    table = doc.add_table(rows=1 + len(rows), cols=len(headers))
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    table.style = "Table Grid"

    # En-tête
    hdr_row = table.rows[0]
    for i, h in enumerate(headers):
        cell = hdr_row.cells[i]
        cell.text = ""
        run = cell.paragraphs[0].add_run(h)
        run.bold = True
        run.font.size = Pt(10)
        run.font.color.rgb = header_fg
        cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
        cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER
        set_cell_bg(cell, header_bg)

    # Lignes de données
    for r_idx, row_data in enumerate(rows):
        row = table.rows[r_idx + 1]
        bg = "f8fafc" if (stripe and r_idx % 2 == 0) else "ffffff"
        for c_idx, cell_text in enumerate(row_data):
            cell = row.cells[c_idx]
            cell.text = str(cell_text)
            cell.paragraphs[0].runs[0].font.size = Pt(10)
            cell.paragraphs[0].runs[0].font.color.rgb = GRAY_DARK
            cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER
            set_cell_bg(cell, bg)

    set_cell_borders(table)
    doc.add_paragraph().paragraph_format.space_after = Pt(6)
    return table


def add_note_box(doc, text, type_="info"):
    """Encadré info/avertissement."""
    colors = {
        "info":    ("dbeafe", "1d4ed8", "ℹ  Information"),
        "warning": ("fef9c3", "a16207", "⚠  Attention"),
        "tip":     ("dcfce7", "166534", "✓  Conseil"),
    }
    bg, fg_hex, label = colors.get(type_, colors["info"])
    fg = RGBColor(int(fg_hex[:2],16), int(fg_hex[2:4],16), int(fg_hex[4:],16))

    table = doc.add_table(rows=1, cols=1)
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    cell = table.rows[0].cells[0]
    cell.text = ""
    p1 = cell.paragraphs[0]
    r1 = p1.add_run(label + "\n")
    r1.bold = True
    r1.font.size = Pt(10)
    r1.font.color.rgb = fg
    r2 = p1.add_run(text)
    r2.font.size = Pt(10)
    r2.font.color.rgb = GRAY_DARK
    set_cell_bg(cell, bg)
    set_cell_borders(table, color=fg_hex)
    doc.add_paragraph().paragraph_format.space_after = Pt(4)


def add_cover_page(doc, title, subtitle, version="1.0.0", confidentiality="Usage interne"):
    """Page de couverture professionnelle."""
    set_margins(doc)

    # Espace haut
    for _ in range(4):
        add_paragraph(doc, "")

    # Bandeau titre
    table = doc.add_table(rows=1, cols=1)
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    cell = table.rows[0].cells[0]
    cell.text = ""
    p = cell.paragraphs[0]
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r = p.add_run(title)
    r.bold = True
    r.font.size = Pt(28)
    r.font.color.rgb = WHITE
    cell.paragraphs[0].paragraph_format.space_before = Pt(20)
    cell.paragraphs[0].paragraph_format.space_after  = Pt(20)
    set_cell_bg(cell, "1a3578")

    add_paragraph(doc, "")

    # Sous-titre
    p2 = add_paragraph(doc, subtitle, size=16, color=GRAY_MID,
                       align=WD_ALIGN_PARAGRAPH.CENTER, space_before=4, space_after=4)

    add_paragraph(doc, "")

    # Ligne décorative
    table2 = doc.add_table(rows=1, cols=1)
    table2.alignment = WD_TABLE_ALIGNMENT.CENTER
    c2 = table2.rows[0].cells[0]
    c2.text = ""
    set_cell_bg(c2, "2d9073")
    c2.paragraphs[0].paragraph_format.space_before = Pt(3)
    c2.paragraphs[0].paragraph_format.space_after  = Pt(3)

    add_paragraph(doc, "")

    # Métadonnées
    meta = [
        ("Version", version),
        ("Date de publication", TODAY),
        ("Éditeur", "ACREMAC"),
        ("Confidentialité", confidentiality),
    ]
    for k, v in meta:
        p = doc.add_paragraph()
        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        r1 = p.add_run(k + " : ")
        r1.bold = True
        r1.font.size = Pt(11)
        r1.font.color.rgb = GRAY_MID
        r2 = p.add_run(v)
        r2.font.size = Pt(11)
        r2.font.color.rgb = GRAY_DARK

    for _ in range(6):
        add_paragraph(doc, "")

    # Pied de page couverture
    p_footer = add_paragraph(doc, "© 2026 ACREMAC — Tous droits réservés",
                              color=GRAY_MID, size=9,
                              align=WD_ALIGN_PARAGRAPH.CENTER)

    add_page_break(doc)


def add_toc_entry(doc, number, title, page=""):
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(2)
    p.paragraph_format.space_after  = Pt(2)
    r1 = p.add_run(f"{number}. ")
    r1.bold = True
    r1.font.size = Pt(11)
    r1.font.color.rgb = NAVY
    r2 = p.add_run(title)
    r2.font.size = Pt(11)
    r2.font.color.rgb = GRAY_DARK


def add_separator(doc):
    table = doc.add_table(rows=1, cols=1)
    cell = table.rows[0].cells[0]
    cell.text = ""
    set_cell_bg(cell, "e2e8f0")
    cell.paragraphs[0].paragraph_format.space_before = Pt(2)
    cell.paragraphs[0].paragraph_format.space_after  = Pt(2)
    doc.add_paragraph().paragraph_format.space_after = Pt(6)


# ══════════════════════════════════════════════════════════════════════════════
# MANUEL TECHNIQUE
# ══════════════════════════════════════════════════════════════════════════════

def build_manuel_technique():
    doc = Document()
    set_margins(doc)

    # ── Page de couverture ────────────────────────────────────────────────────
    add_cover_page(
        doc,
        "MANUEL TECHNIQUE",
        "Plateforme ACX — Système de Gestion du Recouvrement",
        version="1.0.0",
        confidentiality="Usage interne — ACREMAC",
    )

    # ── Table des matières ────────────────────────────────────────────────────
    add_heading(doc, "Table des matières", level=1, color=NAVY)
    toc_items = [
        ("1", "Vue d'ensemble de l'architecture"),
        ("2", "Backend Django — Structure et modules"),
        ("3", "Modèles de données"),
        ("4", "API REST — Référence des endpoints"),
        ("5", "Frontend Next.js"),
        ("6", "Authentification et sécurité"),
        ("7", "Infrastructure de production"),
        ("8", "Base de données PostgreSQL"),
        ("9", "Variables d'environnement"),
        ("10", "Déploiement et mise à jour"),
        ("11", "Monitoring et maintenance"),
        ("12", "Conventions de développement"),
    ]
    for num, title in toc_items:
        add_toc_entry(doc, num, title)

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 1. ARCHITECTURE
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "1. Vue d'ensemble de l'architecture", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "La plateforme ACX est une application SaaS multi-tenant conçue pour la gestion complète "
        "du cycle de recouvrement de créances. Elle repose sur une architecture à deux couches "
        "distinctes : un backend API REST (Django) et un frontend découplé (Next.js), communiquant "
        "exclusivement via HTTP/JSON.", size=11)

    add_heading(doc, "1.1 Schéma d'architecture global", level=2, color=TEAL)
    add_paragraph(doc,
        "L'ensemble du trafic transite par un serveur Apache2 qui joue le rôle de reverse proxy "
        "et termine la connexion SSL. Il distribue ensuite les requêtes entre le processus Gunicorn "
        "(Django) et le processus Node.js (Next.js).", size=11)

    add_table(doc,
        ["Composant", "Technologie", "Version", "Rôle"],
        [
            ["API Backend",     "Django + Django REST Framework", "4.2.7",   "Logique métier, API REST JSON"],
            ["Serveur WSGI",    "Gunicorn",                       "21.2.0",  "Interface WSGI Python → Apache"],
            ["Frontend",        "Next.js (App Router)",           "16.0.10", "Interface utilisateur React/SSR"],
            ["Gestionnaire PM2","PM2",                            "—",       "Supervision processus Node.js"],
            ["Serveur web",     "Apache2",                        "2.4.58",  "Reverse proxy, SSL termination"],
            ["Base de données", "PostgreSQL",                     "16",      "Persistance relationnelle"],
            ["SSL",             "DigiCert wildcard",              "—",       "Chiffrement *.acx-acremac.net"],
        ]
    )

    add_heading(doc, "1.2 Domaines et services", level=2, color=TEAL)
    add_table(doc,
        ["Domaine", "Service", "Port interne", "Description"],
        [
            ["acx-acremac.net",     "Django/Gunicorn", "Socket UNIX",  "API REST + interface admin Django"],
            ["app.acx-acremac.net", "Next.js/PM2",    "3000",         "Application web (tous les profils)"],
        ]
    )

    add_heading(doc, "1.3 Flux de communication", level=2, color=TEAL)
    add_paragraph(doc,
        "Le frontend Next.js communique avec le backend Django via l'API REST. "
        "L'authentification utilise des tokens JWT (access token + refresh token). "
        "Le refresh automatique est géré côté client dans le wrapper API.", size=11)

    add_note_box(doc,
        "Toutes les communications sont chiffrées en HTTPS grâce au certificat wildcard "
        "DigiCert couvrant *.acx-acremac.net.",
        type_="tip")

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 2. BACKEND DJANGO
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "2. Backend Django — Structure et modules", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "2.1 Structure du projet", level=2, color=TEAL)
    add_table(doc,
        ["Dossier / Fichier", "Description"],
        [
            ["acx/settings.py",            "Paramètres de développement local"],
            ["acx/settings_prod.py",       "Paramètres de production (via django-environ)"],
            ["acx/urls.py",               "Routage URL principal"],
            ["accounts/",                  "Utilisateurs, rôles, memberships, journal d'audit"],
            ["tenancy/",                   "Multi-tenancy : modèle Tenant, dashboard super admin"],
            ["cases/",                     "Dossiers, débiteurs, portfolios, messages, documents"],
            ["customers/",                 "Clients créanciers, tickets support"],
            ["collections_management/",    "Recouvrement : actions, paiements, emails, promesses"],
            ["treasury_management/",       "Trésorerie : comptes, mouvements, reversements"],
            ["templates/emails/",          "Templates HTML et texte pour emails transactionnels"],
            ["deploy/",                    "Fichiers de déploiement : Apache, systemd, scripts"],
        ]
    )

    add_heading(doc, "2.2 Modules fonctionnels", level=2, color=TEAL)

    modules = [
        ("accounts", "Gestion des utilisateurs (AbstractUser étendu), rôles RBAC (4 niveaux), "
         "memberships tenant-user, journal d'audit (AuditLog) traçant toutes les actions d'administration."),
        ("tenancy", "Modèle Tenant (nom, plan, statut, localisation, devise, branding). "
         "Endpoint dashboard super admin agrégant KPIs, courbes de croissance, santé des tenants et journal d'audit."),
        ("cases", "Cœur métier : dossiers de créances (Case), débiteurs (Debtor), portfolios, "
         "notes internes, documents, messagerie tenant↔client, appels téléphoniques."),
        ("customers", "Clients créanciers (Customer), memberships portail client (CustomerMembership), "
         "tickets de support avec pièces jointes."),
        ("collections_management", "Cycle de recouvrement : dossiers de recouvrement (CollectionCase), "
         "actions, promesses de paiement, paiements reçus, envois d'emails avec templates."),
        ("treasury_management", "Comptabilité simplifiée : comptes multi-devises, journal des mouvements "
         "(entrées/sorties), transferts inter-comptes, reversements clients."),
    ]
    for mod, desc in modules:
        p = add_paragraph(doc, "")
        r1 = p.add_run(mod + "  ")
        r1.bold = True
        r1.font.size = Pt(11)
        r1.font.color.rgb = NAVY
        r2 = p.add_run(desc)
        r2.font.size = Pt(11)
        r2.font.color.rgb = GRAY_DARK

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 3. MODÈLES DE DONNÉES
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "3. Modèles de données", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "3.1 Tenant", level=2, color=TEAL)
    add_table(doc,
        ["Champ", "Type", "Description"],
        [
            ["name",            "CharField(200)",   "Nom unique de l'organisation"],
            ["slug",            "SlugField",        "Identifiant URL (auto-généré)"],
            ["status",          "TextChoices",      "active | suspended"],
            ["plan",            "CharField(50)",    "starter | business | enterprise"],
            ["country",         "CharField(2)",     "Code ISO pays (ex: TD, FR)"],
            ["currency",        "CharField(3)",     "Devise (ex: XAF, EUR)"],
            ["trial_ends_at",   "DateTimeField",    "Fin de période d'essai"],
            ["created_at",      "DateTimeField",    "Date de création (auto)"],
        ]
    )

    add_heading(doc, "3.2 User / Membership", level=2, color=TEAL)
    add_table(doc,
        ["Champ", "Type", "Description"],
        [
            ["User.email",                "EmailField (unique)", "Email de connexion"],
            ["User.must_change_password", "BooleanField",       "Forcer changement au prochain login"],
            ["Membership.tenant",         "FK → Tenant",        "Organisation d'appartenance"],
            ["Membership.user",           "FK → User",          "Utilisateur"],
            ["Membership.roles",          "M2M → Role",         "Rôles attribués"],
            ["Membership.status",         "TextChoices",        "invited | active | suspended"],
            ["Membership.is_owner",       "BooleanField",       "Propriétaire du tenant"],
        ]
    )

    add_heading(doc, "3.3 Case (Dossier)", level=2, color=TEAL)
    add_table(doc,
        ["Champ", "Type", "Description"],
        [
            ["tenant",           "FK → Tenant",       "Organisation propriétaire"],
            ["reference",        "CharField(40)",     "Référence unique par tenant (ex: ACX-000012)"],
            ["status",           "TextChoices",       "open | in_progress | closed | cancelled"],
            ["original_amount",  "DecimalField",      "Montant initial de la créance"],
            ["balance_amount",   "DecimalField",      "Solde restant dû"],
            ["currency",         "CharField",         "Devise"],
            ["opened_at",        "DateTimeField",     "Date d'ouverture"],
            ["closed_at",        "DateTimeField",     "Date de clôture"],
            ["due_date",         "DateField",         "Date d'échéance"],
            ["priority",         "CharField",         "Niveau de priorité"],
            ["debtor",           "FK → Debtor",       "Débiteur concerné"],
            ["customer",         "FK → Customer",     "Client créancier"],
        ]
    )

    add_heading(doc, "3.4 Rôles utilisateurs", level=2, color=TEAL)
    add_table(doc,
        ["ID", "Libellé", "Périmètre d'accès"],
        [
            ["1", "Personnel entreprise",     "Lecture uniquement"],
            ["2", "Personnel ACREMAC",        "Lecture et écriture"],
            ["3", "Administrateur entreprise","Gestion complète du tenant"],
            ["4", "Administrateur",           "Administration globale"],
            ["—", "Superuser Django",         "Accès total + dashboard super admin"],
        ]
    )

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 4. API REST
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "4. API REST — Référence des endpoints", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "L'API est disponible à l'adresse de base : https://acx-acremac.net/api/\n"
        "Toutes les requêtes authentifiées requièrent l'en-tête : Authorization: Bearer <access_token>",
        size=11)

    add_heading(doc, "4.1 Authentification", level=2, color=TEAL)
    add_table(doc,
        ["Méthode", "Endpoint", "Description", "Auth requise"],
        [
            ["POST", "/auth/token/",              "Obtenir JWT (admin/agent)",                  "Non"],
            ["POST", "/auth/token/refresh/",      "Renouveler le token d'accès",                "Non"],
            ["GET",  "/auth/me/",                 "Profil de l'utilisateur connecté",           "Oui"],
            ["POST", "/auth/client-portal/token/","Token portail client (débiteurs uniquement)","Non"],
        ]
    )

    add_heading(doc, "4.2 Tenants et Administration", level=2, color=TEAL)
    add_table(doc,
        ["Méthode", "Endpoint", "Description"],
        [
            ["GET",    "/tenants/",            "Liste des tenants (superuser)"],
            ["POST",   "/tenants/",            "Créer un tenant"],
            ["GET",    "/tenants/{id}/",       "Détail d'un tenant"],
            ["PATCH",  "/tenants/{id}/",       "Modifier un tenant"],
            ["DELETE", "/tenants/{id}/",       "Supprimer un tenant"],
            ["GET",    "/admin-dashboard/",    "KPIs et stats globales (superuser)"],
        ]
    )

    add_heading(doc, "4.3 Dossiers", level=2, color=TEAL)
    add_table(doc,
        ["Méthode", "Endpoint", "Description"],
        [
            ["GET",    "/cases/",           "Liste des dossiers du tenant"],
            ["POST",   "/cases/",           "Créer un dossier"],
            ["GET",    "/cases/{id}/",      "Détail d'un dossier"],
            ["PATCH",  "/cases/{id}/",      "Modifier un dossier"],
            ["GET",    "/cases/{id}/messages/", "Messages du dossier"],
            ["POST",   "/cases/{id}/messages/", "Envoyer un message"],
        ]
    )

    add_heading(doc, "4.4 Recouvrement et Paiements", level=2, color=TEAL)
    add_table(doc,
        ["Méthode", "Endpoint", "Description"],
        [
            ["GET",  "/collection-cases/",        "Dossiers de recouvrement"],
            ["POST", "/collection-cases/",        "Créer un dossier de recouvrement"],
            ["GET",  "/payments/",                "Liste des paiements"],
            ["POST", "/payments/",                "Enregistrer un paiement"],
            ["GET",  "/collection-emails/",       "Emails de relance envoyés"],
            ["POST", "/collection-emails/",       "Envoyer un email de relance"],
        ]
    )

    add_heading(doc, "4.5 Trésorerie", level=2, color=TEAL)
    add_table(doc,
        ["Méthode", "Endpoint", "Description"],
        [
            ["GET",  "/treasury-accounts/",                  "Liste des comptes"],
            ["POST", "/treasury-accounts/",                  "Créer un compte"],
            ["GET",  "/treasury-movements/",                 "Journal des mouvements"],
            ["POST", "/treasury-movements/manual/",          "Saisie manuelle"],
            ["POST", "/treasury-movements/transfer/",        "Transfert inter-comptes"],
            ["GET",  "/treasury-movements/summary/",         "Résumé financier"],
            ["GET",  "/remittances/",                        "Liste des reversements"],
            ["POST", "/remittances/draft/",                  "Créer un reversement"],
            ["POST", "/remittances/{id}/validate/",          "Valider un reversement"],
            ["POST", "/remittances/{id}/mark-paid/",         "Marquer comme payé"],
        ]
    )

    add_heading(doc, "4.6 Codes de réponse HTTP", level=2, color=TEAL)
    add_table(doc,
        ["Code", "Signification", "Usage"],
        [
            ["200", "OK",                  "Requête traitée avec succès"],
            ["201", "Created",             "Ressource créée avec succès"],
            ["204", "No Content",          "Suppression réussie (pas de corps)"],
            ["400", "Bad Request",         "Données invalides ou manquantes"],
            ["401", "Unauthorized",        "Token absent, expiré ou révoqué"],
            ["403", "Forbidden",           "Permissions insuffisantes"],
            ["404", "Not Found",           "Ressource introuvable"],
            ["500", "Internal Server Error","Erreur côté serveur"],
        ]
    )

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 5. FRONTEND NEXT.JS
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "5. Frontend Next.js", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "5.1 Structure des routes (App Router)", level=2, color=TEAL)
    add_table(doc,
        ["Route", "Profil", "Description"],
        [
            ["/{locale}/login",                    "Tous",         "Page de connexion admin/agent"],
            ["/{locale}/(app)/dashboard",          "Agent/Admin",  "Tableau de bord du tenant"],
            ["/{locale}/(app)/cases",              "Agent/Admin",  "Gestion des dossiers"],
            ["/{locale}/(app)/collections/cases",  "Agent/Admin",  "Dossiers de recouvrement"],
            ["/{locale}/(app)/customers",          "Agent/Admin",  "Clients créanciers"],
            ["/{locale}/(app)/communications",     "Agent/Admin",  "Centre de messagerie"],
            ["/{locale}/(app)/treasury",           "Agent/Admin",  "Trésorerie"],
            ["/{locale}/(admin)/admin",            "Super Admin",  "Dashboard super administration"],
            ["/{locale}/(admin)/admin/tenants",    "Super Admin",  "Gestion des tenants"],
            ["/{locale}/(admin)/admin/users",      "Super Admin",  "Gestion des utilisateurs"],
            ["/{locale}/(admin)/admin/security",   "Super Admin",  "RBAC et sécurité"],
            ["/{locale}/client/dashboard",         "Client",       "Tableau de bord débiteur"],
            ["/{locale}/client/cases",             "Client",       "Dossiers du débiteur"],
            ["/{locale}/client/messages",          "Client",       "Messagerie avec les agents"],
            ["/{locale}/client/support",           "Client",       "Tickets de support"],
        ]
    )

    add_heading(doc, "5.2 Architecture des services API (src/lib/api/)", level=2, color=TEAL)
    add_table(doc,
        ["Fichier", "Description"],
        [
            ["client.ts",   "Fetch wrapper central avec refresh JWT automatique et redirection en cas d'expiration"],
            ["storage.ts",  "Persistance des tokens (localStorage) avec abstraction read/write/clear"],
            ["auth.ts",     "Login, logout, refresh token"],
            ["admin.ts",    "Dashboard super admin : KPIs, croissance, santé tenants, audit log"],
            ["treasury.ts", "Comptes, mouvements, résumé, reversements, suggestions"],
        ]
    )

    add_heading(doc, "5.3 Internationalisation", level=2, color=TEAL)
    add_paragraph(doc,
        "La plateforme supporte le français (fr) et l'anglais (en) via la librairie next-intl. "
        "Les fichiers de traductions sont situés dans messages/fr.json et messages/en.json. "
        "Le préfixe de langue est inclus dans toutes les URLs (/{locale}/...).", size=11)

    add_note_box(doc,
        "Pour ajouter une nouvelle langue, créez le fichier messages/{lang}.json et ajoutez "
        "la locale dans la configuration next-intl.",
        type_="info")

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 6. AUTHENTIFICATION & SÉCURITÉ
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "6. Authentification et sécurité", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "6.1 Flux JWT", level=2, color=TEAL)
    add_table(doc,
        ["Étape", "Action", "Détail"],
        [
            ["1", "Login",          "POST /api/auth/token/ → access (30 min) + refresh (30 jours)"],
            ["2", "Requête API",    "Header Authorization: Bearer <access_token>"],
            ["3", "Expiration",     "Si 401 reçu → tentative de refresh automatique"],
            ["4", "Refresh",        "POST /api/auth/token/refresh/ → nouveau access token"],
            ["5", "Session expirée","Si refresh invalide → déconnexion + redirection login"],
        ]
    )

    add_heading(doc, "6.2 Séparation des portails", level=2, color=TEAL)
    add_paragraph(doc,
        "Le portail client utilise un endpoint d'authentification dédié "
        "(/api/auth/client-portal/token/) qui vérifie l'existence d'une CustomerMembership active. "
        "Les comptes admin/agent sont bloqués sur ce portail, et inversement.", size=11)

    add_heading(doc, "6.3 Mesures de sécurité en production", level=2, color=TEAL)
    add_table(doc,
        ["Mesure", "Description"],
        [
            ["HTTPS obligatoire",       "Redirection HTTP → HTTPS, HSTS activé"],
            ["SSL wildcard DigiCert",   "Certificat couvrant *.acx-acremac.net"],
            ["DEBUG=False",             "Mode production Django, aucune trace exposée"],
            ["CORS restreint",          "Seules les origines déclarées dans CORS_ALLOWED_ORIGINS sont autorisées"],
            ["Variables dans .env",     "Toutes les valeurs sensibles externalisées, fichier exclu du git"],
            ["Headers sécurité",        "Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy"],
            ["RBAC",                    "Contrôle d'accès par rôle sur toutes les vues API"],
            ["Superuser isolé",         "Accès /admin-dashboard/ réservé aux comptes is_superuser=True"],
        ]
    )

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 7. INFRASTRUCTURE
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "7. Infrastructure de production", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "7.1 Serveur", level=2, color=TEAL)
    add_table(doc,
        ["Paramètre", "Valeur"],
        [
            ["Fournisseur",  "RackNerd"],
            ["OS",           "Ubuntu 24.04 LTS"],
            ["IP publique",  "198.46.170.30"],
            ["CPU",          "1 vCPU"],
            ["RAM",          "2 GB"],
            ["Stockage",     "40 GB SSD"],
            ["Hostname",     "racknerd-0dade92"],
        ]
    )

    add_heading(doc, "7.2 Service Gunicorn (systemd)", level=2, color=TEAL)
    add_table(doc,
        ["Paramètre", "Valeur"],
        [
            ["Fichier service",     "/etc/systemd/system/acx-gunicorn.service"],
            ["Répertoire",          "/var/www/html/acx"],
            ["Socket",              "/run/acx-gunicorn.sock"],
            ["Workers",             "3"],
            ["Fichier .env",        "/var/www/html/acx/.env"],
            ["Variable MPLBACKEND", "Agg (matplotlib headless)"],
        ]
    )

    add_heading(doc, "7.3 PM2 — Next.js", level=2, color=TEAL)
    add_table(doc,
        ["Paramètre", "Valeur"],
        [
            ["Nom du processus",  "acx-front"],
            ["Répertoire",        "/var/www/html/front-acx"],
            ["Script",            "node_modules/.bin/next start"],
            ["Port",              "3000"],
            ["Max mémoire",       "512 MB"],
            ["Auto-restart",      "Oui"],
            ["Logs out",          "/var/log/pm2/acx-front-out.log"],
            ["Logs err",          "/var/log/pm2/acx-front-error.log"],
        ]
    )

    add_heading(doc, "7.4 Apache2 — Virtual Hosts", level=2, color=TEAL)
    add_table(doc,
        ["Fichier", "Domaine", "Cible"],
        [
            ["/etc/apache2/sites-available/acx.conf",     "acx-acremac.net",     "Unix socket Gunicorn"],
            ["/etc/apache2/sites-available/acx-app.conf", "app.acx-acremac.net", "127.0.0.1:3000 (PM2)"],
        ]
    )

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 8. BASE DE DONNÉES
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "8. Base de données PostgreSQL", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "8.1 Paramètres de connexion", level=2, color=TEAL)
    add_table(doc,
        ["Paramètre", "Valeur"],
        [
            ["Hôte",     "127.0.0.1"],
            ["Port",     "5432"],
            ["Base",     "acx_db"],
            ["Utilisateur", "acx_user"],
        ]
    )

    add_heading(doc, "8.2 Accès distant via SSH tunnel (pgAdmin)", level=2, color=TEAL)
    add_paragraph(doc,
        "Pour accéder à la base depuis un poste client sans IP fixe, utilisez un tunnel SSH :", size=11)
    add_bullet(doc, "Ouvrez un terminal et exécutez : ssh -L 5433:127.0.0.1:5432 root@198.46.170.30")
    add_bullet(doc, "Dans pgAdmin, configurez la connexion : Hôte = 127.0.0.1, Port = 5433")
    add_bullet(doc, "Utilisez les identifiants de la base de données")

    add_heading(doc, "8.3 Migrations", level=2, color=TEAL)
    add_paragraph(doc,
        "Les migrations sont générées directement en production et ne sont pas versionnées dans git. "
        "Chaque déploiement doit exécuter les commandes suivantes :", size=11)
    add_table(doc,
        ["Commande", "Description"],
        [
            ["python manage.py makemigrations", "Détecter les changements de modèles"],
            ["python manage.py migrate",        "Appliquer les migrations à la base"],
            ["python manage.py collectstatic",  "Collecter les fichiers statiques"],
        ]
    )

    add_heading(doc, "8.4 Sauvegardes", level=2, color=TEAL)
    add_paragraph(doc, "Commande d'export :", size=11)
    add_bullet(doc, "pg_dump -U acx_user -h 127.0.0.1 acx_db > backup_$(date +%Y%m%d).sql")
    add_paragraph(doc, "Commande de restauration :", size=11)
    add_bullet(doc, "psql -U acx_user -h 127.0.0.1 acx_db < backup_YYYYMMDD.sql")

    add_note_box(doc,
        "Il est recommandé de programmer une sauvegarde automatique quotidienne via cron "
        "et de stocker les backups dans un espace de stockage distant (S3, FTP).",
        type_="warning")

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 9. VARIABLES D'ENVIRONNEMENT
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "9. Variables d'environnement", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "9.1 Backend — fichier .env", level=2, color=TEAL)
    add_table(doc,
        ["Variable", "Exemple", "Description"],
        [
            ["SECRET_KEY",                       "django-insecure-...", "Clé secrète Django (générer aléatoirement)"],
            ["DEBUG",                            "False",               "Mode debug (toujours False en production)"],
            ["ALLOWED_HOSTS",                    "acx-acremac.net,...", "Domaines autorisés (séparés par virgule)"],
            ["DATABASE_URL",                     "postgres://user:pwd@host:5432/db", "URL de connexion BDD (encoder @ → %40)"],
            ["CORS_ALLOWED_ORIGINS",             "https://app.acx-acremac.net", "Origines CORS autorisées"],
            ["EMAIL_HOST",                       "smtp.example.com",    "Serveur SMTP"],
            ["EMAIL_PORT",                       "587",                 "Port SMTP"],
            ["EMAIL_USE_TLS",                    "True",               "Activer TLS"],
            ["EMAIL_HOST_USER",                  "acx@acremac.com",    "Compte email émetteur"],
            ["EMAIL_HOST_PASSWORD",              "...",                 "Mot de passe email"],
            ["DEFAULT_FROM_EMAIL",               "acx@acremac.com",    "Adresse expéditeur par défaut"],
            ["FRONTEND_BASE_URL",                "https://app.acx-acremac.net", "URL base du frontend"],
            ["DJANGO_SETTINGS_MODULE",           "acx.settings_prod",  "Module settings à charger"],
        ]
    )

    add_note_box(doc,
        "Le mot de passe base de données doit avoir ses caractères spéciaux encodés en URL : "
        "@ devient %40, $ devient %24, # devient %23.",
        type_="warning")

    add_heading(doc, "9.2 Frontend — fichier .env.production", level=2, color=TEAL)
    add_table(doc,
        ["Variable", "Valeur", "Description"],
        [
            ["NEXT_PUBLIC_API_BASE_URL", "https://acx-acremac.net/api", "URL de base de l'API backend"],
        ]
    )

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 10. DÉPLOIEMENT
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "10. Déploiement et mise à jour", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "10.1 Mise à jour du backend", level=2, color=TEAL)
    steps_back = [
        "cd /var/www/html/acx",
        "git pull",
        "source venv/bin/activate",
        "export DJANGO_SETTINGS_MODULE=acx.settings_prod",
        "pip install -r requirements.txt",
        "python manage.py migrate",
        "python manage.py collectstatic --noinput",
        "systemctl restart acx-gunicorn",
    ]
    for i, s in enumerate(steps_back, 1):
        add_numbered(doc, s)

    add_heading(doc, "10.2 Mise à jour du frontend", level=2, color=TEAL)
    steps_front = [
        "cd /var/www/html/front-acx",
        "git pull",
        "npm install",
        "npm run build",
        "pm2 restart acx-front",
    ]
    for s in steps_front:
        add_numbered(doc, s)

    add_heading(doc, "10.3 Vérification post-déploiement", level=2, color=TEAL)
    checks = [
        "curl -I https://acx-acremac.net → doit retourner HTTP 200",
        "curl -I https://app.acx-acremac.net → doit retourner HTTP 200",
        "pm2 status → acx-front doit être online",
        "systemctl status acx-gunicorn → doit être active (running)",
        "Se connecter sur https://app.acx-acremac.net et tester le login",
    ]
    for c in checks:
        add_bullet(doc, c, color=GRAY_DARK)

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 11. MONITORING
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "11. Monitoring et maintenance", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "11.1 Commandes de supervision", level=2, color=TEAL)
    add_table(doc,
        ["Commande", "Description"],
        [
            ["systemctl status acx-gunicorn",       "Statut du service Gunicorn"],
            ["journalctl -u acx-gunicorn -f",       "Logs Gunicorn en temps réel"],
            ["pm2 status",                          "Statut des processus PM2"],
            ["pm2 logs acx-front --lines 100",      "Logs Next.js"],
            ["tail -f /var/log/apache2/error.log",  "Logs d'erreur Apache"],
            ["tail -f /var/log/apache2/access.log", "Logs d'accès Apache"],
        ]
    )

    add_heading(doc, "11.2 Seuils d'alerte", level=2, color=TEAL)
    add_table(doc,
        ["Indicateur", "Seuil critique", "Action recommandée"],
        [
            ["Mémoire Gunicorn",     "> 512 MB par worker",   "Redémarrer le service"],
            ["Espace disque",        "< 20% libre",            "Nettoyer logs, purger backups anciens"],
            ["Redémarrages PM2",     "> 5 en 1 heure",         "Analyser les logs d'erreur"],
            ["Erreurs 500 Apache",   "Répétées (> 10/min)",    "Vérifier les logs Gunicorn"],
            ["Latence API",          "> 2 secondes",           "Vérifier les requêtes SQL lentes"],
        ]
    )

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 12. CONVENTIONS
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "12. Conventions de développement", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "12.1 Backend Python/Django", level=2, color=TEAL)
    add_bullet(doc, "PEP 8 : indentation 4 espaces, nommage snake_case")
    add_bullet(doc, "Modèles : toujours définir __str__ et Meta.ordering")
    add_bullet(doc, "Serializers DRF pour toutes les vues API")
    add_bullet(doc, "Permissions explicites sur chaque ViewSet")
    add_bullet(doc, "Migrations générées uniquement en production")

    add_heading(doc, "12.2 Frontend TypeScript/Next.js", level=2, color=TEAL)
    add_bullet(doc, "TypeScript strict : typage explicite de toutes les props et retours de fonctions")
    add_bullet(doc, "Composants 'use client' uniquement si interaction navigateur requise")
    add_bullet(doc, "Services API centralisés dans src/lib/api/")
    add_bullet(doc, "Tailwind CSS exclusivement pour le style (pas de style inline sauf couleurs dynamiques)")
    add_bullet(doc, "Traductions i18n obligatoires pour tout texte visible")

    add_heading(doc, "12.3 Git et déploiement", level=2, color=TEAL)
    add_bullet(doc, "Ne jamais commiter les fichiers .env (contenus dans .gitignore)")
    add_bullet(doc, "Ne jamais commiter les migrations (générées en production)")
    add_bullet(doc, "Branche principale : main")
    add_bullet(doc, "Messages de commit en français, format : <type>: <description>")
    add_bullet(doc, "Types : feat, fix, refactor, style, docs, chore")

    # Pied de page final
    add_paragraph(doc, "")
    add_separator(doc)
    add_paragraph(doc,
        "© 2026 ACREMAC — Document confidentiel à usage interne. "
        "Toute reproduction à des fins commerciales est strictement interdite.",
        color=GRAY_MID, size=9, align=WD_ALIGN_PARAGRAPH.CENTER)

    doc.save("MANUEL_TECHNIQUE_ACX.docx")
    print("✓ MANUEL_TECHNIQUE_ACX.docx généré")


# ══════════════════════════════════════════════════════════════════════════════
# MANUEL UTILISATEUR
# ══════════════════════════════════════════════════════════════════════════════

def build_manuel_utilisateur():
    doc = Document()
    set_margins(doc)

    add_cover_page(
        doc,
        "MANUEL UTILISATEUR",
        "Plateforme ACX — Guide d'utilisation complet",
        version="1.0.0",
        confidentiality="Usage interne et clients",
    )

    # Table des matières
    add_heading(doc, "Table des matières", level=1, color=NAVY)
    toc = [
        ("1",  "Présentation de la plateforme ACX"),
        ("2",  "Accès et connexion"),
        ("3",  "Espace Super Administrateur"),
        ("4",  "Tableau de bord Tenant"),
        ("5",  "Gestion des dossiers"),
        ("6",  "Module Recouvrement"),
        ("7",  "Gestion des clients créanciers"),
        ("8",  "Communications et messagerie"),
        ("9",  "Module Trésorerie"),
        ("10", "Portail Client (Débiteurs)"),
        ("11", "Paramètres et gestion du compte"),
        ("12", "Questions fréquentes"),
    ]
    for num, title in toc:
        add_toc_entry(doc, num, title)
    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 1. PRÉSENTATION
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "1. Présentation de la plateforme ACX", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "ACX est une plateforme SaaS (Software as a Service) de gestion du recouvrement de créances "
        "développée et opérée par ACREMAC. Elle centralise l'ensemble du cycle de recouvrement : "
        "constitution des dossiers, suivi opérationnel des actions, gestion des paiements, "
        "communication sécurisée avec les débiteurs, et reporting financier en temps réel.", size=11)

    add_heading(doc, "1.1 Profils utilisateurs", level=2, color=TEAL)
    add_table(doc,
        ["Profil", "Description", "Interface d'accès"],
        [
            ["Super Administrateur", "Personnel ACREMAC — gestion globale de la plateforme, supervision de tous les tenants", "app.acx-acremac.net"],
            ["Administrateur Tenant","Responsable d'une organisation cliente — gestion complète de son espace", "app.acx-acremac.net"],
            ["Agent de recouvrement","Collaborateur traitant les dossiers au quotidien", "app.acx-acremac.net"],
            ["Client (Débiteur)",    "Personne ou entreprise débitrice — consultation et communication", "app.acx-acremac.net/fr/client"],
        ]
    )

    add_heading(doc, "1.2 Navigateurs compatibles", level=2, color=TEAL)
    add_table(doc,
        ["Navigateur", "Version minimale", "Recommandé"],
        [
            ["Google Chrome",  "110+", "Oui"],
            ["Mozilla Firefox","110+", "Oui"],
            ["Microsoft Edge", "110+", "Oui"],
            ["Safari",         "16+",  "Oui"],
        ]
    )

    add_note_box(doc,
        "L'application est responsive et fonctionne sur smartphone et tablette. "
        "Pour une expérience optimale, utilisez un écran d'au moins 1280px de large.",
        type_="tip")

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 2. ACCÈS ET CONNEXION
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "2. Accès et connexion", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "2.1 Connexion — Agents et Administrateurs", level=2, color=TEAL)
    add_numbered(doc, "Ouvrez votre navigateur et accédez à : https://app.acx-acremac.net")
    add_numbered(doc, "Sélectionnez votre langue : Français ou English")
    add_numbered(doc, "Saisissez votre identifiant (nom d'utilisateur ou adresse email)")
    add_numbered(doc, "Saisissez votre mot de passe")
    add_numbered(doc, "Cliquez sur le bouton Se connecter")
    add_numbered(doc, "Vous êtes redirigé vers le tableau de bord de votre organisation")

    add_note_box(doc,
        "Première connexion : si votre administrateur vous a transmis un mot de passe temporaire, "
        "le système vous demandera de le changer immédiatement avant d'accéder à l'application.",
        type_="warning")

    add_heading(doc, "2.2 Connexion — Portail Client (Débiteurs)", level=2, color=TEAL)
    add_numbered(doc, "Accédez à : https://app.acx-acremac.net/fr/client")
    add_numbered(doc, "Saisissez l'adresse email et le mot de passe qui vous ont été communiqués")
    add_numbered(doc, "Cliquez sur Se connecter")

    add_heading(doc, "2.3 Déconnexion et sécurité de session", level=2, color=TEAL)
    add_bullet(doc, "Pour vous déconnecter : cliquez sur votre nom en haut à droite → Se déconnecter")
    add_bullet(doc, "La session expire automatiquement après 30 minutes d'inactivité")
    add_bullet(doc, "En cas de tentative d'accès après expiration, vous serez redirigé vers la page de connexion")

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 3. SUPER ADMIN
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "3. Espace Super Administrateur", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "L'espace super administrateur est réservé au personnel ACREMAC disposant d'un compte "
        "superadmin. Il permet de piloter l'ensemble de la plateforme multi-tenant.", size=11)

    add_heading(doc, "3.1 Dashboard Super Admin", level=2, color=TEAL)
    add_paragraph(doc,
        "Le tableau de bord se charge automatiquement au login. Toutes les données sont récupérées "
        "en temps réel depuis l'API.", size=11)

    add_table(doc,
        ["Section", "Contenu affiché"],
        [
            ["KPIs globaux",            "Tenants actifs, utilisateurs, dossiers, MRR estimé avec variation par rapport au mois précédent"],
            ["Courbe de croissance",    "Évolution cumulée des tenants, utilisateurs et dossiers sur la période sélectionnée"],
            ["Répartition par plan",    "Diagramme circulaire : répartition Starter / Business / Enterprise"],
            ["Santé des tenants",       "Tableau récapitulatif : dossiers, utilisateurs, plan, MRR, statut par organisation"],
            ["Journal d'audit",         "10 dernières actions d'administration sur la plateforme"],
        ]
    )

    add_paragraph(doc,
        "Sélecteur de période : utilisez les boutons 7d / 30d / 90d / 12m pour ajuster "
        "la fenêtre temporelle des graphiques. Le bouton Actualiser recharge toutes les données.", size=11)

    add_heading(doc, "3.2 Gestion des Tenants", level=2, color=TEAL)

    add_paragraph(doc, "Créer un nouveau tenant :", bold=True, size=11)
    add_numbered(doc, "Menu → Tenants → Nouveau tenant")
    add_numbered(doc, "Renseignez le nom de l'organisation (obligatoire)")
    add_numbered(doc, "Sélectionnez le plan tarifaire : Starter, Business ou Enterprise")
    add_numbered(doc, "Complétez les informations de contact : email, téléphone, pays, devise")
    add_numbered(doc, "Cliquez sur Enregistrer — le slug est généré automatiquement")

    add_paragraph(doc, "Modifier ou suspendre un tenant :", bold=True, size=11, space_before=8)
    add_numbered(doc, "Cliquez sur le nom du tenant dans la liste")
    add_numbered(doc, "Modifiez les champs souhaités")
    add_numbered(doc, "Pour suspendre : changez le champ Statut sur Suspendu")
    add_numbered(doc, "Enregistrez les modifications")

    add_heading(doc, "3.3 Gestion des Utilisateurs", level=2, color=TEAL)
    add_paragraph(doc, "Créer un utilisateur :", bold=True, size=11)
    add_numbered(doc, "Menu → Utilisateurs → Nouvel utilisateur")
    add_numbered(doc, "Renseignez l'email, le prénom, le nom de famille")
    add_numbered(doc, "Assignez l'utilisateur à un tenant")
    add_numbered(doc, "Sélectionnez le rôle approprié")
    add_numbered(doc, "Cliquez sur Créer — l'utilisateur reçoit un email d'invitation")

    add_heading(doc, "3.4 Sécurité et RBAC", level=2, color=TEAL)
    add_paragraph(doc,
        "La section Sécurité permet de consulter et gérer les règles de contrôle d'accès. "
        "Chaque modification est tracée automatiquement dans le journal d'audit avec "
        "l'identité de l'acteur et l'horodatage.", size=11)

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 4. TABLEAU DE BORD TENANT
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "4. Tableau de bord Tenant", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "Le tableau de bord est la première page affichée après connexion pour les agents "
        "et administrateurs. Il présente une synthèse de l'activité de votre organisation.", size=11)

    add_heading(doc, "4.1 Indicateurs clés", level=2, color=TEAL)
    add_table(doc,
        ["Indicateur", "Description"],
        [
            ["Dossiers actifs",        "Nombre total de dossiers en cours de traitement"],
            ["Montant total en cours",  "Encours global des créances à recouvrer"],
            ["Taux de recouvrement",    "Pourcentage des créances récupérées sur la période"],
            ["Paiements du mois",       "Total des règlements encaissés sur le mois en cours"],
        ]
    )

    add_heading(doc, "4.2 Navigation principale", level=2, color=TEAL)
    add_table(doc,
        ["Module", "Description"],
        [
            ["Tableau de bord",  "Vue synthétique et indicateurs clés"],
            ["Dossiers",         "Gestion des dossiers de créances"],
            ["Recouvrement",     "Suivi opérationnel des actions de recouvrement"],
            ["Clients",          "Gestion des clients créanciers"],
            ["Communications",   "Centre de messagerie multi-dossiers"],
            ["Trésorerie",       "Comptabilité : comptes, mouvements, reversements"],
            ["Paramètres",       "Configuration du compte et de l'organisation"],
        ]
    )

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 5. DOSSIERS
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "5. Gestion des dossiers", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "5.1 Liste des dossiers", level=2, color=TEAL)
    add_paragraph(doc,
        "La page liste affiche l'ensemble des dossiers de votre organisation avec les "
        "informations essentielles : référence, débiteur, montant, statut, date d'ouverture.",
        size=11)

    add_paragraph(doc, "Filtres disponibles :", bold=True, size=11)
    add_bullet(doc, "Statut : Ouvert, En cours, Fermé, Annulé")
    add_bullet(doc, "Portfolio : filtrer par portefeuille de créances")
    add_bullet(doc, "Assigné à : filtrer par agent responsable")
    add_bullet(doc, "Période : plage de dates d'ouverture")
    add_bullet(doc, "Recherche textuelle : nom du débiteur, référence, montant")

    add_heading(doc, "5.2 Créer un nouveau dossier", level=2, color=TEAL)
    add_numbered(doc, "Cliquez sur le bouton Nouveau dossier")
    add_numbered(doc, "Informations débiteur : nom complet, type (personne physique ou morale), coordonnées")
    add_numbered(doc, "Client créancier : sélectionnez l'organisation titulaire de la créance")
    add_numbered(doc, "Créance : saisissez le montant original et la devise")
    add_numbered(doc, "Portfolio : assignez le dossier à un portefeuille")
    add_numbered(doc, "Dates : date d'ouverture et date d'échéance")
    add_numbered(doc, "Priorité : Normale, Haute ou Urgente")
    add_numbered(doc, "Cliquez sur Créer — la référence est générée automatiquement (ex: ACX-000012)")

    add_heading(doc, "5.3 Fiche dossier — Vue détaillée", level=2, color=TEAL)
    add_table(doc,
        ["Onglet", "Contenu"],
        [
            ["Résumé",    "Informations générales, montants (original, recouvré, solde), statut, historique"],
            ["Actions",   "Appels téléphoniques, courriers, visites, promesses de paiement enregistrés"],
            ["Paiements", "Historique des règlements reçus avec calcul automatique du solde restant"],
            ["Messages",  "Fil de discussion sécurisé avec le débiteur via le portail client"],
            ["Documents", "Documents liés au dossier : contrats, mises en demeure, pièces justificatives"],
            ["Notes",     "Notes internes (visibles uniquement par les agents et administrateurs)"],
        ]
    )

    add_heading(doc, "5.4 Statuts d'un dossier", level=2, color=TEAL)
    add_table(doc,
        ["Statut", "Description", "Transitions possibles"],
        [
            ["Ouvert",    "Dossier nouvellement créé, pas encore traité", "En cours, Annulé"],
            ["En cours",  "Traitement actif par un agent", "Fermé, Annulé"],
            ["Fermé",     "Recouvrement terminé (total ou partiel)", "—"],
            ["Annulé",    "Dossier abandonné sans recouvrement", "—"],
        ]
    )

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 6. RECOUVREMENT
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "6. Module Recouvrement", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "Le module Recouvrement est le cœur opérationnel de la plateforme. Il permet aux agents "
        "de gérer le cycle de vie complet des dossiers de recouvrement : contact, négociation, "
        "suivi des paiements.", size=11)

    add_heading(doc, "6.1 Statuts de recouvrement", level=2, color=TEAL)
    add_table(doc,
        ["Statut", "Signification"],
        [
            ["Nouveau",    "Dossier créé, première prise en charge"],
            ["Contacté",   "Le débiteur a été joint (appel, email, courrier)"],
            ["Promesse",   "Le débiteur a promis un paiement à une date donnée"],
            ["Payé",       "Paiement reçu et enregistré"],
            ["Contesté",   "Le débiteur conteste la créance"],
            ["Clôturé",    "Dossier fermé définitivement"],
        ]
    )

    add_heading(doc, "6.2 Enregistrer une action de recouvrement", level=2, color=TEAL)
    add_numbered(doc, "Ouvrez le dossier de recouvrement concerné")
    add_numbered(doc, "Cliquez sur Nouvelle action")
    add_numbered(doc, "Sélectionnez le type : Appel téléphonique, Email, Courrier, Visite, Autre")
    add_numbered(doc, "Renseignez le résultat obtenu et les notes éventuelles")
    add_numbered(doc, "Planifiez une date de relance si nécessaire")
    add_numbered(doc, "Cliquez sur Enregistrer")

    add_heading(doc, "6.3 Enregistrer une promesse de paiement", level=2, color=TEAL)
    add_numbered(doc, "Sur le dossier de recouvrement, cliquez sur Promesse de paiement")
    add_numbered(doc, "Indiquez le montant promis et la date de paiement prévu")
    add_numbered(doc, "Ajoutez des notes si nécessaire")
    add_numbered(doc, "Enregistrez — le statut du dossier passe automatiquement à Promesse")

    add_heading(doc, "6.4 Enregistrer un paiement reçu", level=2, color=TEAL)
    add_numbered(doc, "Cliquez sur Nouveau paiement dans la fiche du dossier")
    add_numbered(doc, "Saisissez : montant, date de réception, mode de règlement")
    add_numbered(doc, "Indiquez la référence du paiement (numéro de chèque, virement, etc.)")
    add_numbered(doc, "Validez — le solde du dossier est mis à jour automatiquement")

    add_heading(doc, "6.5 Envoyer un email de relance", level=2, color=TEAL)
    add_numbered(doc, "Sur le dossier, cliquez sur Envoyer un email")
    add_numbered(doc, "Choisissez un template prédéfini ou rédigez un message personnalisé")
    add_numbered(doc, "Ajoutez des pièces jointes si nécessaire (PDF, images)")
    add_numbered(doc, "Vérifiez l'adresse email du destinataire")
    add_numbered(doc, "Cliquez sur Envoyer — l'action est tracée dans le dossier")

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 7. CLIENTS
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "7. Gestion des clients créanciers", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "Les clients sont les organisations qui confient leurs créances impayées à votre "
        "structure de recouvrement. Chaque client peut avoir plusieurs dossiers actifs "
        "et un accès au portail pour suivre l'avancement.", size=11)

    add_heading(doc, "7.1 Fiche client", level=2, color=TEAL)
    add_table(doc,
        ["Section", "Information"],
        [
            ["Identité",          "Raison sociale, secteur d'activité, identifiants légaux"],
            ["Contact",           "Responsable, email, téléphone, adresse"],
            ["Localisation",      "Pays, ville, fuseau horaire"],
            ["Dossiers",          "Liste et statistiques des dossiers confiés"],
            ["Financier",         "Montants recouvrés, taux de succès, reversements effectués"],
            ["Accès portail",     "Utilisateurs du portail client et leurs droits"],
        ]
    )

    add_heading(doc, "7.2 Inviter un utilisateur au portail client", level=2, color=TEAL)
    add_numbered(doc, "Ouvrez la fiche du client concerné")
    add_numbered(doc, "Accédez à l'onglet Utilisateurs portail")
    add_numbered(doc, "Cliquez sur Inviter un utilisateur")
    add_numbered(doc, "Saisissez l'adresse email du contact client")
    add_numbered(doc, "Confirmez l'invitation — un email avec les identifiants est envoyé automatiquement")

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 8. COMMUNICATIONS
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "8. Communications et messagerie", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "Le module Communications centralise tous les échanges entre les agents et les "
        "débiteurs. Chaque conversation est rattachée à un dossier spécifique, assurant "
        "la traçabilité complète des communications.", size=11)

    add_heading(doc, "8.1 Fonctionnalités", level=2, color=TEAL)
    add_table(doc,
        ["Fonctionnalité", "Description"],
        [
            ["Boîte unifiée",         "Vue consolidée de tous les messages actifs, tous dossiers confondus"],
            ["Fil par dossier",       "Historique chronologique des échanges par dossier"],
            ["Pièces jointes",        "Envoi et réception de fichiers (PDF, images, documents)"],
            ["Indicateur de lecture", "Confirmation visuelle que le débiteur a lu le message"],
            ["Notifications",         "Alertes lors de nouveaux messages entrants"],
        ]
    )

    add_heading(doc, "8.2 Envoyer un message", level=2, color=TEAL)
    add_numbered(doc, "Accédez au module Communications ou ouvrez un dossier → onglet Messages")
    add_numbered(doc, "Sélectionnez la conversation ou le dossier cible")
    add_numbered(doc, "Rédigez votre message dans la zone de texte")
    add_numbered(doc, "Ajoutez des pièces jointes si nécessaire (glisser-déposer ou bouton Joindre)")
    add_numbered(doc, "Cliquez sur Envoyer")

    add_note_box(doc,
        "Le débiteur est notifié par email lorsqu'il reçoit un nouveau message. "
        "Il peut y répondre depuis son portail client ou par email.",
        type_="info")

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 9. TRÉSORERIE
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "9. Module Trésorerie", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "Le module Trésorerie offre une comptabilité simplifiée pour suivre l'ensemble "
        "des flux financiers liés aux activités de recouvrement : encaissements, "
        "décaissements, transferts inter-comptes et reversements aux clients créanciers.", size=11)

    add_heading(doc, "9.1 Gestion des comptes", level=2, color=TEAL)
    add_table(doc,
        ["Type de compte", "Description"],
        [
            ["Bancaire",      "Compte en banque classique"],
            ["Caisse",        "Espèces en caisse"],
            ["Mobile Money",  "Compte de paiement mobile (Orange Money, Airtel Money, etc.)"],
            ["Autre",         "Tout autre type de compte"],
        ]
    )
    add_paragraph(doc,
        "Chaque compte dispose d'un solde calculé en temps réel à partir des mouvements enregistrés. "
        "La plateforme supporte plusieurs devises simultanément.", size=11)

    add_heading(doc, "9.2 Journal des mouvements", level=2, color=TEAL)
    add_table(doc,
        ["Colonne", "Description"],
        [
            ["Date valeur", "Date effective du mouvement financier"],
            ["Direction",   "Entrée (IN) = encaissement — Sortie (OUT) = décaissement"],
            ["Montant",     "Valeur du mouvement dans la devise du compte"],
            ["Compte",      "Compte débité ou crédité"],
            ["Libellé",     "Description du mouvement"],
            ["Référence",   "Numéro de référence (virement, reçu, etc.)"],
            ["Source",      "Origine : paiement client, saisie manuelle, transfert"],
            ["Statut",      "En attente, Confirmé, Annulé"],
        ]
    )

    add_heading(doc, "9.3 Saisir un mouvement manuel", level=2, color=TEAL)
    add_numbered(doc, "Cliquez sur Nouveau mouvement")
    add_numbered(doc, "Choisissez la direction : Entrée (encaissement) ou Sortie (décaissement)")
    add_numbered(doc, "Sélectionnez le compte concerné")
    add_numbered(doc, "Saisissez le montant et la devise")
    add_numbered(doc, "Renseignez la date valeur, le libellé et la référence")
    add_numbered(doc, "Choisissez le statut : En attente ou Confirmé")
    add_numbered(doc, "Enregistrez")

    add_heading(doc, "9.4 Effectuer un transfert inter-comptes", level=2, color=TEAL)
    add_numbered(doc, "Cliquez sur Transfert")
    add_numbered(doc, "Sélectionnez le compte source (qui sera débité)")
    add_numbered(doc, "Sélectionnez le compte destination (qui sera crédité)")
    add_numbered(doc, "Saisissez le montant, la devise et la date")
    add_numbered(doc, "Ajoutez une référence et des notes éventuelles")
    add_numbered(doc, "Confirmez — deux mouvements sont créés automatiquement : OUT (source) et IN (destination)")

    add_heading(doc, "9.5 Reversements clients", level=2, color=TEAL)
    add_paragraph(doc,
        "Les reversements permettent de reverser à un client créancier les fonds recouvrés "
        "en son nom, après déduction éventuelle des frais de gestion.", size=11)

    add_table(doc,
        ["Étape", "Action"],
        [
            ["1 — Créer",    "Menu Reversements → Nouveau reversement → choisir le client et le compte de débit"],
            ["2 — Alimenter","Ajouter les paiements éligibles (paiements du client non encore reversés)"],
            ["3 — Valider",  "Cliquer sur Valider — le reversement passe en statut Validé"],
            ["4 — Payer",    "Une fois le virement effectué, cliquer sur Marquer comme Payé"],
        ]
    )

    add_heading(doc, "9.6 Résumé financier", level=2, color=TEAL)
    add_paragraph(doc,
        "Le résumé financier présente une synthèse des entrées, sorties et solde net "
        "par devise, ainsi que le solde détaillé de chaque compte.", size=11)

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 10. PORTAIL CLIENT
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "10. Portail Client (Débiteurs)", level=1, color=NAVY)
    add_separator(doc)

    add_paragraph(doc,
        "Le portail client est une interface dédiée aux débiteurs. Il leur permet de suivre "
        "leurs dossiers, consulter les documents, échanger avec les agents de recouvrement "
        "et soumettre des demandes de support — le tout de manière sécurisée.",
        size=11)

    add_paragraph(doc, "URL d'accès : https://app.acx-acremac.net/fr/client", bold=True, size=11,
                  color=NAVY)

    add_heading(doc, "10.1 Tableau de bord client", level=2, color=TEAL)
    add_table(doc,
        ["Section", "Information affichée"],
        [
            ["Situation générale",  "Nombre de dossiers actifs, montant total dû, prochaine échéance"],
            ["Dossiers récents",    "Liste des derniers dossiers avec statut et montant"],
            ["Messages non lus",   "Aperçu des derniers messages reçus des agents"],
            ["Alertes",            "Notifications importantes (échéances proches, nouvelles actions)"],
        ]
    )

    add_heading(doc, "10.2 Mes dossiers", level=2, color=TEAL)
    add_paragraph(doc,
        "La liste des dossiers présente pour chaque dossier :", size=11)
    add_bullet(doc, "La référence unique et la description de la créance")
    add_bullet(doc, "Le montant initial et le solde restant dû")
    add_bullet(doc, "Le statut actuel du dossier")
    add_bullet(doc, "L'historique des paiements effectués")
    add_bullet(doc, "Les documents disponibles en téléchargement")

    add_heading(doc, "10.3 Messagerie", level=2, color=TEAL)
    add_numbered(doc, "Sélectionnez un dossier dans la liste")
    add_numbered(doc, "Accédez à l'onglet Messages")
    add_numbered(doc, "Consultez l'historique des échanges avec l'agent responsable")
    add_numbered(doc, "Rédigez votre réponse ou une nouvelle question")
    add_numbered(doc, "Joignez des documents si nécessaire")
    add_numbered(doc, "Cliquez sur Envoyer")

    add_heading(doc, "10.4 Tickets de support", level=2, color=TEAL)
    add_paragraph(doc,
        "Pour toute question, contestation ou demande particulière :", size=11)
    add_numbered(doc, "Menu → Support → Nouveau ticket")
    add_numbered(doc, "Sélectionnez la catégorie : Question, Contestation, Demande de délai, Autre")
    add_numbered(doc, "Décrivez précisément votre demande")
    add_numbered(doc, "Joignez des pièces justificatives si nécessaire")
    add_numbered(doc, "Soumettez le ticket — un numéro de suivi vous est attribué")
    add_numbered(doc, "Suivez l'avancement dans la liste Mes tickets")

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 11. PARAMÈTRES
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "11. Paramètres et gestion du compte", level=1, color=NAVY)
    add_separator(doc)

    add_heading(doc, "11.1 Modifier mon profil", level=2, color=TEAL)
    add_numbered(doc, "Cliquez sur votre nom en haut à droite de l'écran")
    add_numbered(doc, "Sélectionnez Mon profil")
    add_numbered(doc, "Modifiez les informations souhaitées : prénom, nom, téléphone, département")
    add_numbered(doc, "Cliquez sur Enregistrer")

    add_heading(doc, "11.2 Changer mon mot de passe", level=2, color=TEAL)
    add_numbered(doc, "Accédez à Mon profil → Sécurité")
    add_numbered(doc, "Saisissez votre mot de passe actuel")
    add_numbered(doc, "Saisissez et confirmez le nouveau mot de passe")
    add_numbered(doc, "Le mot de passe doit contenir au minimum 8 caractères")
    add_numbered(doc, "Cliquez sur Mettre à jour")

    add_note_box(doc,
        "Pour des raisons de sécurité, choisissez un mot de passe unique, combinant lettres "
        "majuscules, minuscules, chiffres et caractères spéciaux. "
        "Ne partagez jamais votre mot de passe.",
        type_="warning")

    add_heading(doc, "11.3 Changer de langue", level=2, color=TEAL)
    add_paragraph(doc,
        "Le sélecteur de langue est disponible dans la barre de navigation supérieure. "
        "Cliquez sur le code langue actuel (FR ou EN) pour basculer vers l'autre langue. "
        "Le choix est mémorisé pour vos prochaines visites.", size=11)

    add_heading(doc, "11.4 Paramètres de l'organisation (Administrateurs uniquement)", level=2, color=TEAL)
    add_table(doc,
        ["Paramètre", "Description"],
        [
            ["Informations générales", "Nom, adresse, contacts, logo de l'organisation"],
            ["Devise par défaut",      "Devise utilisée pour les nouveaux dossiers"],
            ["Fuseau horaire",         "Paramétrage des dates et heures"],
            ["Gestion des utilisateurs","Inviter, désactiver, modifier les droits des membres"],
            ["Portfolios",             "Créer et gérer les portefeuilles de créances"],
        ]
    )

    add_page_break(doc)

    # ════════════════════════════════════════════════════════════════════════
    # 12. FAQ
    # ════════════════════════════════════════════════════════════════════════
    add_heading(doc, "12. Questions fréquentes", level=1, color=NAVY)
    add_separator(doc)

    faq = [
        ("J'ai oublié mon mot de passe, que faire ?",
         "Contactez votre administrateur ACX. Il peut réinitialiser votre mot de passe depuis "
         "l'espace Gestion des utilisateurs. Vous recevrez un email avec un lien de réinitialisation."),

        ("Je ne vois pas certains modules dans le menu.",
         "L'accès aux modules dépend de votre rôle. Si vous pensez manquer d'accès nécessaires "
         "à votre travail, contactez votre administrateur pour révision de vos permissions."),

        ("Comment télécharger les documents d'un dossier ?",
         "Ouvrez le dossier concerné, accédez à l'onglet Documents, puis cliquez sur l'icône de "
         "téléchargement à côté du document souhaité."),

        ("La plateforme est-elle accessible sur mobile ?",
         "Oui, l'interface est entièrement responsive. Elle s'adapte automatiquement aux smartphones "
         "et tablettes. Aucune application mobile à installer n'est nécessaire."),

        ("Comment savoir si un débiteur a lu mon message ?",
         "Un indicateur de lecture (icône checkmark double) s'affiche dans la conversation "
         "une fois que le débiteur a consulté le message depuis son portail."),

        ("Puis-je exporter les données en Excel ou PDF ?",
         "La fonctionnalité d'export est en cours de développement. En attendant, "
         "contactez ACREMAC à support@acremac.com pour un export personnalisé."),

        ("Comment contacter le support technique ?",
         "Envoyez un email à support@acremac.com en précisant : votre nom d'organisation, "
         "le problème rencontré avec une description détaillée, et si possible une capture d'écran."),

        ("Comment supprimer un dossier ?",
         "Les dossiers ne peuvent pas être supprimés pour des raisons de traçabilité. "
         "Vous pouvez les passer en statut Annulé ou Fermé selon le cas."),

        ("Les données sont-elles sauvegardées ?",
         "Oui, la base de données fait l'objet de sauvegardes régulières sur le serveur de production. "
         "Contactez ACREMAC pour toute demande de restauration de données."),
    ]

    for question, reponse in faq:
        p = add_paragraph(doc, "")
        r1 = p.add_run("Q : " + question)
        r1.bold = True
        r1.font.size = Pt(11)
        r1.font.color.rgb = NAVY

        p2 = add_paragraph(doc, "R : " + reponse, size=11, color=GRAY_DARK, space_before=2, space_after=10)

    # Pied de page
    add_paragraph(doc, "")
    add_separator(doc)
    add_table(doc,
        ["Contact", "Coordonnées"],
        [
            ["Support technique", "support@acremac.com"],
            ["Site web",          "acx-acremac.net"],
            ["Application",       "app.acx-acremac.net"],
        ],
        header_bg="2d9073"
    )

    add_paragraph(doc,
        "© 2026 ACREMAC — Tous droits réservés. "
        "Ce document est la propriété d'ACREMAC et ne peut être reproduit sans autorisation.",
        color=GRAY_MID, size=9, align=WD_ALIGN_PARAGRAPH.CENTER)

    doc.save("MANUEL_UTILISATEUR_ACX.docx")
    print("✓ MANUEL_UTILISATEUR_ACX.docx généré")


# ── Point d'entrée ─────────────────────────────────────────────────────────
if __name__ == "__main__":
    build_manuel_technique()
    build_manuel_utilisateur()
    print("\nTerminé. Les deux fichiers Word sont dans le dossier courant.")
