#!/usr/bin/env python3.12
"""
List designed sites with extracted metadata and emit to TMP/DESIGNED.md.

Features:
- Better seed/style extraction from stamps and content
- Extract colors, fonts, aesthetic summary
- Detect completion status
- Output detailed markdown table
"""
from __future__ import annotations

import argparse
import pathlib
import re
from typing import List, Tuple, Optional, Dict, Any

REQUIRED_HEADINGS = [
    "## Aesthetics and Tone",
    "## Layout Motifs and Structure",
    "## Typography and Palette",
    "## Imagery and Motifs",
    "## Prompts for Implementation",
    "## Uniqueness Notes",
]


def load_temp_dir(root: pathlib.Path) -> pathlib.Path:
    cfg = root / ".wdmaker" / "config.toml"
    if not cfg.exists():
        return pathlib.Path(f"/Volumes/Temp/WDMaker/{root.name}/")
    text = cfg.read_text()
    for line in text.splitlines():
        if line.strip().startswith("temp_dir"):
            val = line.split("=", 1)[1].strip().strip('"').strip("'")
            return pathlib.Path(val)
    return pathlib.Path(f"/Volumes/Temp/WDMaker/{root.name}/")


def ensure_headings(path: pathlib.Path, domain: str) -> bool:
    """Ensure headings exist, return True if file was modified."""
    if not path.exists():
        template = [f"# Design Language for {domain}\n\n"]
        for heading in REQUIRED_HEADINGS:
            template.append(f"{heading}\n\n(placeholder - fill with real content)\n\n")
        path.write_text("".join(template), encoding="utf-8")
        return True

    text = path.read_text(encoding="utf-8")
    missing = [h for h in REQUIRED_HEADINGS if h not in text]
    if missing:
        buf = [f"# Design Language for {domain}\n\n"]
        for heading in REQUIRED_HEADINGS:
            section = ""
            if heading in text:
                pattern = re.compile(rf"{re.escape(heading)}\s*(.*?)(^##|\Z)", re.S | re.M)
                m = pattern.search(text)
                if m:
                    section = m.group(1).strip()
            buf.append(f"{heading}\n\n{section or '(placeholder - fill with real content)'}\n\n")
        path.write_text("".join(buf), encoding="utf-8")
        return True

    return False


def extract_seed_from_stamp(text: str) -> Optional[str]:
    """Extract seed from DESIGN STAMP."""
    match = re.search(r"seed:\s*([^\n]+)", text)
    if match:
        return match.group(1).strip()
    return None


def extract_seed_from_content(text: str) -> Optional[str]:
    """Extract seed/style from Uniqueness Notes section."""
    patterns = [
        r"(?:seed|style)[:\s]+([a-z0-9-:, \t]+)",
        r"Seed/Style[:\s]+([a-z0-9-:, \t]+)",
        r"chosen.*?[:\s]+([a-z0-9-:, \t]+)",
    ]

    uniqueness_match = re.search(r"##\s*Uniqueness Notes(.*?)(?=##|$)", text, re.DOTALL | re.IGNORECASE)
    search_text = uniqueness_match.group(1) if uniqueness_match else text

    for pattern in patterns:
        match = re.search(pattern, search_text, re.IGNORECASE)
        if match:
            return match.group(1).strip().lower()

    return None


def extract_aesthetic(text: str) -> Optional[str]:
    """Extract first line of aesthetic description."""
    match = re.search(r"##\s*Aesthetics.*?\n(.*?)(?=\n\n|##|$)", text, re.DOTALL | re.IGNORECASE)
    if match:
        line = match.group(1).strip().split("\n")[0].strip("-* ")
        if line and len(line) > 5:
            return line[:60] + "..." if len(line) > 60 else line
    return None


def extract_colors(text: str) -> List[str]:
    """Extract hex colors."""
    return re.findall(r"#[0-9A-Fa-f]{6}\b", text)[:5]  # Max 5 colors


def extract_fonts(text: str) -> List[str]:
    """Extract font names."""
    font_pattern = r"(Inter|Helvetica|Roboto|Open Sans|Lato|Montserrat|Poppins|Space|IBM Plex|JetBrains|Georgia|Merriweather|Playfair|Lora|Work Sans|Canela|Cormorant|Sora|Futura)"
    fonts = re.findall(font_pattern, text, re.IGNORECASE)
    return list(dict.fromkeys(fonts))[:3]  # Unique, max 3


