"""
CLI: signalwire-slides

Commands:
    signalwire-slides list                # show all 29 layouts with descriptions
    signalwire-slides show L04            # print source code of a layout
    signalwire-slides show content        # same, by name
    signalwire-slides build               # build reference deck (both themes)
    signalwire-slides build --theme dark  # dark only
    signalwire-slides build -o /tmp       # custom output dir
"""

import argparse
import inspect
import os
import sys


def cmd_list(args):
    """List all available layouts."""
    from . import LAYOUT_INFO
    print(f"\nSignalWire Slide Builder — {len(LAYOUT_INFO)} layouts\n")
    print(f"  {'ID':<6} {'Name':<22} Description")
    print(f"  {'—'*5:<6} {'—'*20:<22} {'—'*50}")
    for info in LAYOUT_INFO:
        print(f"  {info['id']:<6} {info['name']:<22} {info['desc']}")
    print(f"\nUsage:")
    print(f"  signalwire-slides show L04          # view layout source code")
    print(f"  signalwire-slides show content       # same, by name")
    print(f"  signalwire-slides build              # build reference deck\n")


def cmd_show(args):
    """Show the source code of a layout."""
    from . import CATALOG, LAYOUT_INFO
    key = args.layout
    # Try direct catalog lookup
    fn = CATALOG.get(key) or CATALOG.get(key.upper()) or CATALOG.get(key.lower())
    if not fn:
        # Try partial match on name
        for info in LAYOUT_INFO:
            if key.lower() in info["name"].lower() or key.lower() in info["id"].lower():
                fn = info["fn"]
                break
    if not fn:
        print(f"Unknown layout '{key}'. Run: signalwire-slides list")
        sys.exit(1)
    # Find the info entry
    info = next((i for i in LAYOUT_INFO if i["fn"] == fn), None)
    if info:
        print(f"\n# {info['id']}: {info['name']}")
        print(f"# {info['desc']}\n")
    print(inspect.getsource(info["module"] if info else fn))


def cmd_docs(args):
    """Show full API reference, writing rules, and word limits."""
    print("""
SignalWire Slide Builder — API Reference
═════════════════════════════════════════

QUICK START
───────────
  from signalwire_slides import *

  prs = Presentation()
  prs.slide_width = SW; prs.slide_height = SH
  bk = prs.slide_layouts[6]
  lw = svg_to_png(LOGO_WHITE_SVG, width=800)  # dark theme logo
  lb = svg_to_png(LOGO_BLACK_SVG, width=800)  # light theme logo

  L01_title(prs, bk, GRAD, lw, title="Your Title", subtitle="Name | Role")
  L04_content(prs, bk, GRAD, lw, title="Headline", bullets=["A", "B", "C"])
  L12_kpi(prs, bk, GRAD, lw, metric="2.7B", caption="Minutes annually")
  L15_closing(prs, bk, GRAD, lw, actions=["Step 1", "Step 2", "Step 3"])

  prs.save('my_deck.pptx')

Every layout accepts content as keyword arguments. Defaults are sample text.
Run: signalwire-slides show L04  to see any layout's parameters.

THEMES
──────
  GRAD   — dark gradient theme (use with white logo: lw)
  LIGHT  — light theme (use with black logo: lb)

SLIDEBUILDER API (for custom slides)
─────────────────────────────────────
  S = SlideBuilder(prs, bk, GRAD, lw)

  Setup:
    .done()                          Add footer. Call last.
    .s                               Raw slide for direct python-pptx access.

  Text (numbers auto-convert: position=Inches, size=Pt):
    .title(text, size, top, large)   large=True for 48pt cover titles
    .subtitle(text, top)             Muted text below title
    .label(text, left, top, color)   Uppercase eyebrow
    .body(items, top, left, width)   Bullet list with emphasis dots
    .numbered(items, top)            Numbered list
    .text(content, left, top, ...)   Any text, anywhere

  Visual:
    .card(left, top, w, h, accent, title, body_text)
    .image_area(left, top, w, h, label)
    .icon(name, left, top, size, color_hex)

  Compound:
    .kpi(value, caption, label)
    .quote(text, name, company)
    .two_col(l_title, l_items, r_title, r_items)
    .process_steps(steps, descriptions)
    .timeline(milestones, descriptions)
    .metric_cards([(value, label, desc, color), ...])

  text() shortcuts:
    font="h" = heading, font="body" = body
    color="emphasis", "muted", "subtle", "text", "fuchsia", "blue", "white"

WORD LIMITS (write to these BEFORE building)
────────────────────────────────────────────
  48pt big title:       8 words, 1 line
  36pt headline:       12 words, 1 line
  24pt bullet:         15 words, 1-2 lines
  20pt small bullet:   10 words (half-width columns)
  16-18pt card text:   20 words, 2-3 lines
  14pt caption:        25 words, 1 line

AUTO-FIT
────────
  All text auto-shrinks if too wide (titles, bullets) or too tall (card body).
  Warnings print when shrinking occurs. Occasional title shrinks are fine.
  If most slides warn, tighten the copy.

  Scale ladders:
    Big title:  48 > 42 > 40 > 36 (minimum)
    Headline:   36 > 32 > 30 > 28 (minimum)
    Body:       24 > 22 > 20 > 18 (minimum)
    Card body:  18 > 16 > 14 (minimum, vertical overflow only)

  PowerPoint/Google Slides also has normAutofit on every text frame
  as a native safety net.

WRITING RULES
─────────────
  Headlines are ASSERTIONS: "800ms latency on every call" not "About Latency"
  Bullets are FRAGMENTS: no periods, 6-8 words each, 3 max per slide
  Numbers over adjectives: "2.7B minutes" not "massive scale"
  No filler: cut "that", "which", "in order to", "leveraging"

QA: TWO PASSES
──────────────
  1. Content: every headline is an assertion, bullets 6-8 words
  2. Layout: no text overflows, titles on one line, "almost fits" = broken

CONSTANTS
─────────
  SW, SH        Slide dimensions (13.333" x 7.5")
  ML, CW        Left margin (0.7"), content width (11.933")
  BLUE           #044EF4
  FUCHSIA        #F72A72
  TURQUOISE      #40E0D0
  GOLD           #FFD700
  WHITE          #FFFFFF
  FONT_H         Instrument Sans (headings)
  FONT_B         Outfit (body)
  TITLE_SIZE     36pt
  TITLE_LG       48pt
  BODY_SIZE      24pt
  BODY_SM        20pt
""")


