"""Three everyday decisions about one product review, in one API request."""

import argparse
import json
import os
import sys
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen


REVIEWS = {
    "negative": (
        "These headphones stopped working after one day. "
        "I want a refund. Very disappointed."
    ),
    "positive": (
        "These headphones sound fantastic and fit perfectly. "
        "I'm happy with my purchase and I'm keeping them."
    ),
    "mixed": (
        "The sound is great, but the headband hurts after an hour. "
        "It's a little annoying, but I'm keeping them for now."
    ),
}

QUESTIONS = {
    "wants_refund": {
        "type": "noul",  # This is the API's name for a yes/no question.
        "instructions": "Does the reviewer explicitly ask for their money back?",
    },
    "topic": {
        "type": "choice",
        "instructions": (
            "What is the main topic of this review? When there is a complaint, "
            "pick its topic rather than the topic of any praise."
        ),
        "criteria": {
            "sound": "How the headphones sound.",
            "comfort": "How the headphones fit or feel when worn.",
            "broken_product": "The headphones are faulty or stopped working.",
            "other": "Another topic, or no clear topic.",
        },
    },
    "dissatisfaction": {
        "type": "score",
        "instructions": "How much dissatisfaction does this review express?",
        "criteria": [
            "0: No dissatisfaction; the reviewer is happy.",
            "1: Mild dissatisfaction; a small complaint or annoyance.",
            "2: Strong dissatisfaction; very disappointed or angry.",
        ],
    },
}


def print_probabilities(probabilities):
    """Print one option per line: score levels in order, choices highest first."""
    items = list(probabilities.items() if isinstance(probabilities, dict)
                 else enumerate(probabilities))
    if all(str(name).isdigit() for name, _ in items):
        items.sort(key=lambda item: int(item[0]))
    else:
        items.sort(key=lambda item: item[1], reverse=True)
    for name, value in items:
        print(f"     {str(name):<16}{value:6.1%}")


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--example", choices=REVIEWS, default="negative")
    parser.add_argument("--text", help="Use your own review instead of an example.")
    parser.add_argument("--json", action="store_true", help="Print the full API response.")
    parser.add_argument("--dry-run", action="store_true", help="Print the request; make no API call.")
    args = parser.parse_args()

    payload = {
        "model": "gemini-decision-1",
        "input": args.text if args.text is not None else REVIEWS[args.example],
        "questions": QUESTIONS,
    }
    if args.dry_run:
        print(json.dumps(payload, indent=2))
        return

    api_key = os.environ.get("GEMINI_API_KEY")
    if not api_key:
        parser.exit(1, "Set GEMINI_API_KEY first, or use --dry-run to inspect the request.\n")

    print("Sending 3 questions to Gemini Decision 1...")
    # This decodes the HTTP response's JSON, not AI-generated answer text.
    request = Request(
        "https://generativelanguage.googleapis.com/v1beta/decisions",
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json", "x-goog-api-key": api_key},
        method="POST",
    )
    try:
        with urlopen(request, timeout=60) as response:
            result = json.load(response)
    except HTTPError as error:
        print(f"API request failed (HTTP {error.code}).", file=sys.stderr)
        print(error.read().decode("utf-8", errors="replace"), file=sys.stderr)
        sys.exit(1)
    except (URLError, TimeoutError) as error:
        print(f"Could not reach the API: {error}", file=sys.stderr)
        sys.exit(1)

    if args.json:
        print(json.dumps(result, indent=2))
        return

    answers = result["answers"]
    refund = answers["wants_refund"]
    topic = answers["topic"]
    dissatisfaction = answers["dissatisfaction"]
    print(f"\nREVIEW: {payload['input']}\n")
    print(f"1. Wants a refund?   P(yes) {refund['noul']:6.1%}   confidence {refund['confidence']:6.1%}")
    print(f"\n2. Main topic:       {topic['choice']}   confidence {topic['confidence']:6.1%}")
    print_probabilities(topic["probabilities"])
    print(f"\n3. Dissatisfaction:  {dissatisfaction['score']:.2f} / 2   "
          f"confidence {dissatisfaction['confidence']:6.1%}")
    print_probabilities(dissatisfaction["probabilities"])

    # Illustrative thresholds for the video; tune these on real examples.
    if refund["noul"] >= 0.9:
        action = "Flag for a refund review."
    elif refund["noul"] <= 0.1:
        action = "No explicit refund request detected."
    else:
        action = "Ask a person to check whether a refund was requested."
    print(f"\nCODE DECIDES: {action}")
    print("This demo only prints the action; it does not issue refunds.\n")


if __name__ == "__main__":
    main()
