#!/usr/bin/env python3
"""Audit 404 GSC — teste les URLs candidates et propose une action."""

from __future__ import annotations

import re
import urllib.error
import urllib.parse
import urllib.request
from dataclasses import dataclass

BASE = "https://www.arnaud-merigeau.fr"

# URLs réelles repérées (logs Googlebot + .htaccess cassé + crawl interne)
CANDIDATES: list[tuple[str, str]] = [
    # Portfolio / feeds
    ("/realisations/feed/", "feed archive portfolio"),
    ("/realisations/olow/feed/", "feed projet"),
    ("/realisations/marketplace-produits-locaux/feed/", "feed projet"),
    ("/realisations/new-york-french-connection/feed/", "feed projet supprimé"),
    ("/realisations/boutique-prestashop-soin-spa/", "projet retiré"),
    ("/realisations/theme-prestashop-wide/", "redirect htaccess cassé"),
    ("/realisations-sitemap.xml", "sitemap obsolète"),
    # Articles / slugs
    ("/10-themes-prestashop-1-8-gratuits-et-responsive", "slug article"),
    ("/10-themes-prestashop-1-7-gratuits-et-responsive/", "article existant"),
    ("/ajouter-recaptcha-prestashop-tuto-gratuitfeed/", "URL typo"),
    ("/ajouter-recaptcha-prestashop-tuto-gratuit/", "slug probable"),
    ("/migration-prestashop-1-7-vers-9-sans-perdre-seo/", "brouillon pilier"),
    ("/tarif-freelance-prestashop-2026/", "brouillon pilier"),
    # Catégories / pagination
    ("/blog/category/referencement/", "structure /blog/category/"),
    ("/category/referencement/", "structure WP"),
    ("/blog/category/vitesse-de-chargement/", "structure /blog/category/"),
    ("/articles/page/11/", "redirect legacy"),
    ("/articles/page/12/", "redirect legacy"),
    ("/articles/page/13/", "redirect legacy"),
    ("/blog/page/11/", "cible redirect articles"),
    ("/category/prestashop/page/17/", "pagination"),
    ("/tag/prestashop-2/page/15/", "pagination"),
    ("/boutique/page/3/", "pagination boutique"),
    # URLs datées
    ("/2009/12/03/multiwizz-ou-le-sms-gratuit/?cid=245", "redirect ?cid cassé"),
    ("/2009/12/03/multiwizz-ou-le-sms-gratuit/", "URL datée"),
    ("/multiwizz-ou-le-sms-gratuit/", "cible attendue"),
    ("/2009/07/multiwizz-ou-le-sms-gratuit/", "URL datée variante"),
    ("/2010/10/22/piles-plus/?cid=161", "redirect ?cid cassé"),
    ("/2010/10/22/piles-plus/", "URL datée"),
    ("/2011/07/14/20-themes-prestashop-1-3-1-4-gratuits/?cid=284", "redirect ?cid cassé"),
    ("/20-themes-prestashop-1-3-1-4-gratuits/", "cible attendue"),
    ("/2011/07/13/tuto-integration-du-bouton-google-1-dans-prestashop/", "URL datée"),
    ("/2012/02/02/rassurance-client-sur-votre-boutique-prestashop-5-points-importants", "sans slash final"),
    # Query legacy
    ("/?post_type=product&p=2196", "ID produit legacy"),
    ("/?post_type=portfolio&p=4124", "ID portfolio legacy"),
    ("/?p=15803", "brouillon"),
    ("/?author=2", "archive auteur par ID"),
    ("/author/amerigeau/", "archive auteur"),
    # Divers
    ("/boutique/theme-prestashop-1-4-wide/", "cible redirect theme"),
    ("/confidentialite/", "redirect mentions"),
    ("/a-propos", "page about"),
    ("/a-propos/", "page about"),
    ("/product-category-sitemap.xml", "sitemap WC"),
    ("/sitemap.xml", "sitemap racine"),
    ("/sitemap_index.xml", "sitemap Yoast"),
]


@dataclass
class Result:
    path: str
    note: str
    status: int | str
    final_url: str
    action: str


def fetch(path: str) -> tuple[int | str, str, str]:
    url = BASE + path if path.startswith("/") else path
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0 GSC-404-Audit/1.0"})
    try:
        with urllib.request.urlopen(req, timeout=20) as resp:
            return resp.status, resp.geturl(), resp.headers.get("Location", "")
    except urllib.error.HTTPError as e:
        return e.code, url, e.headers.get("Location", "")
    except Exception as exc:
        return str(exc), url, ""


def suggest(path: str, status: int | str, final: str, note: str) -> str:
    if status in (301, 302, 308):
        if final.rstrip("/") != (BASE + path.split("?")[0]).rstrip("/"):
            return f"Redirection OK → {final}"
        return f"Redirige mais vérifier cible: {final}"
    if status == 200:
        return "OK — aucune action"
    if status == 404:
        if "feed" in path:
            return "301 → /realisations/ ou activer feed + noindex"
        if "soin-spa" in path or "theme-prestashop-wide" in path:
            return "301 → /realisations/"
        if "1-8-gratuits" in path:
            return "301 → /10-themes-prestashop-1-7-gratuits-et-responsive/"
        if "recaptcha" in path and "feed" in path:
            return "301 → /ajouter-recaptcha-prestashop-tuto-gratuit/"
        if "migration-prestashop" in path or "tarif-freelance" in path:
            return "Publier le brouillon OU retirer les liens internes en attendant"
        if "/blog/category/" in path:
            slug = path.split("/")[-2] if path.endswith("/") else path.split("/")[-1]
            return f"301 → /category/{slug}/"
        if "realisations-sitemap" in path:
            return "301 → /portfolio-sitemap.xml"
        if "articles/page/" in path:
            n = re.search(r"/page/(\d+)/", path)
            return f"RewriteRule articles → blog (page {n.group(1) if n else '?'})"
        if re.match(r"/\d{4}/", path):
            slug = path.rstrip("/").split("/")[-1].split("?")[0]
            return f"301 → /{slug}/ (RewriteRule date legacy)"
        if "?post_type=" in path or "?p=" in path:
            return "301 → /boutique/ ou /blog/ (IDs obsolètes)"
        if "boutique/theme-prestashop" in path:
            return "301 → /boutique/ (produit retiré)"
        if path in ("/a-propos", "/a-propos/"):
            return "301 → /savoir-faire/ ou /contact/"
        if "product-category-sitemap" in path:
            return "Ignorer (scan bot) ou 410"
        return "Créer redirection 301 manuelle"
    if status == 403:
        return "Bloquer / ignorer (bot)"
    return "À analyser"


def main() -> None:
    results: list[Result] = []
    for path, note in CANDIDATES:
        status, final, _ = fetch(path)
        results.append(Result(path, note, status, final, suggest(path, status, final, note)))

    need_action = [r for r in results if "OK — aucune" not in r.action and "Ignorer" not in r.action]

    print(f"Testées: {len(results)} | Actions recommandées: {len(need_action)}\n")
    print("STATUS\tACTION\tURL")
    for r in sorted(need_action, key=lambda x: str(x.status)):
        print(f"{r.status}\t{r.action}\t{r.path}")

    print("\n--- Pages OK (200 ou redirect sain) ---")
    for r in results:
        if r not in need_action:
            print(f"{r.status}\t{r.path} → {r.final_url if r.final_url != BASE + r.path else '200'}")


if __name__ == "__main__":
    main()
