#!/usr/bin/env bash
# deck-art-director.sh — Slide-by-slide Kimi-powered deck improvement agent
# Extracts each slide, has Kimi review + improve it, replaces it, compiles.
# Iterates until the deck looks great. Leaves image placeholders everywhere.
#
# Usage: ./deck-art-director.sh [iterations]
#   iterations: full-deck improvement cycles (default 3)

set -euo pipefail

DECK_DIR="/home/mnm/workspaces/thebaker/assets/decks"
DECK_SRC="$DECK_DIR/THE_BAKER_Cannes_Deck.typ"
DECK_PDF="$DECK_DIR/THE_BAKER_Cannes_Deck.pdf"
BACKUP_DIR="$DECK_DIR/iterations"
TMPDIR="${TMPDIR:-/tmp}"
WORK="$TMPDIR/deck-agent-$$"

CREATIVE_MODEL="kimi-k2.6:cloud"   # Visual direction, creative language, design review

ITERATIONS="${1:-3}"

mkdir -p "$BACKUP_DIR" "$WORK"

# ── helpers ──────────────────────────────────────────────────────

log()  { echo "[$(date +%H:%M:%S)] $*"; }
banner() {
    echo
    echo "══════════════════════════════════════════════════════"
    echo "  $*"
    echo "══════════════════════════════════════════════════════"
    echo
}

compile_deck() {
    local out="$WORK/compile.log"
    if typst compile "$DECK_SRC" "$DECK_PDF" 2>"$out"; then
        log "  ✅ Compile OK  ($(du -h "$DECK_PDF" | cut -f1))"
        return 0
    else
        log "  ❌ Compile FAILED"
        tail -5 "$out" | sed 's/^/      /'
        return 1
    fi
}

snapshot() {
    local label="$1"
    cp "$DECK_SRC" "$BACKUP_DIR/$(date +%H%M%S)-${label}.typ"
}

# ── extract all slides ──────────────────────────────────────────

extract_slides() {
    # Splits deck into individual slide files in $WORK/slides/
    # Also creates $WORK/header.typ (preamble before first slide)
    # and $WORK/footer.typ (everything after last slide)
    mkdir -p "$WORK/slides"

    local in_slide=false slide_num=0 current=""

    # Find line number of first "// SLIDE"
    local first_slide
    first_slide=$(grep -n '^// SLIDE ' "$DECK_SRC" | head -1 | cut -d: -f1)

    # Header = everything before first slide
    head -n $((first_slide - 1)) "$DECK_SRC" > "$WORK/header.typ"

    # Extract slides using awk for reliability
    awk -v work="$WORK/slides" '
    /^\/\/ SLIDE / {
        if (slide_file != "") {
            print content > slide_file
            close(slide_file)
        }
        slide_num++
        slide_file = sprintf("%s/slide-%02d.typ", work, slide_num)
        content = $0 "\n"
        next
    }
    /^\/\/ ANNEX / {
        if (slide_file != "") {
            print content > slide_file
            close(slide_file)
        }
        slide_num++
        slide_file = sprintf("%s/slide-%02d.typ", work, slide_num)
        content = $0 "\n"
        next
    }
    {
        if (slide_file != "")
            content = content $0 "\n"
    }
    END {
        if (slide_file != "")
            print content > slide_file
    }
    ' "$DECK_SRC"

    # Count slides
    local count
    count=$(ls "$WORK/slides"/slide-*.typ 2>/dev/null | wc -l)
    log "Extracted $count slides"
    echo "$count" > "$WORK/slide-count.txt"
}

# ── Kimi: review a single slide ──────────────────────────────────