def extract_content_hash(text: str) -> Optional[str]:
    """Extract content hash from stamp."""
    match = re.search(r"content_hash:\s*([a-f0-9]+)", text)
    if match:
        return match.group(1)
    return None


def check_completeness(text: str) -> str:
    """Check if design is complete."""
    issues = []

    # Check for placeholders
    if "(placeholder" in text.lower():
        issues.append("placeholder")

    # Check required headings
    missing = sum(1 for h in REQUIRED_HEADINGS if h not in text)
    if missing > 0:
        issues.append(f"{missing} missing sections")

    # Check for stamp
    if "DESIGN STAMP" not in text and "updated" not in text:
        issues.append("no stamp")

    if not issues:
        return "✓ Complete"
    return ", ".join(issues)


def analyze_design(path: pathlib.Path) -> Dict[str, Any]:
    """Analyze a design file and extract metadata."""
    text = path.read_text(encoding="utf-8")
    domain = path.parent.name.split("-")[0]

    # Try stamp first, then content
    seed = extract_seed_from_stamp(text) or extract_seed_from_content(text) or ""

    return {
        "domain": domain,
        "directory": path.parent.name,
        "seed": seed,
        "aesthetic": extract_aesthetic(text) or "",
        "colors": extract_colors(text),
        "fonts": extract_fonts(text),
        "hash": extract_content_hash(text) or "",
        "status": check_completeness(text),
        "lines": len(text.splitlines()),
    }


def main() -> int:
    parser = argparse.ArgumentParser(
        description="List designed sites and write DESIGNED.md",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  %(prog)s --root .
  %(prog)s --root . --format table
  %(prog)s --root . --format json
        """
    )
    parser.add_argument("--root", default=".", help="Repo root (default: .)")
    parser.add_argument("--format", choices=["table", "json", "simple"], default="table",
                       help="Output format (default: table)")
    parser.add_argument("--no-fix", action="store_true", help="Don't fix missing headings")
    args = parser.parse_args()

    root = pathlib.Path(args.root).resolve()
    temp_dir = load_temp_dir(root)
    temp_dir.mkdir(parents=True, exist_ok=True)
    designed_md = temp_dir / "DESIGNED.md"

    records: List[Dict[str, Any]] = []

    for design_path in sorted(root.glob("sites/*/DESIGN.md")):
        domain = design_path.parent.name.split("-")[0]

        if not args.no_fix:
            ensure_headings(design_path, domain)

        records.append(analyze_design(design_path))

    # Sort by domain
    records.sort(key=lambda r: r["domain"])

    # Generate output
    if args.format == "json":
        import json
        output = json.dumps(records, indent=2)
    elif args.format == "simple":
        lines = ["# Designed Sites\n\n"]
        lines.append("| Domain | Seed/Style |\n")
        lines.append("|--------|------------|\n")
        for r in records:
            lines.append(f"| {r['domain']} | {r['seed']} |\n")
        output = "".join(lines)
    else:  # table
        lines = [
            "# Designed Sites Summary\n\n",
            f"Total: {len(records)} sites\n\n",
            "## Overview\n\n",
            "| Domain | Seed/Style | Status |\n",
            "|--------|------------|--------|\n",
        ]
        for r in records:
            lines.append(f"| {r['domain']} | {r['seed'][:30] or '-'} | {r['status']} |\n")

        lines.append("\n## Details\n\n")
        for r in records:
            lines.append(f"### {r['domain']}\n\n")
            lines.append(f"- **Directory**: `{r['directory']}`\n")
            lines.append(f"- **Seed**: {r['seed'] or 'not set'}\n")
            if r['aesthetic']:
                lines.append(f"- **Aesthetic**: {r['aesthetic']}\n")
            if r['colors']:
                lines.append(f"- **Colors**: {', '.join(r['colors'])}\n")
            if r['fonts']:
                lines.append(f"- **Fonts**: {', '.join(r['fonts'])}\n")
            if r['hash']:
                lines.append(f"- **Hash**: `{r['hash']}`\n")
            lines.append(f"- **Lines**: {r['lines']}\n")
            lines.append("\n")

        output = "".join(lines)

    designed_md.write_text(output, encoding="utf-8")
    complete = sum(1 for r in records if "Complete" in r["status"])
    print(f"OK:listed:{len(records)} sites ({complete} complete) -> {designed_md}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
