"""
generate_headshots.py — Team Headshot Generator via Hugging Face Inference API (FLUX.1-schnell)

Usage:
    export HF_TOKEN=...
    python scripts/generate_headshots.py                  # generate all headshots + team photo
    python scripts/generate_headshots.py --member jonas   # single member
    python scripts/generate_headshots.py --team-only      # only team photo
    python scripts/generate_headshots.py --no-team        # skip team photo
    python scripts/generate_headshots.py --output-dir team/headshots
"""

import argparse
import os
import sys
import time
from pathlib import Path

try:
    from huggingface_hub import InferenceClient
except ImportError:
    print("Missing dependencies. Run: pip install huggingface_hub Pillow")
    sys.exit(1)

# ── Style prefix used for all portraits (ensures visual consistency) ──────────
STYLE_PREFIX = (
    "Photorealistic portrait photograph, natural lighting, shallow depth of field, "
    "85mm lens look, candid professional feel. "
)

TEAM_MEMBERS = {
    "claudia": {
        "name": "Claudia",
        "role": "Orchestrator & Coordinator",
        "prompt": (
            "Portrait of a confident woman in her early 40s, short dark hair with a few silver strands, "
            "warm and slightly amused expression — like someone who's seen it all but still enjoys the game. "
            "She's sitting at a cluttered-but-organized home desk, laptop open, coffee mug visible. "
            "Casual outfit, maybe a blazer thrown over a t-shirt. Natural window light, slightly candid feel, "
            "not a posed corporate headshot. Warm tones, cozy Berlin apartment vibe."
        ),
    },
    "jonas": {
        "name": "Jonas",
        "role": "Senior Researcher",
        "prompt": (
            "Portrait of a man in his mid-30s, light brown hair slightly tousled, wearing glasses, "
            "medium stubble. Focused but friendly expression — like someone who just looked up from an "
            "interesting article. Background: a home office with bookshelves, stacks of papers, maybe a "
            "half-empty coffee cup. Casual shirt. Natural light, slightly overcast day outside the window. "
            "Candid, not posed. The kind of photo a colleague took at a workshop."
        ),
    },
    "leyla": {
        "name": "Leyla",
        "role": "Writer",
        "prompt": (
            "Portrait of a woman in her early 30s, dark curly hair loosely tied back, wearing a simple "
            "but stylish outfit — maybe a striped top or linen shirt. She's at a cafe table with a notebook "
            "and pen visible, looking up mid-thought with a slight smile. Warm cafe lighting, afternoon sun "
            "through a window behind her. Relaxed and creative energy. Not a corporate photo — more like the "
            "photo on the back of a book she'd write someday."
        ),
    },
    "tobias": {
        "name": "Tobias",
        "role": "Planner",
        "prompt": (
            "Portrait of a man in his mid-40s, short salt-and-pepper hair, clean-shaven, calm and steady "
            "expression — not unfriendly, just not easily impressed. He's standing or sitting near a whiteboard "
            "with some handwritten notes visible in the background. Dressed casually-professional (button-down, "
            "no tie). Good posture. Natural light, office or home-office setting. Practical, grounded energy."
        ),
    },
    "yusuf": {
        "name": "Yusuf",
        "role": "Senior Fullstack Engineer",
        "prompt": (
            "Portrait of a man in his early 40s, dark hair with a few greys, short beard, wearing a casual "
            "dark hoodie or plain t-shirt. He's in a home office setup with multiple monitors visible in the "
            "background — code on the screens, not posed-looking code. Expression: focused, calm, slightly "
            "amused — the look of someone who's seen every bug twice before. Good light, probably late afternoon. "
            "Headphones around neck or on desk. Real, not stock."
        ),
    },
    "elena": {
        "name": "Elena",
        "role": "Finance & Accounting",
        "prompt": (
            "Portrait of a woman in her mid-40s, light auburn hair neatly done, wearing smart-casual clothes — "
            "a nice blouse, maybe a subtle pattern. She's at a tidy desk with a laptop, some printed documents, "
            "and a calculator visible. Expression: professional but warm, the kind of person you trust "
            "immediately with important numbers. Reading glasses either on her nose or set on the desk. "
            "Soft office lighting, feels like a well-organized home office or small firm. Not corporate-stock, "
            "more like a trusted Steuerberaterin who just happens to be good at explaining things."
        ),
    },
    "sofia": {
        "name": "Sofia",
        "role": "UX Designer",
        "prompt": (
            "Portrait of a woman in her mid-30s, straight dark blonde hair worn loose, wearing something "
            "creative but practical — maybe a color-blocked top or interesting jacket. She's in a design studio "
            "or modern workspace with post-its and sketches visible in the soft background. Expression: curious "
            "and engaged, slight tilt of the head. The kind of look that says she's already thinking about how "
            "to improve whatever she's looking at. Bright, airy space, natural light."
        ),
    },
    "amira": {
        "name": "Amira",
        "role": "HR Director",
        "prompt": (
            "Portrait of a woman in her late 30s, wearing a colorful patterned hijab (deep teal or burgundy), "
            "warm open smile, confident posture. She's sitting in a bright, modern co-working space or home "
            "office. Coffee mug in one hand, relaxed but professional. Natural daylight, candid moment feel — "
            "caught between two things she was doing. Not posed, not stock photo. Looks like someone you'd "
            "actually want to talk to about a job."
        ),
    },
}

