#!/usr/bin/env python3
"""Prepare Madrassa Sahaba public-page images for web upload."""

from __future__ import annotations

from pathlib import Path

from PIL import Image, ImageOps


PROJECT_DIR = Path(__file__).resolve().parents[1]
SOURCE_DIR = PROJECT_DIR / "designs" / "sahaba" / "images"
OUTPUT_DIR = SOURCE_DIR / "optimized"

SPECS = [
    {
        "source": "hero_sahaba.png",
        "stem": "hero_sahaba",
        "max_width": 1600,
        "usage": "Image hero à téléverser dans le champ “Image hero ou flyer public”.",
    },
    {
        "source": "presentation_2.png",
        "stem": "presentation_2",
        "max_width": 1400,
        "usage": "Image de présentation à téléverser dans “Image présentation 1”.",
    },
    {
        "source": "presentation_3.png",
        "stem": "presentation_3",
        "max_width": 1400,
        "usage": "Image de présentation à téléverser dans “Image présentation 2”.",
    },
]


def resize_max_width(image: Image.Image, max_width: int) -> Image.Image:
    if image.width <= max_width:
        return image

    ratio = max_width / image.width
    size = (max_width, round(image.height * ratio))

    return image.resize(size, Image.Resampling.LANCZOS)


def open_for_web(path: Path) -> Image.Image:
    image = Image.open(path)
    image = ImageOps.exif_transpose(image)

    if image.mode not in ("RGB", "RGBA"):
        image = image.convert("RGB")

    return image


def save_webp(image: Image.Image, path: Path) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    image.save(path, "WEBP", quality=84, method=6)


def save_jpeg(image: Image.Image, path: Path) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    rgb = image.convert("RGB")
    rgb.save(path, "JPEG", quality=84, optimize=True, progressive=True)


def dimensions(path: Path) -> tuple[int, int]:
    with Image.open(path) as image:
        return image.size


def write_readme(created: list[tuple[Path, str]]) -> None:
    lines = [
        "# Images optimisées Sahaba",
        "",
        "Les originaux restent conservés dans `designs/sahaba/images`.",
        "",
        "Pour l’interface `http://127.0.0.1:8000/platform/ecoles/5/edit`, privilégier les fichiers `.webp` générés ici. Les `.jpg` servent de secours si un navigateur ou un outil externe pose problème.",
        "",
        "## Fichiers",
        "",
        "| Fichier | Dimensions | Usage recommandé |",
        "| --- | ---: | --- |",
    ]

    for path, usage in sorted(created, key=lambda item: item[0].name):
        width, height = dimensions(path)
        lines.append(f"| `{path.name}` | {width} x {height} px | {usage} |")

    lines.extend([
        "",
        "## Correspondance upload",
        "",
        "- `hero_sahaba.webp` -> Image hero ou flyer public.",
        "- `presentation_2.webp` -> Image présentation 1.",
        "- `presentation_3.webp` -> Image présentation 2.",
        "- Le champ Image présentation 3 peut rester vide pour l’instant.",
    ])

    (OUTPUT_DIR / "README.md").write_text("\n".join(lines) + "\n", encoding="utf-8")


def main() -> None:
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    created: list[tuple[Path, str]] = []

    for spec in SPECS:
        source = SOURCE_DIR / spec["source"]
        if not source.is_file():
            raise SystemExit(f"Image source introuvable : {source}")

        image = resize_max_width(open_for_web(source), spec["max_width"])

        webp = OUTPUT_DIR / f"{spec['stem']}.webp"
        jpg = OUTPUT_DIR / f"{spec['stem']}.jpg"
        save_webp(image, webp)
        save_jpeg(image, jpg)
        created.append((webp, spec["usage"]))
        created.append((jpg, spec["usage"].replace("téléverser", "téléverser comme secours")))

    write_readme(created)

    print("Images générées :")
    for path, _usage in sorted(created, key=lambda item: item[0].name):
        width, height = dimensions(path)
        print(f"- {path.relative_to(PROJECT_DIR)}: {width}x{height}, {path.stat().st_size} bytes")
    print(f"- {(OUTPUT_DIR / 'README.md').relative_to(PROJECT_DIR)}")


if __name__ == "__main__":
    main()
