#!/usr/bin/env python3
"""Crée la fiche produit WooCommerce brouillon pour le module Pennylane × PrestaShop."""

from __future__ import annotations

import json
import sys
import uuid
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))

from article_studio.config import load_config
from article_studio.wp_client import _request, upload_media

ASSETS = ROOT / "exports" / "pennylane-product"
ZIP_PATH = ASSETS / "pennylane-1.2.0.zip"

PRODUCT_NAME = "Module PrestaShop synchronisation Pennylane — Clients et factures automatiques"
SLUG = "module-prestashop-synchronisation-pennylane"
SKU = "pennylane-1.2.0"

SHORT_DESCRIPTION = (
    "Connectez PrestaShop à Pennylane : à chaque statut de commande déclencheur, le module crée "
    "le client Pennylane et la facture (brouillon ou import PDF PrestaShop). Journal, renvoi manuel "
    "et lien PDF depuis la fiche commande. Compatible PS 1.7.8 à 9.1."
)

DESCRIPTION_HTML = """<h2>Vos ventes PrestaShop dans Pennylane, sans ressaisie</h2>
<p>Chaque commande validée, c'est un client à créer dans Pennylane, une facture à émettre, des montants à vérifier. Ce module automatise l'envoi des commandes PrestaShop vers <strong>Pennylane</strong> via l'API v2 — dès qu'un statut de commande configuré est atteint.</p>
<p><strong>Client</strong> : création ou réutilisation par référence externe PrestaShop.<br>
<strong>Facture</strong> : brouillon Pennylane généré depuis les lignes commande, ou import finalisé avec le PDF de facture PrestaShop et les montants exacts.</p>

<h2>Ce que le module fait concrètement</h2>
<ul>
<li>déclenche la synchronisation sur un ou plusieurs <strong>statuts de commande</strong> (paiement accepté, expédié, etc.),</li>
<li>crée ou retrouve le <strong>client Pennylane</strong> à partir des données de facturation PrestaShop,</li>
<li>génère une <strong>facture brouillon</strong> Pennylane (lignes produits, TVA, transport) ou importe la facture finalisée avec le PDF PrestaShop,</li>
<li>associe un <strong>modèle de facture Pennylane par boutique</strong> en mode multiboutique,</li>
<li>configure le <strong>délai de paiement</strong> (échéance en jours) sur les factures Pennylane,</li>
<li>enregistre chaque synchronisation dans une <strong>table de traçabilité</strong> (client ID, facture ID, statut, erreur),</li>
<li>affiche le statut Pennylane et un lien <strong>PDF facture</strong> sur la fiche commande back-office et front-office.</li>
</ul>

<h2>Interface de configuration</h2>
<p>Page native PrestaShop avec :</p>
<ul>
<li>saisie de la <strong>clé API Pennylane</strong> (ou variable <code>PENNYLANE_API_KEY</code> dans un fichier <code>.env</code>),</li>
<li>bouton <strong>Tester la connexion API</strong>,</li>
<li>sélection multiple des statuts déclencheurs,</li>
<li>choix du mode facture : <strong>brouillon</strong> ou <strong>import PDF finalisé</strong>,</li>
<li>mapping des <strong>modèles de facture Pennylane</strong> par boutique,</li>
<li><strong>journal Pennylane</strong> paginé (500 entrées max) avec niveaux info, succès, avertissement, erreur.</li>
</ul>

<h2>Fiche commande et renvoi manuel</h2>
<p>Sur chaque commande synchronisée, le module affiche dans le back-office :</p>
<ul>
<li>statut de synchronisation et identifiants Pennylane (client, facture),</li>
<li>bouton <strong>« Renvoyer vers Pennylane »</strong> pour forcer une nouvelle tentative,</li>
<li>lien de téléchargement de la <strong>facture Pennylane en PDF</strong> (front et back-office sécurisé).</li>
</ul>

<h2>Prérequis</h2>
<ul>
<li>extension PHP <strong>cURL</strong> activée,</li>
<li>compte Pennylane avec <strong>clé API v2</strong>,</li>
<li>PrestaShop avec génération de factures activée (mode import PDF).</li>
</ul>

<h2>Compatibilité</h2>
<ul>
<li>PrestaShop <strong>1.7.8 à 9.1</strong> (toutes versions mineures),</li>
<li><strong>multiboutique</strong> supporté (modèle de facture par boutique),</li>
<li>interface multilingue (FR),</li>
<li>développé en France par <strong>Latoutfrancais - Arnaud Merigeau</strong>.</li>
</ul>

<h2>Complément export comptable</h2>
<p>Ce module couvre le flux <strong>ventes → Pennylane</strong> en temps réel. Pour un export CSV comptable périodique (Sage, Cegid, Quadra…), consultez aussi le <a href="https://www.arnaud-merigeau.fr/produit/module-export-comptable-pour-prestashop/">module export comptable PrestaShop</a>.</p>

<h2>Conclusion</h2>
<p>Ce connecteur Pennylane pour PrestaShop supprime la double saisie entre votre boutique et votre outil comptable cloud : synchronisation fiable, journal détaillé, renvoi manuel et PDF accessible depuis la fiche commande.</p>
<p>Livraison immédiate du ZIP après achat, avec licence et mises à jour selon la durée choisie.</p>"""

