#!/usr/bin/env python3
"""
ICAC — Script de renommage assisté de documents PDF.

Analyse les PDFs d'un dossier source, extrait la première page,
propose un nom selon la convention ICAC, demande confirmation.

Convention de nommage :
  {type}_{annee}_{description}.pdf

Exemples :
  compte_gestion_2022_besseges.pdf
  pv_conseil_2026_02_24.pdf
  budget_primitif_2026.pdf
  bulletin_municipal_2026_01.pdf
  marche_voirie_2026_colas.pdf

Usage :
  python scripts/rename_docs.py /chemin/vers/dossier
  python scripts/rename_docs.py ~/Documents/mairie/
"""

import sys
import shutil
import re
from pathlib import Path

# --- Optional PyMuPDF for text extraction ---
try:
    import fitz  # PyMuPDF
    HAS_FITZ = True
except ImportError:
    HAS_FITZ = False

# --- Config ---
DST_DIR = Path(__file__).resolve().parent.parent / "data" / "documents"
COMMUNE = "besseges"

# --- Type detection patterns ---
TYPE_PATTERNS = [
    (r"compte.*(gestion|administratif)|cg[_\s]|ca[_\s]", "compte_gestion"),
    (r"budget.*primitif|bp[_\s]", "budget_primitif"),
    (r"budget.*suppl|bs[_\s]|d[ée]cision.*modif", "budget_supplementaire"),
    (r"proc[eè]s.?verbal|pv[_\s]|conseil.*municipal", "pv_conseil"),
    (r"bulletin.*municipal|bm[_\s]", "bulletin_municipal"),
    (r"d[ée]lib[ée]ration", "deliberation"),
    (r"march[ée]", "marche"),
    (r"contrat|convention", "contrat"),
    (r"rapport.*activit|rapport.*annuel", "rapport"),
    (r"arr[eê]t[ée]", "arrete"),
    (r"facture|mandat", "facture"),
    (r"subvention|detr|dsil|fctva", "subvention"),
]

# --- Year extraction ---
YEAR_RE = re.compile(r"20[12]\d")

# --- Month patterns ---
MONTHS_FR = {
    "janvier": "01", "février": "02", "mars": "03",
    "avril": "04", "mai": "05", "juin": "06",
    "juillet": "07", "août": "08", "septembre": "09",
    "octobre": "10", "novembre": "11", "décembre": "12",
    "jan": "01", "fev": "02", "fév": "02", "mar": "03",
    "avr": "04", "jui": "06", "jul": "07",
    "aou": "08", "aoû": "08", "sep": "09",
    "oct": "10", "nov": "11", "dec": "12", "déc": "12",
}
MONTH_RE = re.compile(
    r"\b(" + "|".join(MONTHS_FR.keys()) + r")\b",
    re.IGNORECASE
)
DATE_RE = re.compile(r"(\d{1,2})[/\-.](\d{1,2})[/\-.](\d{4})")


def extract_first_page_text(pdf_path: Path) -> str:
    """Extract text from first page of PDF."""
    if not HAS_FITZ:
        return f"[PyMuPDF non installé — nom du fichier : {pdf_path.name}]"
    try:
        doc = fitz.open(str(pdf_path))
        if len(doc) == 0:
            return "[PDF vide]"
        text = doc[0].get_text("text").strip()
        doc.close()
        return text[:800] if text else "[Page vide]"
    except Exception as e:
        return f"[Erreur lecture : {e}]"


def detect_type(text: str, filename: str) -> str:
    """Detect document type from text content and filename."""
    combined = (text + " " + filename).lower()
    for pattern, doc_type in TYPE_PATTERNS:
        if re.search(pattern, combined):
            return doc_type
    return "document"


def extract_year(text: str, filename: str) -> str:
    """Extract year from text or filename."""
    # Try filename first
    m = YEAR_RE.search(filename)
    if m:
        return m.group()
    # Then content
    m = YEAR_RE.search(text)
    if m:
        return m.group()
    return ""