TEAM_PHOTO_PROMPT = (
    "Photorealistic group photograph of exactly 8 people in a modern, bright office space. "
    "Natural daylight through large windows, shallow depth of field, candid team meeting feel. "
    "The group is gathered casually — some sitting, some standing — around a large table with laptops "
    "and coffee cups. Warm natural tones, no posed corporate feel. Wide format, no text. "
    "The 8 team members are: "
    "Claudia (woman, early 40s, short dark hair with a few silver strands, blazer over t-shirt, warm amused expression); "
    "Jonas (man, mid-30s, tousled light brown hair, glasses, medium stubble, casual shirt); "
    "Leyla (woman, early 30s, dark curly hair loosely tied back, striped top or linen shirt); "
    "Tobias (man, mid-40s, short salt-and-pepper hair, clean-shaven, button-down shirt, calm steady expression); "
    "Yusuf (man, early 40s, dark hair with a few greys, short beard, dark hoodie, headphones around neck); "
    "Elena (woman, mid-40s, light auburn hair neatly done, smart blouse, reading glasses on nose); "
    "Sofia (woman, mid-30s, straight dark blonde hair worn loose, creative color-blocked top, curious expression); "
    "Amira (woman, late 30s, colorful patterned hijab in deep teal, warm open smile, confident posture). "
    "They look like a real startup team: relaxed, focused, mid-conversation."
)


def check_api_key():
    """Verify that HF_TOKEN is set and return it."""
    token = os.environ.get("HF_TOKEN")
    if not token:
        print("Error: HF_TOKEN environment variable not set.")
        print("Get a free token at: huggingface.co/settings/tokens")
        sys.exit(1)
    return token


def generate_image(prompt: str, output_path: Path, landscape: bool = False, retries: int = 3) -> bool:
    """Generate a single image via Hugging Face Inference API (FLUX.1-schnell) and save to disk."""
    token = os.environ.get("HF_TOKEN")
    client = InferenceClient(token=token)

    width = 1792 if landscape else 1024
    height = 1024

    for attempt in range(retries):
        try:
            print(f"  Generating: {output_path.name} ...", end=" ", flush=True)
            image = client.text_to_image(
                prompt,
                model="black-forest-labs/FLUX.1-schnell",
                width=width,
                height=height,
            )
            output_path.parent.mkdir(parents=True, exist_ok=True)
            image.save(str(output_path))
            size_kb = output_path.stat().st_size // 1024
            print(f"saved ({size_kb} KB)")
            return True
        except Exception as e:
            if attempt < retries - 1:
                wait = 2 ** attempt
                print(f"retrying in {wait}s... ({e})")
                time.sleep(wait)
            else:
                print(f"FAILED: {e}")
                return False
    return False


def main():
    parser = argparse.ArgumentParser(description="Generate AI team headshots via Hugging Face Inference API")
    parser.add_argument("--member", metavar="NAME", help="Generate only this member (e.g. jonas)")
    parser.add_argument("--team-only", action="store_true", help="Generate only the team photo")
    parser.add_argument("--no-team", action="store_true", help="Skip team photo generation")
    parser.add_argument("--output-dir", default="team/headshots", help="Output directory (default: team/headshots)")
    args = parser.parse_args()

    output_dir = Path(args.output_dir)
    check_api_key()

    if args.team_only:
        generate_image(TEAM_PHOTO_PROMPT, output_dir / "team_photo.png", landscape=True)
        return

    if args.member:
        key = args.member.lower()
        if key not in TEAM_MEMBERS:
            print(f"Unknown member '{args.member}'. Available: {', '.join(TEAM_MEMBERS.keys())}")
            sys.exit(1)
        member = TEAM_MEMBERS[key]
        full_prompt = STYLE_PREFIX + member["prompt"]
        generate_image(full_prompt, output_dir / f"{key}.png")
        return

    # Generate all headshots
    print(f"Generating {len(TEAM_MEMBERS)} headshots + 1 team photo...\n")
    success = 0
    for key, member in TEAM_MEMBERS.items():
        full_prompt = STYLE_PREFIX + member["prompt"]
        if generate_image(full_prompt, output_dir / f"{key}.png"):
            success += 1
        time.sleep(1)  # be gentle with rate limits

    if not args.no_team:
        print()
        generate_image(TEAM_PHOTO_PROMPT, output_dir / "team_photo.png", landscape=True)

    print(f"\nDone. {success}/{len(TEAM_MEMBERS)} headshots generated in {output_dir}/")


if __name__ == "__main__":
    main()
