"""Lab 04 - Text analysis, two routes.

Objective 2.2 - Build a lightweight application that includes text analysis.

Route A: a generative model with a JSON schema  (no extra Azure resource)
Route B: Azure AI Language                      (needs LANGUAGE_ENDPOINT)

Run:  python 04_text_analysis.py
"""
import json
import os

from _common import banner, get_clients, require

MODEL = require("MODEL_DEPLOYMENT")

REVIEWS = [
    "The seats were filthy but the staff were wonderful. Contoso Rail should be ashamed.",
    "Booked with Fabrikam Travel on 3 May. Flawless. Sarah at the desk deserves a raise.",
    "Train delayed 90 minutes, no announcement, no refund offered. Third time this month.",
]

banner("Route A - Generative model, bespoke JSON schema")

_, openai = get_clients()

SCHEMA_INSTRUCTIONS = (
    "You analyse customer feedback. Reply with JSON ONLY, no prose, matching:\n"
    '{"sentiment": "positive|negative|neutral|mixed",'
    ' "confidence": number,'
    ' "themes": [string],'
    ' "organisations": [string],'
    ' "people": [string],'
    ' "urgent": boolean,'
    ' "summary": string}'
)

for review in REVIEWS:
    result = openai.responses.create(
        model=MODEL,
        instructions=SCHEMA_INSTRUCTIONS,
        input=review,
        temperature=0,          # deterministic: this is extraction, not creativity
    )
    print(f"\n  {review[:60]}...")
    try:
        parsed = json.loads(result.output_text.strip().strip("`").removeprefix("json"))
        print("   ", json.dumps(parsed, indent=6)[6:])
    except json.JSONDecodeError:
        print("    raw:", result.output_text)

print("\n  Route A wins when the output shape is bespoke to your app.")
print("  Note 'mixed' on review 1 - filthy seats AND wonderful staff.")

banner("Route B - Azure AI Language (structured, scored, categorised)")

if not os.getenv("LANGUAGE_ENDPOINT"):
    print("  LANGUAGE_ENDPOINT not set - skipping.")
    print("  Set it in .env to run this half. The code below is exam-relevant either way:")
    print("""
    from azure.ai.textanalytics import TextAnalyticsClient
    client = TextAnalyticsClient(endpoint=..., credential=DefaultAzureCredential())

    s = client.analyze_sentiment(documents=docs, show_opinion_mining=True)[0]
    s.sentiment            # positive | negative | neutral | mixed
    s.confidence_scores    # positive / neutral / negative, summing to 1

    client.extract_key_phrases(documents=docs)   # topics
    client.recognize_entities(documents=docs)    # named things WITH categories
    client.recognize_pii_entities(documents=docs)
    """)
else:
    from azure.identity import DefaultAzureCredential
    from azure.ai.textanalytics import TextAnalyticsClient

    client = TextAnalyticsClient(
        endpoint=os.environ["LANGUAGE_ENDPOINT"],
        credential=DefaultAzureCredential(),
    )

    for doc, sentiment in zip(REVIEWS, client.analyze_sentiment(
        documents=REVIEWS, show_opinion_mining=True
    )):
        print(f"\n  {doc[:60]}...")
        print(f"    sentiment : {sentiment.sentiment}")
        print(f"    scores    : pos={sentiment.confidence_scores.positive:.2f} "
              f"neu={sentiment.confidence_scores.neutral:.2f} "
              f"neg={sentiment.confidence_scores.negative:.2f}")
        for s in sentiment.sentences:
            for opinion in s.mined_opinions:
                targets = ", ".join(a.text for a in opinion.assessments)
                print(f"    opinion   : {opinion.target.text} -> "
                      f"{opinion.target.sentiment} ({targets})")

    for doc, entities in zip(REVIEWS, client.recognize_entities(documents=REVIEWS)):
        named = ", ".join(f"{e.text} [{e.category}]" for e in entities.entities)
        print(f"\n  entities: {named}")

    for doc, phrases in zip(REVIEWS, client.extract_key_phrases(documents=REVIEWS)):
        print(f"  key phrases: {', '.join(phrases.key_phrases)}")

print("\nExam anchors:")
print("  - Sentiment has FOUR labels: positive, negative, neutral, MIXED")
print("  - Key phrases = topics.  Entities = named things WITH categories")
print("  - Opinion mining = sentiment per aspect ('food good, service bad')")
print("  - Extractive summarisation copies sentences; abstractive writes new ones")
print("  - LUIS and QnA Maker are RETIRED -> Azure AI Language")