kimi_review_slide() {
    local slide_path="$1"
    local slide_text
    slide_text=$(cat "$slide_path")

    local slide_name
    slide_name=$(basename "$slide_path")

    log "  👁️  Kimi reviewing $slide_name..."

    ollama run "$CREATIVE_MODEL" \
"You are an art director reviewing a single slide from a Cannes film pitch deck for THE BAKER.
The deck uses dark backgrounds (#121212), gold accents (#B78A3C), cards, and Typst functions:
display(), h1(), h2(), copy(), card(), stat(), role_card(), small_card(), kicker(), divider().

Evaluate this slide on:
1. Visual density — is it too packed or too sparse?
2. Language — which lines land? Which could be tighter or more evocative?
3. Image opportunity — does this slide need an illustration placeholder?
4. Typographic hierarchy — is the heading-to-body relationship clear?

Give 3-5 specific, implementable suggestions. Keep each to one sentence.
Start each with a TYPE tag: [LANGUAGE] [LAYOUT] [IMAGE] [COLOR] [TYPOGRAPHY]

$slide_name:
$slide_text" 2>/dev/null
}

# ── Kimi: regenerate an improved slide ───────────────────────────

kimi_improve_slide() {
    local slide_path="$1"
    local review="$2"
    local slide_text
    slide_text=$(cat "$slide_path")
    local slide_name
    slide_name=$(basename "$slide_path")

    log "  🔧 Kimi regenerating $slide_name..."

    local result
    result=$(ollama run "$CREATIVE_MODEL" \
"You are a Typst expert. You are editing a single slide from a Cannes deck.
Apply the art director's review suggestions to improve the slide.

CRITICAL RULES:
- Output ONLY the replacement Typst for this slide. No markdown, no code fences, no explanations.
- Start with the '// SLIDE NN' comment line.
- End with '#pagebreak()' (the caller handles the blank line after).
- Use ONLY these existing functions: slide(), kicker(), display(), h1(), h2(), copy(), card(), stat(), role_card(), small_card(), divider(), note(), bullet_list(), grid(), block(), align(), v(), text(), set.
- Color palette: c_card=#1B1B1B, c_card2=#202020, c_line=#2E2E2E, c_white=#FFFFFF, c_gray=#E6E6E6, c_muted=#A8A8A8, c_gold=#B78A3C.
- Page is 320mm × 180mm, margins 22mm x, 18mm y.
- If adding an image placeholder, use:
  #block(width: XXmm, height: YYmm, stroke: 1pt + c_line, radius: 4pt, fill: c_card2)[
    #align(center + horizon)[
      #text(fill: c_muted, style: \"italic\")[Illustration: short description]
    ]
  ]
- Preserve ALL factual content. Only change what the review asks you to change.
- The slide MUST compile. Check your brackets.

Art director's review:
$review

Current slide to improve:
$slide_text

Improved slide:" 2>/dev/null)

    # Extract just the Typst code (strip any conversational prefix/suffix)
    echo "$result" | sed -n '/^\/\/ SLIDE /,/^#pagebreak()/p' > "$WORK/improved-${slide_name}"

    if grep -q '^#pagebreak()' "$WORK/improved-${slide_name}" 2>/dev/null; then
        log "    ✅ Got valid improved slide"
        return 0
    else
        log "    ⚠️  Output invalid — keeping original"
        cp "$slide_path" "$WORK/improved-${slide_name}"
        return 1
    fi
}

# ── rebuild deck from slides ─────────────────────────────────────

rebuild_deck() {
    cat "$WORK/header.typ" > "$DECK_SRC"
    echo "" >> "$DECK_SRC"

    for slide_file in $(ls "$WORK/slides"/slide-*.typ 2>/dev/null | sort); do
        # Use improved version if it exists
        local name
        name=$(basename "$slide_file")
        if [[ -f "$WORK/improved-${name}" ]]; then
            cat "$WORK/improved-${name}" >> "$DECK_SRC"
        else
            cat "$slide_file" >> "$DECK_SRC"
        fi
        echo "" >> "$DECK_SRC"
    done
}

# ── image placeholder sweep ──────────────────────────────────────

