"""Lab 06 - Vision: interpret images, then generate them.

Objective 2.3 - Interpret visual input in prompts by using a deployed multimodal
                model; create new visual outputs; build an app with vision.

Run:  python 06_vision.py
"""
import base64
import mimetypes
import os
import pathlib

from _common import banner, get_clients, require

MULTIMODAL = os.getenv("MULTIMODAL_DEPLOYMENT") or require("MODEL_DEPLOYMENT")
IMAGE_MODEL = os.getenv("IMAGE_DEPLOYMENT", "gpt-image-1")

_, openai = get_clients()


def to_data_url(path: str) -> str:
    """Local file -> data URL, the way you pass your own images."""
    mime = mimetypes.guess_type(path)[0] or "image/jpeg"
    with open(path, "rb") as handle:
        return f"data:{mime};base64,{base64.b64encode(handle.read()).decode()}"


banner("Part A - Describe an image from a URL")

SAMPLE = ("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-"
          "sample-data-files/master/ComputerVision/Images/objects.jpg")

response = openai.responses.create(
    model=MULTIMODAL,
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text",
             "text": "Describe this image. List every distinct object you can see."},
            {"type": "input_image", "image_url": SAMPLE},
        ],
    }],
)
print(" ", response.output_text)
print("\n  Note the shape: content is a LIST OF TYPED PARTS.")
print("  input_text and input_image travel together in one message.")

banner("Part B - Structured extraction from an image")

response = openai.responses.create(
    model=MULTIMODAL,
    instructions=(
        "You extract structured data from images. Reply with JSON only:\n"
        '{"scene": string, "objects": [{"name": string, "count": number}],'
        ' "dominant_colours": [string], "text_visible": [string]}'
    ),
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text", "text": "Extract this image."},
            {"type": "input_image", "image_url": SAMPLE},
        ],
    }],
    temperature=0,
)
print(" ", response.output_text)

banner("Part C - Compare two images in one prompt")

SECOND = ("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-"
          "sample-data-files/master/ComputerVision/Images/landmark.jpg")

response = openai.responses.create(
    model=MULTIMODAL,
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text",
             "text": "Compare these two images. What differs in subject and setting?"},
            {"type": "input_image", "image_url": SAMPLE},
            {"type": "input_image", "image_url": SECOND},
        ],
    }],
)
print(" ", response.output_text)
print("\n  Multiple input_image parts in one message = comparison. Exam-relevant.")

banner("Part D - Your own local image (optional)")

local = pathlib.Path("sample.jpg")
if local.exists():
    response = openai.responses.create(
        model=MULTIMODAL,
        input=[{
            "role": "user",
            "content": [
                {"type": "input_text", "text": "What is in this image? Any text?"},
                {"type": "input_image", "image_url": to_data_url(str(local))},
            ],
        }],
    )
    print(" ", response.output_text)
else:
    print("  Drop a sample.jpg in this folder to try a local image via data URL.")

banner("Part E - Generate an image")

try:
    result = openai.images.generate(
        model=IMAGE_MODEL,
        prompt=(
            "A cutaway technical illustration of a Victorian railway station "
            "roof truss, muted palette, fine linework, white background, "
            "no text, no people"
        ),
        size="1024x1024",
        quality="medium",
        n=1,
    )
    payload = result.data[0]
    if getattr(payload, "b64_json", None):
        pathlib.Path("generated.png").write_bytes(base64.b64decode(payload.b64_json))
        print("  Wrote generated.png")
    else:
        print("  Image URL:", payload.url)
except Exception as exc:                                    # noqa: BLE001
    print(f"  Image generation unavailable: {exc}")
    print(f"  Deploy an image model and set IMAGE_DEPLOYMENT in .env.")

print("""
  Prompt recipe:  SUBJECT + STYLE + COMPOSITION + CONSTRAINTS
  Parameters that drive cost and latency: size, quality, n
""")

banner("Part F - When NOT to use a multimodal model")

print("""
  Multimodal model      -> describe, reason, answer questions, bespoke JSON
  Azure AI Vision       -> bounding-box COORDINATES, tags, OCR at scale
  Custom Vision         -> YOUR OWN classes (product SKUs, defect types)
  Azure AI Face         -> verification / identification  (LIMITED ACCESS)
  Content Understanding -> schema fields + confidence + grounding

  VisualFeatures flags:  CAPTION (sentence) | OBJECTS (boxes)
                         READ (text)        | TAGS (labels + confidence)

  Production shape: Vision gives precision, the model gives judgement.
  Feed OCR text and detected objects INTO the model for the decision.
""")
