import os
import json
from pathlib import Path
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv(override=True)
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

EXCEPTIONS_PROMPT = """You are a pharma exception detection engine.

Compare actual observed values against SOP spec limits from this pharma batch data.
Find every parameter that breached its limit.

Return JSON only with this exact structure:
{
  "batch_id": string or null,
  "product_name": string or null,
  "summary": {
    "total_exceptions": number,
    "total_change": string,
    "critical": number,
    "critical_trend": one of ["Stable", "Increasing", "Decreasing"],
    "major": number,
    "major_trend": string,
    "minor": number,
    "minor_trend": one of ["Stable", "Increasing", "Decreasing"],
    "regulatory_risks": number,
    "compliance_gaps": number,
    "risk_level": one of ["Critical", "High", "Medium", "Low"],
    "risk_statement": string
  },
  "batch_risk": {
    "level": one of ["Critical", "High", "Medium", "Low"],
    "label": string,
    "description": string
  },
  "exception_clusters": [
    {
      "cluster_id": string,
      "cluster_name": string,
      "severity": one of ["Critical", "Major", "Minor"],
      "confidence": number 0-100,
      "linked_signals": number,
      "integrated_data_systems": array of strings,
      "system_explanation": string
    }
  ],
  "exceptions": [
    {
      "exception_id": string,
      "type": string,
      "parameter": string,
      "equipment_id": string or null,
      "actual_value": string,
      "spec_range": string,
      "severity": one of ["Critical", "Major", "Minor"],
      "process_step": string,
      "operator": string or null,
      "timestamp": string or null,
      "source_file": string,
      "cluster_id": string or null,
      "notes": string or null,
      "is_critical_compliance": true or false,
      "is_gmp_impacting": true or false
    }
  ],
  "most_affected_equipment": [
    {
      "equipment_id": string,
      "equipment_name": string,
      "exception_count": number
    }
  ],
  "most_affected_process_step": {
    "step_name": string,
    "percentage": number,
    "description": string
  },
  "recommended_next_action": string,
  "system_recommendation": string
}

Severity rules:
- Critical: value exceeds limit AND SOP says stop immediately
- Major: value exceeds limit but process can continue with monitoring
- Minor: soft breach, trending issue, or low-impact deviation

total_change: percentage change vs previous period e.g. "+12%"
critical_trend / minor_trend: "Stable" if no change, "Increasing" if more than before
major_trend: exact change string e.g. "+2" or "Stable"
regulatory_risks: count of exceptions that require regulatory reporting
compliance_gaps: count of critical compliance threshold breaches
risk_statement: one sentence summary of the batch risk

batch_risk.label: format as "Batch <batch_id> Risk"
batch_risk.description: one sentence describing the risk impact

is_critical_compliance: true if this exception requires regulatory reporting or QA stop
is_gmp_impacting: true if this exception directly impacts GMP compliance

Document content:
<content>
"""


async def detect_exceptions(extracted_data: dict) -> dict:
    try:
        data_str = json.dumps(extracted_data, indent=2)
        prompt = EXCEPTIONS_PROMPT.replace("<content>", data_str[:8000])

        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {
                    "role": "system",
                    "content": "You are a pharma exception detection engine. Return JSON only. No extra text."
                },
                {
                    "role": "user",
                    "content": prompt
                }
            ],
            response_format={"type": "json_object"},
            temperature=0
        )

        raw = response.choices[0].message.content
        result = json.loads(raw)
        result["status"] = "completed"
        return result

    except json.JSONDecodeError as e:
        return {
            "status": "parse_error",
            "error": str(e),
            "summary": {
                "total_exceptions": 0, "total_change": "0%",
                "critical": 0, "critical_trend": "Stable",
                "major": 0, "major_trend": "Stable",
                "minor": 0, "minor_trend": "Stable",
                "regulatory_risks": 0, "compliance_gaps": 0,
                "risk_level": "Low", "risk_statement": ""
            },
            "batch_risk": {"level": "Low", "label": "", "description": ""},
            "exception_clusters": [],
            "exceptions": [],
            "most_affected_equipment": [],
            "most_affected_process_step": {},
            "recommended_next_action": "",
            "system_recommendation": ""
        }
    except Exception as e:
        return {
            "status": "error",
            "error": str(e),
            "summary": {
                "total_exceptions": 0, "total_change": "0%",
                "critical": 0, "critical_trend": "Stable",
                "major": 0, "major_trend": "Stable",
                "minor": 0, "minor_trend": "Stable",
                "regulatory_risks": 0, "compliance_gaps": 0,
                "risk_level": "Low", "risk_statement": ""
            },
            "batch_risk": {"level": "Low", "label": "", "description": ""},
            "exception_clusters": [],
            "exceptions": [],
            "most_affected_equipment": [],
            "most_affected_process_step": {},
            "recommended_next_action": "",
            "system_recommendation": ""
        }