sweep_image_placeholders() {
    log "🖼️  Image placeholder sweep..."

    local slide_count
    slide_count=$(cat "$WORK/slide-count.txt")
    local added=0

    for i in $(seq 1 "$slide_count"); do
        local sf="$WORK/slides/slide-$(printf '%02d' "$i").typ"
        [[ -f "$sf" ]] || continue

        # Check if slide already has an illustration placeholder
        if grep -q 'Illustration' "$sf" 2>/dev/null; then
            continue  # already has one
        fi

        local slide_text
        slide_text=$(cat "$sf")
        local slide_label
        slide_label=$(head -1 "$sf" | sed 's/^\/\/ //')

        log "  Adding placeholder to $slide_label..."

        local improved
        improved=$(ollama run "$CREATIVE_MODEL" \
"Add an image/illustration placeholder block to this Typst slide. 
Choose dimensions that fit naturally in the layout (page 320×180mm, margins 22mm x, 18mm y).
Use a descriptive label for what kind of image belongs there.
Output ONLY the modified Typst slide — no markdown, no code fences.
Start with the '// SLIDE' comment, end with '#pagebreak()'.

The placeholder format:
#block(width: XXmm, height: YYmm, stroke: 1pt + c_line, radius: 4pt, fill: c_card2)[
  #align(center + horizon)[
    #text(fill: c_muted, style: \"italic\")[Illustration: description]
  ]
]

$slide_text" 2>/dev/null)

        echo "$improved" | sed -n '/^\/\/ SLIDE /,/^#pagebreak()/p' > "$WORK/improved-slide-$(printf '%02d' "$i").typ"

        if grep -q '#pagebreak()' "$WORK/improved-slide-$(printf '%02d' "$i").typ" 2>/dev/null; then
            cp "$WORK/improved-slide-$(printf '%02d' "$i").typ" "$sf"
            ((added++)) || true
        fi
    done

    log "  Added placeholders to $added slides"
}

# ── main ─────────────────────────────────────────────────────────

main() {
    banner "THE BAKER · Deck Art Director Agent"
    log "Creative model: $CREATIVE_MODEL"
    log "Iterations:     $ITERATIONS"
    log "Deck:           $DECK_SRC"

    snapshot "original"

    # ── extract slides ──
    extract_slides
    local slide_count
    slide_count=$(cat "$WORK/slide-count.txt")

    # ── first pass: image placeholders on every slide ──
    banner "PASS 0 — Image Placeholders"
    sweep_image_placeholders
    rebuild_deck
    compile_deck || log "⚠️  Compile issues after image pass (will fix in iterations)"
    snapshot "post-images"

    # ── iterative improvement passes ──
    for iter in $(seq 1 "$ITERATIONS"); do
        banner "ITERATION $iter of $ITERATIONS"

        # Re-extract slides to pick up any structural changes
        extract_slides
        slide_count=$(cat "$WORK/slide-count.txt")

        local changed=0

        for i in $(seq 1 "$slide_count"); do
            local sf="$WORK/slides/slide-$(printf '%02d' "$i").typ"
            [[ -f "$sf" ]] || continue

            local label
            label=$(head -1 "$sf" | sed 's/^\/\/ //')

            # Step 1: Kimi reviews the slide
            local review
            review=$(kimi_review_slide "$sf")

            # Check if review has substantive suggestions
            if echo "$review" | grep -qE '\[LANGUAGE\]|\[LAYOUT\]|\[IMAGE\]|\[COLOR\]|\[TYPOGRAPHY\]'; then
                # Step 2: Kimi regenerates improved slide
                kimi_improve_slide "$sf" "$review" && ((changed++)) || true
            else
                log "  ⏭️  No substantive changes for $label"
            fi

            # Compile check every 5 slides
            if (( i % 5 == 0 )); then
                rebuild_deck
                compile_deck || true
            fi
        done

        # Rebuild and final compile for this iteration
        rebuild_deck
        if compile_deck; then
            log "✅ Iteration $iter complete — $changed slides improved"
        else
            log "⚠️  Iteration $iter has compile errors"
        fi

        snapshot "iter-$(printf '%02d' "$iter")"

        # Sweep image placeholders again every other iteration
        if (( iter % 2 == 0 )); then
            sweep_image_placeholders
            rebuild_deck
            compile_deck || true
            snapshot "iter-$(printf '%02d' "$iter")-images"
        fi
    done

    # ── final image sweep ──
    banner "FINAL — Image Placeholder Sweep"
    extract_slides
    sweep_image_placeholders
    rebuild_deck
    compile_deck || true

    banner "COMPLETE ✨"
    log "Final deck: $DECK_SRC"
    log "Final PDF:  $DECK_PDF"
    log "Backups:    $BACKUP_DIR"
    ls -la "$DECK_PDF"
}

main "$@"