def cmd_build(args):
    """Build reference deck."""
    from pptx import Presentation
    from .core import (
        SW, SH, GRAD, LIGHT,
        LOGO_WHITE_SVG, LOGO_BLACK_SVG, svg_to_png,
    )
    from . import ALL_LAYOUTS, RESOURCE_LAYOUTS, LAYOUT_NAMES
    from .L15_closing import L15_closing
    from .L17_blank_dark import L17_blank_dark
    from .L18_blank_light import L18_blank_light

    def build_deck(theme_config, logo_png, logo_white_png, suffix, output_dir):
        prs = Presentation()
        prs.slide_width = SW; prs.slide_height = SH
        bk = prs.slide_layouts[6]
        for fn in ALL_LAYOUTS:
            if fn == L15_closing:
                fn(prs, bk, theme_config, logo_png, logo_white=logo_white_png)
            else:
                fn(prs, bk, theme_config, logo_png)
        for fn in RESOURCE_LAYOUTS:
            fn(prs, bk, theme_config, logo_png)
        if theme_config["is_gradient"]:
            L17_blank_dark(prs, bk, theme_config, logo_png)
        else:
            L18_blank_light(prs, bk, theme_config, logo_png)
        out = os.path.join(output_dir, f"SignalWire_Template_{suffix}.pptx")
        prs.save(out)
        return out, len(prs.slides)

    lw = svg_to_png(LOGO_WHITE_SVG, width=800)
    lb = svg_to_png(LOGO_BLACK_SVG, width=800)

    builds = []
    if args.theme in ("dark", "both"):
        builds.append((GRAD, lw, lw, "Dark", "DARK GRADIENT"))
    if args.theme in ("light", "both"):
        builds.append((LIGHT, lb, lw, "Light", "LIGHT"))

    for theme, logo, logo_w, suffix, label in builds:
        out, count = build_deck(theme, logo, logo_w, suffix, args.output_dir)
        print(f"\n{label}: {out}")
        print(f"  {count} slides:")
        for i, n in enumerate(LAYOUT_NAMES):
            print(f"    {i+1:2}. {n}")


def main():
    parser = argparse.ArgumentParser(
        prog="signalwire-slides",
        description="SignalWire branded slide deck builder"
    )
    sub = parser.add_subparsers(dest="command")

    # list
    sub.add_parser("list", help="Show all available layouts")

    # show
    show_p = sub.add_parser("show", help="View source code of a layout")
    show_p.add_argument("layout", help="Layout ID (L04) or name (content)")

    # build
    build_p = sub.add_parser("build", help="Build reference deck")
    build_p.add_argument("--theme", choices=["dark", "light", "both"], default="both")
    build_p.add_argument("-o", "--output-dir", default=".")

    # docs
    sub.add_parser("docs", help="Full API reference, writing rules, word limits")

    args = parser.parse_args()

    if args.command == "list":
        cmd_list(args)
    elif args.command == "show":
        cmd_show(args)
    elif args.command == "build":
        cmd_build(args)
    elif args.command == "docs":
        cmd_docs(args)
    else:
        # Default: show help
        parser.print_help()
        print("\nQuick start:")
        print("  signalwire-slides list     # see all layouts")
        print("  signalwire-slides docs     # full API reference")
        print("  signalwire-slides build    # build reference deck")


if __name__ == "__main__":
    main()
