#!/usr/bin/env python3
"""
Moodboard Compiler - Generates an accessible HTML moodboard with Cosmos-style interface.

Accessibility Standards (WCAG 2.1 AA):
- Semantic HTML structure (header, main, section, figure)
- Proper heading hierarchy (h1 → h2, no skips)
- 4.5:1 contrast ratio for normal text
- Alt text for all images
- prefers-reduced-motion support
- Visible focus states
- Minimum 44x44px touch targets
"""

import argparse
import os
from pathlib import Path
from datetime import datetime
import random

HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{name} - Moodboard</title>
    <meta name="description" content="Visual moodboard for {name}: {tagline}">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family={heading_font_url}:wght@400;500;600;700&family={body_font_url}:wght@400;500;600&display=swap" rel="stylesheet">
    <style>
        :root {{
            --primary: {primary};
            --secondary: {secondary};
            --accent: {accent};
            --neutral-dark: {neutral_dark};
            --neutral-light: {neutral_light};
            --bg: #0a0a0a;
            --surface: #141414;
            --surface-hover: #1a1a1a;
            --text: #fafafa;
            --text-muted: #888;
            --border: #2a2a2a;
        }}
        
        * {{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }}
        
        @media (prefers-reduced-motion: reduce) {{
            *, *::before, *::after {{
                animation-duration: 0.01ms !important;
                transition-duration: 0.01ms !important;
            }}
        }}
        
        body {{
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
            background: var(--bg);
            color: var(--text);
            line-height: 1.5;
            min-height: 100vh;
        }}
        
        /* Skip link */
        .skip-link {{
            position: absolute;
            top: -40px;
            left: 0;
            background: var(--primary);
            color: var(--bg);
            padding: 0.75rem 1rem;
            z-index: 100;
            text-decoration: none;
            font-weight: 500;
        }}
        .skip-link:focus {{ top: 0; }}
        
        /* Focus states */
        *:focus {{ outline: 2px solid var(--primary); outline-offset: 2px; }}
        *:focus:not(:focus-visible) {{ outline: none; }}
        *:focus-visible {{ outline: 2px solid var(--primary); outline-offset: 2px; }}
        
        /* Header - Minimal */
        header {{
            padding: 2rem 2rem 1rem;
            max-width: 1800px;
            margin: 0 auto;
        }}
        
        .header-content {{
            display: flex;
            align-items: flex-start;
            justify-content: space-between;
            gap: 2rem;
            flex-wrap: wrap;
        }}
        
        .brand {{
            flex: 1;
            min-width: 280px;
        }}
        
        h1 {{
            font-size: 1.75rem;
            font-weight: 600;
            color: var(--text);
            margin-bottom: 0.25rem;
            letter-spacing: -0.02em;
        }}
        
        .tagline {{
            font-size: 0.9rem;
            color: var(--text-muted);
        }}
        
        .vibe-tags {{
            display: flex;
            gap: 0.5rem;
            flex-wrap: wrap;
            margin-top: 1rem;
        }}
        
        .vibe-tag {{
            background: var(--surface);
            color: var(--text-muted);
            border: 1px solid var(--border);
            padding: 0.375rem 0.75rem;
            border-radius: 100px;
            font-size: 0.75rem;
            font-weight: 500;
            letter-spacing: 0.02em;
        }}
        
        /* Color Pills - Inline */
        .color-strip {{
            display: flex;
            gap: 0.5rem;
            align-items: center;
            flex-wrap: wrap;
        }}
        
        .color-pill {{
            display: flex;
            align-items: center;
            gap: 0.5rem;
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: 100px;
            padding: 0.25rem 0.75rem 0.25rem 0.25rem;
        }}
        
        .color-dot {{
            width: 24px;
            height: 24px;
            border-radius: 50%;
            flex-shrink: 0;
        }}
        
        .color-value {{
            font-family: 'SF Mono', Monaco, monospace;
            font-size: 0.7rem;
            color: var(--text-muted);
        }}
        
        /* Main Grid - Cosmos Style Masonry */
        main {{
            padding: 1rem 2rem 4rem;
            max-width: 1800px;
            margin: 0 auto;
        }}
        
        .masonry {{
            columns: 4;
            column-gap: 1rem;
        }}
        
        @media (max-width: 1400px) {{ .masonry {{ columns: 3; }} }}
        @media (max-width: 1000px) {{ .masonry {{ columns: 2; }} }}
        @media (max-width: 600px) {{ .masonry {{ columns: 1; }} }}
        
        .card {{
            break-inside: avoid;
            margin-bottom: 1rem;
            border-radius: 12px;
            overflow: hidden;
            background: var(--surface);
            border: 1px solid var(--border);
            transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
        }}
        
        .card:hover {{
            transform: translateY(-4px);
            box-shadow: 0 20px 40px rgba(0,0,0,0.4);
        }}
        
        /* Image Cards */
        .card-image {{
            position: relative;
            overflow: hidden;
        }}
        
        .card-image img {{
            width: 100%;
            height: auto;
            display: block;
            transition: transform 0.3s ease-out;
        }}
        
        .card-image:hover img {{
            transform: scale(1.02);
        }}
        
        .card-image figcaption {{
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            padding: 3rem 1rem 1rem;
            background: linear-gradient(transparent, rgba(0,0,0,0.8));
            font-size: 0.8rem;
            color: rgba(255,255,255,0.8);
            opacity: 0;
            transition: opacity 0.2s ease-out;
        }}
        
        .card-image:hover figcaption {{
            opacity: 1;
        }}
        
        /* Typography Card */
        .card-typography {{
            padding: 2rem;
        }}
        
        .type-label {{
            font-size: 0.65rem;
            text-transform: uppercase;
            letter-spacing: 0.1em;
            color: var(--text-muted);
            margin-bottom: 0.75rem;
        }}
        
        .heading-preview {{
            font-family: '{heading_font}', serif;
            font-size: 2rem;
            line-height: 1.2;
            margin-bottom: 1rem;
            color: var(--text);
        }}
        
        .body-preview {{
            font-family: '{body_font}', sans-serif;
            font-size: 0.9rem;
            color: var(--text-muted);
            line-height: 1.6;
        }}
        
        .font-name {{
            font-size: 0.7rem;
            color: var(--primary);
            margin-top: 0.75rem;
        }}
        
        /* UI Preview Card */
        .card-ui {{
            padding: 2rem;
        }}
        
        .ui-buttons {{
            display: flex;
            gap: 0.5rem;
            flex-wrap: wrap;
            margin-bottom: 1rem;
        }}
        
        .ui-btn {{
            padding: 0.625rem 1.25rem;
            border-radius: 8px;
            font-size: 0.8rem;
            font-weight: 500;
            border: none;
            cursor: pointer;
            min-height: 44px;
            transition: transform 0.15s ease-out;
        }}
        
        .ui-btn:hover {{ transform: translateY(-1px); }}
        .ui-btn:active {{ transform: scale(0.97); }}
        
        .ui-btn-primary {{
            background: var(--primary);
            color: var(--bg);
        }}
        
        .ui-btn-secondary {{
            background: transparent;
            border: 1px solid var(--border);
            color: var(--text);
        }}
        
        .ui-input {{
            width: 100%;
            padding: 0.75rem 1rem;
            background: var(--bg);
            border: 1px solid var(--border);
            border-radius: 8px;
            color: var(--text);
            font-size: 0.875rem;
            min-height: 44px;
        }}
        
        .ui-input::placeholder {{ color: var(--text-muted); }}
        .ui-input:focus {{ border-color: var(--primary); }}
        
        /* Palette Card */
        .card-palette {{
            padding: 0;
        }}
        
        .palette-bar {{
            display: flex;
            height: 80px;
        }}
        
        .palette-color {{
            flex: 1;
            display: flex;
            align-items: flex-end;
            justify-content: center;
            padding-bottom: 0.5rem;
            font-family: 'SF Mono', Monaco, monospace;
            font-size: 0.6rem;
            color: var(--bg);
            text-shadow: 0 1px 2px rgba(0,0,0,0.3);
        }}
        
        .palette-color.light-text {{
            color: var(--text);
        }}
        
        /* Footer */
        footer {{
            text-align: center;
            padding: 2rem;
            color: var(--text-muted);
            font-size: 0.75rem;
            border-top: 1px solid var(--border);
            margin-top: 2rem;
        }}
    </style>
