#!/usr/bin/env python3
"""Convert the canonical "rounded-2xl border-dashed bg-white px-6 py-16 text-center"
empty-state block in apps/rep templates into ``components/empty_state.html``.

Pattern matched (multiline regex):
    <div class="rounded-2xl border border-dashed border-ruforum-border bg-white px-6 py-16 text-center">
      <div class="mx-auto mb-5 flex h-14 w-14 items-center justify-center rounded-full bg-ruforum-surface-warm">
        <svg ...><path ... d="<ICON>"/></svg>
      </div>
      <p class="font-display text-xl font-semibold text-ruforum-text">HEADING</p>
      <p class="...text-ruforum-text-muted">SUBTEXT</p>
      <a class="btn-primary ..." href="URL">LABEL</a>
    </div>

Run: python scripts/migrate_empty_states_rep.py [--dry-run]

Skips any block that contains Django ``{% if %}`` branches inside (manual cases).
Only touches `<div>`-wrapped blocks; the `<section>` variant in `forum_list.html`
was migrated by hand.
"""
from __future__ import annotations

import argparse
import re
import sys
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parent.parent

PATTERN = re.compile(
    r'<div class="rounded-2xl border border-dashed border-ruforum-border bg-white px-\d+ py-\d+ text-center">\s*'
    r'<div class="mx-auto mb-\d+ flex h-\d+ w-\d+ items-center justify-center rounded-full bg-ruforum-surface-warm">\s*'
    r'<svg[^>]*aria-hidden="true">\s*'
    r'<path[^/]*d="(?P<icon>[^"]+)"[^/]*/>\s*'
    r'</svg>\s*'
    r'</div>\s*'
    r'<p class="font-display text-(?:xl|lg|base) font-semibold text-ruforum-text">(?P<heading>[^<]+)</p>\s*'
    r'<p class="[^"]*text-ruforum-text-muted[^"]*">\s*(?P<subtext>[^<{]+?)\s*</p>\s*'
    r'(?P<cta>(?:<a [^>]+>[^<]+</a>\s*)*)?'
    r'</div>',
    re.DOTALL,
)

ANCHOR_RE = re.compile(r'<a [^>]*href="\{% url (?P<urlname>[^\s%]+(?: [^%]+)?) %\}"[^>]*>(?P<label>[^<]+)</a>')


def transform(path: Path) -> tuple[bool, str]:
    text = path.read_text(encoding="utf-8")
    changed = False

    def repl(match):
        nonlocal changed
        # Skip if there is any {% if %} inside the matched block — those are
        # branchy and should be hand-migrated like forum_list.html.
        block = match.group(0)
        if "{% if " in block:
            return block
        icon = match.group("icon").strip()
        heading = match.group("heading").strip()
        subtext = match.group("subtext").strip()
        cta_block = (match.group("cta") or "").strip()

        anchors = ANCHOR_RE.findall(cta_block)
        # Build {% url %} expression -> 'as varname' chain so the include can
        # consume them without inline {% url %} (empty_state.html does not
        # accept tag arguments inside `with`).
        if not anchors:
            return (
                f'{{% include "components/empty_state.html" with '
                f'heading="{heading}" subtext="{subtext}" '
                f'icon_path="{icon}" %}}'
            )
        if len(anchors) >= 1:
            primary_url, primary_label = anchors[0]
            secondary_url = secondary_label = None
            if len(anchors) >= 2:
                secondary_url, secondary_label = anchors[1]

        # Inline {% url %} into the include via {% url ... as ... %} blocks
        # placed before the include.
        var_lines = []
        var_lines.append(f"{{% url {primary_url} as _empty_primary_url %}}")
        if secondary_url:
            var_lines.append(f"{{% url {secondary_url} as _empty_secondary_url %}}")

        include_args = (
            f'heading="{heading}" subtext="{subtext}" '
            f'icon_path="{icon}" '
            f'primary_url=_empty_primary_url primary_label="{primary_label}"'
        )
        if secondary_url:
            include_args += f' secondary_url=_empty_secondary_url secondary_label="{secondary_label}"'

        out = "\n".join(var_lines) + "\n"
        out += f'{{% include "components/empty_state.html" with {include_args} %}}'
        changed_local = True
        return out

    new_text = PATTERN.sub(repl, text)
    if new_text != text:
        changed = True
    return changed, new_text


def main(argv=None):
    parser = argparse.ArgumentParser()
    parser.add_argument("--dry-run", action="store_true")
    args = parser.parse_args(argv)

    files = sorted((REPO_ROOT / "apps" / "rep").rglob("*.html"))
    touched = 0
    for path in files:
        changed, new_text = transform(path)
        if not changed:
            continue
        touched += 1
        if args.dry_run:
            print(f"  would migrate: {path.relative_to(REPO_ROOT)}")
        else:
            path.write_text(new_text, encoding="utf-8")
            print(f"  migrated: {path.relative_to(REPO_ROOT)}")
    print(f"\n{touched} template{'' if touched == 1 else 's'} touched.")
    return 0


if __name__ == "__main__":
    sys.exit(main())
