"""Render PWA icons deterministically from the brand wordmark.

LD010 follow-up — Lighthouse PWA audit and Android install banners want PNG
icons in 192×192 + 512×512 (regular) and a 512×512 maskable icon that respects
an 80% safe zone.

Outputs:
  static/img/brand/pwa-192.png
  static/img/brand/pwa-512.png
  static/img/brand/pwa-maskable-512.png

Run with:
  docker compose exec web python manage.py generate_pwa_icons
"""
from __future__ import annotations

from pathlib import Path

from django.conf import settings
from django.core.management.base import BaseCommand
from PIL import Image, ImageDraw, ImageFont

BRAND_BG = "#0F4C2A"  # ruforum-primary
BRAND_FG = "#FFFFFF"

_FONT_CANDIDATES = (
    "/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf",
    "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
)


def _load_font(size: int) -> ImageFont.ImageFont:
    for path in _FONT_CANDIDATES:
        if Path(path).exists():
            return ImageFont.truetype(path, size=size)
    # Last resort — PIL bitmap default. Won't look great but won't crash.
    return ImageFont.load_default()


def _draw_wordmark(canvas_size: int, safe_fraction: float = 1.0) -> Image.Image:
    """Render a square canvas with the 'IILMP' wordmark centered.

    safe_fraction < 1.0 shrinks the text to fit within a centred safe zone,
    which Android maskable masks may crop into a circle / squircle.
    """
    img = Image.new("RGB", (canvas_size, canvas_size), BRAND_BG)
    draw = ImageDraw.Draw(img)

    # Pick a font size that fills the safe zone width with margin.
    target_width = canvas_size * safe_fraction * 0.78
    font_size = canvas_size  # start big, shrink
    font = _load_font(font_size)
    text = "IILMP"
    while font_size > 8:
        bbox = draw.textbbox((0, 0), text, font=font)
        width = bbox[2] - bbox[0]
        if width <= target_width:
            break
        font_size -= 4
        font = _load_font(font_size)

    bbox = draw.textbbox((0, 0), text, font=font)
    width = bbox[2] - bbox[0]
    height = bbox[3] - bbox[1]
    x = (canvas_size - width) // 2 - bbox[0]
    y = (canvas_size - height) // 2 - bbox[1]
    draw.text((x, y), text, fill=BRAND_FG, font=font)

    return img


class Command(BaseCommand):
    help = "Generate PWA icons (192, 512, 512-maskable) into static/img/brand/."

    def handle(self, *args, **options):
        out_dir = Path(settings.BASE_DIR) / "static" / "img" / "brand"
        out_dir.mkdir(parents=True, exist_ok=True)

        artifacts = [
            ("pwa-192.png", 192, 1.0),
            ("pwa-512.png", 512, 1.0),
            # Maskable: keep content within centre 80% so OS masks don't clip
            # the wordmark when they crop the icon into a circle / squircle.
            ("pwa-maskable-512.png", 512, 0.80),
        ]
        for filename, size, safe in artifacts:
            img = _draw_wordmark(size, safe_fraction=safe)
            path = out_dir / filename
            img.save(path, format="PNG", optimize=True)
            self.stdout.write(self.style.SUCCESS(f"wrote {path} ({size}x{size}, safe={safe:.2f})"))