</head>
<body>
    <a href="#main-content" class="skip-link">Skip to content</a>
    
    <header>
        <div class="header-content">
            <div class="brand">
                <h1>{name}</h1>
                <p class="tagline">{tagline}</p>
                <div class="vibe-tags" role="list" aria-label="Style keywords">
                    {vibe_tags_html}
                </div>
            </div>
            <div class="color-strip" role="list" aria-label="Color palette">
                <div class="color-pill">
                    <div class="color-dot" style="background: {primary}"></div>
                    <span class="color-value">{primary}</span>
                </div>
                <div class="color-pill">
                    <div class="color-dot" style="background: {secondary}"></div>
                    <span class="color-value">{secondary}</span>
                </div>
                <div class="color-pill">
                    <div class="color-dot" style="background: {accent}"></div>
                    <span class="color-value">{accent}</span>
                </div>
            </div>
        </div>
    </header>
    
    <main id="main-content">
        <div class="masonry">
            {cards_html}
        </div>
    </main>
    
    <footer>
        <p>Moodboard generated <time datetime="{date_iso}">{date}</time></p>
    </footer>
</body>
</html>
"""

def font_to_url(font_name: str) -> str:
    return font_name.replace(" ", "+")

def generate_cards(images: list, heading_font: str, body_font: str, primary: str, secondary: str, accent: str, neutral_dark: str, neutral_light: str) -> str:
    """Generate masonry cards mixing images with typography/UI cards."""
    cards = []
    
    # Insert typography card early
    typography_card = f'''
        <article class="card card-typography">
            <div class="type-label">Typography</div>
            <div class="heading-preview">Make every action count</div>
            <div class="body-preview">Small changes add up to something bigger. Track your impact and watch it grow.</div>
            <div class="font-name">{heading_font} + {body_font}</div>
        </article>
    '''
    
    # UI preview card
    ui_card = f'''
        <article class="card card-ui">
            <div class="type-label">Components</div>
            <div class="ui-buttons">
                <button class="ui-btn ui-btn-primary" type="button">Take Action</button>
                <button class="ui-btn ui-btn-secondary" type="button">Learn More</button>
            </div>
            <input type="text" class="ui-input" placeholder="Search your impact..." aria-label="Example input">
        </article>
    '''
    
    # Full palette card
    palette_card = f'''
        <article class="card card-palette">
            <div class="palette-bar">
                <div class="palette-color" style="background: {primary}">{primary}</div>
                <div class="palette-color" style="background: {secondary}">{secondary}</div>
                <div class="palette-color" style="background: {accent}">{accent}</div>
                <div class="palette-color light-text" style="background: {neutral_dark}">{neutral_dark}</div>
                <div class="palette-color" style="background: {neutral_light}">{neutral_light}</div>
            </div>
        </article>
    '''
    
    # Build image cards
    image_cards = []
    for path, alt in images:
        image_cards.append(f'''
            <figure class="card card-image">
                <img src="{path}" alt="{alt}" loading="lazy">
                <figcaption>{alt}</figcaption>
            </figure>
        ''')
    
    # Interleave: images + special cards at strategic positions
    result = []
    special_cards = [typography_card, ui_card, palette_card]
    special_positions = [2, 5, 8]  # Insert after these image indices
    
    special_idx = 0
    for i, img_card in enumerate(image_cards):
        result.append(img_card)
        if special_idx < len(special_cards) and i + 1 in special_positions:
            result.append(special_cards[special_idx])
            special_idx += 1
    
    # Add remaining special cards at end if not enough images
    while special_idx < len(special_cards):
        result.append(special_cards[special_idx])
        special_idx += 1
    
    return '\n'.join(result)

def main():
    parser = argparse.ArgumentParser(description="Generate a Cosmos-style HTML moodboard")
    parser.add_argument("--output", "-o", required=True, help="Output HTML file path")
    parser.add_argument("--name", required=True, help="Product/brand name")
    parser.add_argument("--tagline", default="", help="Product tagline")
    parser.add_argument("--vibe", default="modern, minimal", help="Comma-separated vibe keywords")
    parser.add_argument("--primary", default="#22c55e", help="Primary color hex")
    parser.add_argument("--secondary", default="#14b8a6", help="Secondary color hex")
    parser.add_argument("--accent", default="#84cc16", help="Accent color hex")
    parser.add_argument("--neutral-dark", default="#18181b", help="Dark neutral hex")
    parser.add_argument("--neutral-light", default="#fafafa", help="Light neutral hex")
    parser.add_argument("--heading-font", default="DM Serif Display", help="Heading font name")
    parser.add_argument("--body-font", default="Inter", help="Body font name")
    parser.add_argument("--images", default="", help="Comma-separated image paths (path:alt pairs)")
    
    args = parser.parse_args()
    
    # Process vibe tags
    vibe_tags = [v.strip() for v in args.vibe.split(",") if v.strip()]
    vibe_tags_html = "\n".join(f'<span class="vibe-tag" role="listitem">{tag}</span>' for tag in vibe_tags)
    
    # Process images
    image_entries = [p.strip() for p in args.images.split(",") if p.strip()]
    images = []
    for i, entry in enumerate(image_entries):
        if ":" in entry and not entry.startswith("http"):
            path, alt = entry.split(":", 1)
        else:
            path = entry
            alt = f"Mood inspiration {i + 1}"
        images.append((path, alt))
    
    # Generate cards
    cards_html = generate_cards(
        images, 
        args.heading_font, 
        args.body_font,
        args.primary,
        args.secondary,
        args.accent,
        args.neutral_dark,
        args.neutral_light
    )
    
    # Dates
    now = datetime.now()
    date_display = now.strftime("%B %d, %Y")
    date_iso = now.strftime("%Y-%m-%d")
    
    # Generate HTML
    html = HTML_TEMPLATE.format(
        name=args.name,
        tagline=args.tagline,
        vibe_tags_html=vibe_tags_html,
        primary=args.primary,
        secondary=args.secondary,
        accent=args.accent,
        neutral_dark=args.neutral_dark,
        neutral_light=args.neutral_light,
        heading_font=args.heading_font,
        body_font=args.body_font,
        heading_font_url=font_to_url(args.heading_font),
        body_font_url=font_to_url(args.body_font),
        cards_html=cards_html,
        date=date_display,
        date_iso=date_iso,
    )
    
    # Write file
    output_path = Path(args.output)
    output_path.parent.mkdir(parents=True, exist_ok=True)
    output_path.write_text(html)
    
    print(f"✓ Moodboard generated: {output_path}")
    print(f"  Style: Cosmos-inspired dark masonry")
    print(f"  Colors: {args.primary} | {args.secondary} | {args.accent}")
    print(f"  Fonts: {args.heading_font} + {args.body_font}")
    print(f"  Images: {len(images)} included")

if __name__ == "__main__":
    main()
