"""Create an original, fast-paced story suited to a 45-65 second YouTube Short."""
import argparse
import json
import random
from datetime import datetime, timezone

from openai import OpenAI

from config import OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_MODEL, STORIES_DIR, STORY_THEMES


def fallback_story(theme: str) -> dict:
    """Works without an API key so the video renderer remains usable."""
    text = (
        "My coworker kept stealing my lunch, and everyone told me I was imagining it. "
        "For three months, my meals disappeared from the fridge every Tuesday. "
        "So I put a tiny Bluetooth tracker inside a sealed container of leftovers. "
        "At noon, the signal led straight to our manager's office. "
        "He had been taking food because he thought nobody would confront him. "
        "I showed HR the location history, and suddenly he had a lot to explain. "
        "The next day, he brought in a whole tray of sandwiches for the team. "
        "Nobody touched them."
    )
    return {
        "title": "My Manager Kept Stealing My Lunch",
        "story": text,
        "description": "A workplace mystery with an unexpected ending. #storytime #redditstories #shorts",
        "hashtags": ["#shorts", "#storytime", "#redditstories", "#karma"],
        "theme": theme,
        "source": "original-fallback",
    }


def generate_story(theme: str | None = None) -> dict:
    theme = theme or random.choice(STORY_THEMES)
    if not OPENAI_API_KEY:
        return fallback_story(theme)

    client = OpenAI(api_key=OPENAI_API_KEY, base_url=OPENAI_BASE_URL)
    prompt = f"""Write an original first-person story for a YouTube Short.
Theme: {theme}

Rules:
- 125 to 150 spoken English words, target 50 to 60 seconds.
- Begin with a compelling hook in the first sentence.
- Use natural spoken language, short sentences, and escalating stakes.
- End with a satisfying, surprising, or ironic payoff.
- Entirely fictional and original. Do not reference Reddit, real people, brands, or existing posts.
- No graphic violence, sexual content, self-harm, hate, or slurs.

Return ONLY valid JSON matching this shape:
{{"title":"under 65 characters", "story":"the narration text", "description":"under 150 characters, includes 2-4 relevant hashtags", "hashtags":["#shorts", "#storytime", "#... "]}}"""
    try:
        response = client.chat.completions.create(
            model=OPENAI_MODEL,
            messages=[{"role": "user", "content": prompt}],
            temperature=1.0,
            response_format={"type": "json_object"},
        )
        story = json.loads(response.choices[0].message.content)
        if not all(story.get(k) for k in ("title", "story", "description", "hashtags")):
            raise ValueError("Model response omitted required fields")
        story["theme"] = theme
        story["source"] = "original-ai"
        return story
    except Exception as exc:
        print(f"Story API failed ({exc}); using the local fallback story.")
        return fallback_story(theme)


def save_story(story: dict, stem: str | None = None) -> tuple[dict, str]:
    timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
    stem = stem or timestamp
    story["created_at"] = datetime.now(timezone.utc).isoformat()
    path = STORIES_DIR / f"{stem}.json"
    path.write_text(json.dumps(story, indent=2, ensure_ascii=True) + "\n")
    return story, stem


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Generate an original Short story")
    parser.add_argument("--theme", help="Story theme")
    parser.add_argument("--output-stem", help="Output filename stem")
    args = parser.parse_args()
    story, stem = save_story(generate_story(args.theme), args.output_stem)
    print(json.dumps({"stem": stem, "title": story["title"], "words": len(story["story"].split())}, indent=2))