YOAST_TITLE = "Module PrestaShop synchronisation Pennylane | Factures et clients auto"
YOAST_METADESC = (
    "Module PrestaShop pour synchroniser Pennylane : création client, facture brouillon ou import PDF, "
    "déclenchement par statut commande, journal et renvoi manuel. Compatible PS 1.7.8 à 9.1."
)
YOAST_FOCUS = "Module PrestaShop synchronisation Pennylane"

VARIATIONS = [
    ("6 mois", "99.94"),
    ("12 mois (25% d'économie)", "174.895"),
    ("24 mois (54% d'économie)", "195.8824"),
]

IMAGE_FILES = [
    ("product-pennylane-featured.png", "Module PrestaShop synchronisation Pennylane — clients et factures automatiques", True),
    ("product-pennylane-admin-config.png", "Back-office PrestaShop — configuration synchronisation Pennylane", False),
    ("product-pennylane-order.png", "Fiche commande PrestaShop — statut et facture Pennylane", False),
    ("product-pennylane-flow.png", "Schéma flux synchronisation PrestaShop vers Pennylane", False),
    ("product-pennylane-module.png", "Module PrestaShop Pennylane — icône", False),
]

DOWNLOAD_NAME = "module-synchronisation-pennylane-prestashop-1.2.0"


def post_json(base_url: str, user: str, password: str, path: str, payload: dict) -> dict:
    url = f"{base_url.rstrip('/')}{path}"
    _, data = _request(
        "POST",
        url,
        user,
        password,
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
    )
    return data


def put_json(base_url: str, user: str, password: str, path: str, payload: dict) -> dict:
    url = f"{base_url.rstrip('/')}{path}"
    _, data = _request(
        "PUT",
        url,
        user,
        password,
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
    )
    return data