def extract_date_suffix(text: str, filename: str) -> str:
    """Extract date suffix (month or full date) for PV/bulletins."""
    combined = (text + " " + filename).lower()

    # Try DD/MM/YYYY pattern
    m = DATE_RE.search(combined)
    if m:
        day, month, year = m.groups()
        return f"{year}_{month.zfill(2)}_{day.zfill(2)}"

    # Try month name
    m = MONTH_RE.search(combined)
    if m:
        month_num = MONTHS_FR.get(m.group().lower(), "")
        year = extract_year(text, filename)
        if year and month_num:
            return f"{year}_{month_num}"

    return ""


def suggest_name(pdf_path: Path, text: str) -> str:
    """Suggest a standardized filename."""
    filename = pdf_path.name
    doc_type = detect_type(text, filename)
    year = extract_year(text, filename)

    # For PV and bulletins, try to get more specific date
    if doc_type in ("pv_conseil", "bulletin_municipal", "deliberation"):
        date_suffix = extract_date_suffix(text, filename)
        if date_suffix:
            return f"{doc_type}_{date_suffix}.pdf"

    if year:
        return f"{doc_type}_{year}_{COMMUNE}.pdf"

    return f"{doc_type}_{COMMUNE}.pdf"


def main():
    if len(sys.argv) < 2:
        print("Usage : python scripts/rename_docs.py /chemin/vers/dossier")
        print("        python scripts/rename_docs.py ~/Documents/mairie/")
        sys.exit(1)

    src_dir = Path(sys.argv[1]).expanduser().resolve()
    if not src_dir.is_dir():
        print(f"Erreur : {src_dir} n'est pas un dossier valide.")
        sys.exit(1)

    DST_DIR.mkdir(parents=True, exist_ok=True)

    pdfs = sorted(src_dir.glob("*.pdf"))
    if not pdfs:
        print(f"Aucun PDF trouvé dans {src_dir}")
        sys.exit(0)

    print(f"\n{'=' * 60}")
    print(f"  ICAC — Renommage assisté de documents")
    print(f"  Source  : {src_dir}")
    print(f"  Dest.   : {DST_DIR}")
    print(f"  PDFs    : {len(pdfs)} fichier(s)")
    if not HAS_FITZ:
        print(f"  ⚠ PyMuPDF non installé — analyse par nom de fichier uniquement")
    print(f"{'=' * 60}")

    copied = 0
    for pdf in pdfs:
        text = extract_first_page_text(pdf)
        suggested = suggest_name(pdf, text)

        print(f"\n{'─' * 50}")
        print(f"  Fichier  : {pdf.name}")
        print(f"  Taille   : {pdf.stat().st_size // 1024} Ko")
        if HAS_FITZ:
            # Show first 200 chars of extracted text
            preview = text[:200].replace('\n', ' ').strip()
            print(f"  Extrait  : {preview}")
        print(f"  Proposé  : \033[1;33m{suggested}\033[0m")

        user_input = input("  Nouveau nom (Enter = accepter, 's' = skip) : ").strip()

        if user_input.lower() == 's':
            print("  → Ignoré.")
            continue

        if user_input:
            new_name = user_input
        else:
            new_name = suggested

        if not new_name.endswith(".pdf"):
            new_name += ".pdf"

        dest = DST_DIR / new_name

        # Avoid overwriting
        if dest.exists():
            print(f"  ⚠ {dest.name} existe déjà !")
            overwrite = input("  Écraser ? (o/N) : ").strip().lower()
            if overwrite != 'o':
                print("  → Ignoré.")
                continue

        shutil.copy2(pdf, dest)
        print(f"  → Copié : \033[1;32m{dest}\033[0m")
        copied += 1

    print(f"\n{'=' * 60}")
    print(f"  Terminé : {copied}/{len(pdfs)} fichier(s) copiés")
    print(f"  Dossier : {DST_DIR}")
    print(f"{'=' * 60}\n")


if __name__ == "__main__":
    main()
