"""Model-aware LLM system prompt builder for banner generation.

Each image generation model family has different prompt conventions:
- DALL-E 3 / gpt-image-1: natural language sentences, negatives embedded in text
- Flux (standard): no negative prompts, no SD-style weights, front-load subject
- Flux Kontext: edit-instruction style (what to preserve + what to change)

The LLM that rewrites/enhances the image prompt must follow these rules
so the final prompt is optimal for the target model.
"""

from __future__ import annotations

from .presets import BannerStyle, ImageModelFamily


# ── Per-family prompt rules ───────────────────────────────────────────────────

_RULES_DALLE = """\
## Target model: DALL-E 3 / gpt-image-1
Rules for this model:
- Write in natural language sentences — NOT comma-separated keyword lists
- Embed negative constraints directly in the prompt text:
  "no text", "no watermarks", "no human faces", "no logos"
- Do NOT use Stable Diffusion weight syntax like (word:1.5) — unsupported
- Optimal length: 150–200 words (model handles longer prompts well)
- Front-load the most important subject/concept in the first sentence
- Be explicit about colors, lighting, and composition — model follows them closely
- Negative prompt field does not exist — all constraints must be positive framing
  ("clean background" not "no clutter", "sharp focus" not "not blurry")
"""


_RULES_GEMINI = """\
## Target model: Google Gemini image generation (gemini-2.5-flash-image, gemini-3-pro-image)
Rules for this model:
- Write in natural language sentences — Gemini follows narrative descriptions closely
- Gemini excels at complex scenes with multiple elements — be specific about spatial relationships
- Embed negative constraints directly in the prompt text:
  "no text", "no watermarks", "no human faces", "no logos", "no UI chrome"
- Gemini handles long prompts well — 100–250 words is optimal
- Front-load the primary concept in the first sentence
- Specify lighting explicitly — Gemini is very responsive to lighting descriptions
- Use color hex codes for precision: "electric blue (#0066FF) accent glow"
- Gemini has strong style adherence — name the art style explicitly:
  "rendered in Pixar 3D animation style", "isometric 3D illustration", etc.
- No separate negative prompt field — embed all constraints in the main prompt
"""

_RULES_UNKNOWN = _RULES_DALLE  # safe fallback


_FAMILY_RULES: dict[ImageModelFamily, str] = {
    ImageModelFamily.DALLE:   _RULES_DALLE,
    ImageModelFamily.GEMINI:  _RULES_GEMINI,
    ImageModelFamily.UNKNOWN: _RULES_UNKNOWN,
}


# ── System prompt builder ─────────────────────────────────────────────────────

_BASE_SYSTEM_PROMPT = """\
You are a senior visual designer specializing in developer tool branding and README hero images.

Your job: read a project's context (title, description, README) and write a detailed, vivid
image generation prompt that will produce a stunning, professional banner image.

## Prompt structure (priority order — models weight earlier tokens more)
[Primary concept] + [Style/medium] + [Composition] + [Lighting] + [Color palette] + [Mood] + [Technical constraints]

## General rules
- No text, logos, letters, or human faces in the image
- Avoid clichés: no rocket ships, no hands typing, no generic office scenes, no stock photo feel
- Pick 2–3 dominant colors that match the project personality
- High contrast between subject and background
- Wide, cinematic composition — one clear focal object or scene

## Step-by-step approach
1. Extract the CORE CONCEPT (what this tool does in one word: "route", "search", "embed", "deploy")
2. Choose a VISUAL METAPHOR that represents the concept
3. Apply the STYLE DIRECTION below as the aesthetic anchor
4. Add precise LIGHTING and COLORS
5. End with model-appropriate negative constraints (see model rules below)

{model_rules}

{style_section}

Return ONLY the image generation prompt. No preamble, no explanation, no markdown.
"""

_STYLE_SECTION_TEMPLATE = """\
## Visual style direction
The user has requested this aesthetic: {style_name}

Style description: {style_hint}

Use this as the primary aesthetic direction. Adapt it to suit the project's context —
do not copy it verbatim, but let it shape the mood, palette, and composition.
"""


def build_system_prompt(
    family: ImageModelFamily,
    style: BannerStyle | None = None,
) -> str:
    """Build a model-aware LLM system prompt for banner generation.

    Args:
        family: Image model family (determines prompt rules).
        style: Visual style enum — passed as aesthetic direction hint to the LLM.
               If None, LLM picks the style freely based on project context.
    """
    model_rules = _FAMILY_RULES[family]

    if style is not None:
        style_section = _STYLE_SECTION_TEMPLATE.format(
            style_name=style.value,
            style_hint=style.hint(),
        )
    else:
        style_section = (
            "## Visual style direction\n"
            "No specific style requested. Pick the best style for this project based on its "
            "core concept and personality. Options: dark glassmorphism, isometric 3D, "
            "cinematic AI network, cyberpunk neon, blueprint/engineering, minimal gradient, "
            "speed/fiber-optic, Pixar 3D, holographic, abstract gradient mesh."
        )

    return _BASE_SYSTEM_PROMPT.format(
        model_rules=model_rules,
        style_section=style_section,
    )


__all__ = ["build_system_prompt"]