def main() -> None:
    cfg = load_config()
    base = cfg.wp_base_url
    user = cfg.wp_user
    pwd = cfg.wp_application_password.replace(" ", "")

    if not ZIP_PATH.is_file():
        raise FileNotFoundError(f"Archive introuvable : {ZIP_PATH} — lancez package_pennylane.py")

    print("Upload des images…")
    image_ids: list[int] = []
    featured_id: int | None = None
    for filename, alt, is_featured in IMAGE_FILES:
        path = ASSETS / filename
        if not path.is_file():
            raise FileNotFoundError(f"Image introuvable : {path} — lancez generate_pennylane_product_assets.py")
        media = upload_media(base, user, pwd, path, alt_text=alt, title=alt)
        mid = int(media["id"])
        image_ids.append(mid)
        if is_featured:
            featured_id = mid
        print(f"  media {mid}: {filename}")

    print("Upload du ZIP…")
    zip_media = upload_media(
        base,
        user,
        pwd,
        ZIP_PATH,
        alt_text="Module PrestaShop synchronisation Pennylane v1.2.0",
        title=DOWNLOAD_NAME,
    )
    zip_url = zip_media.get("source_url") or zip_media.get("guid", {}).get("rendered", "")
    print(f"  zip URL: {zip_url}")

    print("Création du produit variable (brouillon)…")
    product_payload = {
        "name": PRODUCT_NAME,
        "slug": SLUG,
        "type": "variable",
        "status": "draft",
        "catalog_visibility": "visible",
        "description": DESCRIPTION_HTML,
        "short_description": SHORT_DESCRIPTION,
        "sku": SKU,
        "virtual": True,
        "downloadable": True,
        "downloads": [
            {
                "id": str(uuid.uuid4()),
                "name": DOWNLOAD_NAME,
                "file": zip_url,
            }
        ],
        "download_limit": -1,
        "download_expiry": -1,
        "tax_status": "taxable",
        "manage_stock": False,
        "categories": [{"id": 714}],
        "tags": [
            {"name": "prestashop"},
            {"name": "module prestashop"},
            {"name": "pennylane"},
            {"name": "comptabilité"},
            {"name": "facturation"},
            {"name": "synchronisation"},
            {"name": "export comptable"},
        ],
        "images": [{"id": i} for i in image_ids],
        "attributes": [
            {
                "id": 2,
                "position": 0,
                "visible": True,
                "variation": True,
                "options": [v[0] for v in VARIATIONS],
            },
            {
                "id": 3,
                "position": 1,
                "visible": False,
                "variation": False,
                "options": ["Conversions"],
            },
        ],
        "default_attributes": [
            {"id": 2, "name": "Durée du SAV et des mises à jour", "option": "6 mois"},
        ],
        "meta_data": [
            {"key": "_yoast_wpseo_title", "value": YOAST_TITLE},
            {"key": "_yoast_wpseo_metadesc", "value": YOAST_METADESC},
            {"key": "_yoast_wpseo_focuskw", "value": YOAST_FOCUS},
            {"key": "_yoast_wpseo_primary_product_cat", "value": "714"},
            {"key": "_amlicence_lm_enabled", "value": "yes"},
            {"key": "_amlicence_lm_activation_slots", "value": "1"},
            {"key": "_amlicence_lm_expiry_months", "value": "0"},
        ],
    }

    product = post_json(base, user, pwd, "/wp-json/wc/v3/products", product_payload)
    product_id = int(product["id"])
    print(f"Produit créé: id={product_id}")

    print("Création des variations…")
    for option, price in VARIATIONS:
        var_payload = {
            "regular_price": price,
            "virtual": True,
            "downloadable": True,
            "downloads": product_payload["downloads"],
            "attributes": [
                {
                    "id": 2,
                    "name": "Durée du SAV et des mises à jour",
                    "option": option,
                }
            ],
            "meta_data": [
                {"key": "_amlicence_lm_enabled", "value": "yes"},
                {"key": "_amlicence_lm_activation_slots", "value": "1"},
                {"key": "_amlicence_lm_expiry_months", "value": "0"},
            ],
        }
        var = post_json(
            base,
            user,
            pwd,
            f"/wp-json/wc/v3/products/{product_id}/variations",
            var_payload,
        )
        print(f"  variation {var['id']}: {option} → {price} €")

    print("Mise à jour ACF (meta WooCommerce) et image à la une…")
    changelog = (
        "<h3>Version 1.2.0 — 10/07/2026</h3><ul>"
        "<li>Modèles de facture Pennylane configurables par boutique (multiboutique)</li>"
        "<li>Chargement des modèles depuis l'API Pennylane v2</li></ul>"
        "<h3>Version 1.1.1</h3><ul>"
        "<li>Correction des enregistrements bloqués en statut pending lorsque la facture Pennylane existe déjà</li></ul>"
        "<h3>Version 1.1.0</h3><ul>"
        "<li>Affichage du lien PDF facture Pennylane sur la fiche commande (back-office et front-office)</li>"
        "<li>Hook displayAdminOrderMain et displayOrderDetail</li>"
        "<li>Stockage de l'URL PDF Pennylane en base</li></ul>"
        "<h3>Version 1.0.8</h3><ul>"
        "<li>Renforcement de l'installation SQL (tables de synchronisation et journal)</li></ul>"
        "<h3>Version 1.0.7</h3><ul>"
        "<li>Identifiants Pennylane en BIGINT pour les grands IDs API</li></ul>"
        "<h3>Version 1.0.6</h3><ul>"
        "<li>Synchronisation déclenchée uniquement par changement de statut (plus sur validation commande)</li>"
        "<li>Journal Pennylane intégré à la configuration</li>"
        "<li>Bouton renvoi manuel depuis la fiche commande</li>"
        "<li>Mode facture brouillon ou import PDF PrestaShop finalisé</li>"
        "<li>Compatibilité PrestaShop 1.7.8 à 9.1</li></ul>"
    )
    put_json(
        base,
        user,
        pwd,
        f"/wp-json/wc/v3/products/{product_id}",
        {
            "meta_data": [
                {"key": "cms", "value": ["PrestaShop"]},
                {"key": "versions", "value": "v1.7.8 à v9.1 toutes versions"},
                {"key": "langues_du_module", "value": ["FR"]},
                {"key": "derniere_mise_a_jour", "value": "20260710"},
                {"key": "version_du_module__theme", "value": "V1.2.0"},
                {"key": "niveau", "value": "Configuration requise (clé API Pennylane)"},
                {"key": "documentation", "value": "1"},
                {"key": "changelog", "value": changelog},
                {"key": "url_demo", "value": "https://demo-prestashop.bnpj9981.odns.fr/backoffice"},
                {"key": "identifiant_demo", "value": "demo@demo.fr"},
                {"key": "mot_de_passe_demo", "value": "demodemo"},
                {
                    "key": "infos_demo",
                    "value": (
                        "Module installé sur la démo. Configuration : Modules → Pennylane. "
                        "Nécessite une clé API Pennylane v2 pour tester la synchronisation réelle. "
                        "Définissez un statut déclencheur et passez une commande test en ce statut."
                    ),
                },
            ]
        },
    )
    try:
        put_json(
            base,
            user,
            pwd,
            f"/wp-json/wp/v2/product/{product_id}",
            {"excerpt": SHORT_DESCRIPTION, "featured_media": featured_id},
        )
        print("  excerpt + featured_media OK")
    except RuntimeError as e:
        print(f"  Avertissement WP: {e}")

    edit_url = f"{base}/wp-admin/post.php?post={product_id}&action=edit"
    print("\n--- Terminé ---")
    print(f"ID produit : {product_id}")
    print(f"Slug       : {SLUG}")
    print(f"Édition BO : {edit_url}")
    print(f"Aperçu     : {base}/produit/{SLUG}/?preview=true")


if __name__ == "__main__":
    main()
