#!/usr/bin/env python3
"""Publie l'article Skimmer PrestaShop 2026 + images + posts social + IndexNow."""

from __future__ import annotations

import importlib.util
import json
import sys
import urllib.error
import urllib.parse
import urllib.request
from pathlib import Path

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

from article_studio.config import load_config  # noqa: E402
from article_studio import wp_client  # noqa: E402

INDEXNOW_KEY = "5f8e4b8b35b143b988c607967725f4b9"
HOST = "www.arnaud-merigeau.fr"


def load_draft_module():
    path = ROOT / "scripts" / "create_pillar_skimmer_prestashop_draft.py"
    spec = importlib.util.spec_from_file_location("skimmer_draft", path)
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod


def get_or_create_tag(base: str, user: str, password: str, name: str) -> int:
    slug = name.lower().replace(" ", "-")
    lookup = f"{base}/wp-json/wp/v2/tags?slug={urllib.parse.quote(slug)}"
    _, tags = wp_client._request("GET", lookup, user, password)
    if tags:
        return int(tags[0]["id"])
    _, tag = wp_client._request(
        "POST",
        f"{base}/wp-json/wp/v2/tags",
        user,
        password,
        data=json.dumps({"name": name, "slug": slug}).encode("utf-8"),
        headers={"Content-Type": "application/json"},
    )
    return int(tag["id"])


def upload_image(
    base: str,
    user: str,
    password: str,
    path: Path,
    *,
    alt: str,
    title: str,
) -> tuple[str, int | None]:
    if not path.is_file():
        raise FileNotFoundError(f"Image introuvable : {path}")
    print(f"Upload : {path.name}")
    media = wp_client.upload_media(
        base,
        user,
        password,
        path,
        alt_text=alt,
        title=title,
    )
    url = media.get("source_url") or media.get("guid", {}).get("rendered", "")
    media_id = media.get("id")
    print(f"  media id={media_id} — {url}")
    return url, media_id


def ping_indexnow(url: str) -> None:
    payload = {
        "host": HOST,
        "key": INDEXNOW_KEY,
        "keyLocation": f"https://{HOST}/{INDEXNOW_KEY}.txt",
        "urlList": [url],
    }
    req = urllib.request.Request(
        "https://api.indexnow.org/indexnow",
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json; charset=utf-8"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            print(f"IndexNow: HTTP {resp.status}")
    except urllib.error.HTTPError as e:
        print(f"IndexNow: HTTP {e.code}")


def save_social_exports(article_url: str, draft) -> Path:
    out = ROOT / "exports" / "skimmer-prestashop-2026"
    social = out / "social"
    social.mkdir(parents=True, exist_ok=True)
    posts = {
        "linkedin.txt": draft.SOCIAL_LINKEDIN,
        "x.txt": draft.SOCIAL_X,
        "facebook.txt": draft.SOCIAL_FACEBOOK,
        "instagram.txt": draft.SOCIAL_INSTAGRAM,
        "newsletter.txt": draft.SOCIAL_NEWSLETTER,
    }
    for name, text in posts.items():
        (social / name).write_text(text.format(url=article_url) + "\n", encoding="utf-8")
    (out / "README.txt").write_text(
        f"Article publié : {article_url}\n\n"
        "Posts prêts à coller :\n"
        "- social/linkedin.txt\n"
        "- social/x.txt\n"
        "- social/facebook.txt\n"
        "- social/instagram.txt\n"
        "- social/newsletter.txt\n",
        encoding="utf-8",
    )
    return out


def main() -> int:
    draft = load_draft_module()
    cfg = load_config()
    base = cfg.wp_base_url.rstrip("/")

    img_hero, featured_id = upload_image(
        base,
        cfg.wp_user,
        cfg.wp_application_password,
        draft.IMG_HERO_LOCAL,
        alt="Skimmer PrestaShop 2026 — alerte sécurité et détection du malware invisible",
        title="Skimmer PrestaShop 2026 hero",
    )
    img_test, _ = upload_image(
        base,
        cfg.wp_user,
        cfg.wp_application_password,
        draft.IMG_TEST_LOCAL,
        alt="Schéma du protocole de test anti-skimmer PrestaShop en trois étapes",
        title="Skimmer PrestaShop test procédure",
    )
    img_head, _ = upload_image(
        base,
        cfg.wp_user,
        cfg.wp_application_password,
        draft.IMG_HEAD_LOCAL,
        alt="Arborescence du fichier head.tpl PrestaShop à inspecter en priorité",
        title="Skimmer PrestaShop head.tpl inspection",
    )
    img_emergency, _ = upload_image(
        base,
        cfg.wp_user,
        cfg.wp_application_password,
        draft.IMG_EMERGENCY_LOCAL,
        alt="Protocole d'urgence en cas de boutique PrestaShop compromise par un skimmer",
        title="Skimmer PrestaShop protocole urgence",
    )

    content = draft.build_content(img_hero, img_test, img_head, img_emergency)
    tag_ids = [
        get_or_create_tag(base, cfg.wp_user, cfg.wp_application_password, t)
        for t in draft.TAG_NAMES
    ]

    payload = {
        "title": draft.TITLE,
        "content": content,
        "excerpt": draft.EXCERPT,
        "status": "publish",
        "slug": draft.SLUG,
        "author": cfg.wp_author_id,
        "categories": draft.CATEGORY_IDS,
        "tags": tag_ids,
        "meta": {
            "_yoast_wpseo_title": draft.YOAST_TITLE,
            "_yoast_wpseo_metadesc": draft.YOAST_DESC,
            "_yoast_wpseo_focuskw": draft.FOCUS,
            "_yoast_wpseo_linkdex": "75",
        },
    }
    if featured_id:
        payload["featured_media"] = featured_id

    _, post = wp_client._request(
        "POST",
        f"{base}/wp-json/wp/v2/posts",
        cfg.wp_user,
        cfg.wp_application_password,
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
    )

    article_url = post.get("link", f"{base}/{draft.SLUG}/")
    print(f"Publié — ID {post.get('id')} — {article_url}")

    out_dir = save_social_exports(article_url, draft)
    print(f"Posts social : {out_dir / 'social'}/")

    ping_indexnow(article_url)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
