import os
import json
from pathlib import Path
from openai import OpenAI
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
from datetime import datetime
from fastapi import Request
from dotenv import load_dotenv

load_dotenv(override=True)
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

REPORTS_DIR = Path("reports")
REPORTS_DIR.mkdir(exist_ok=True)

REPORT_PROMPT = """You are a senior pharma quality investigator writing a GMP-compliant investigation report.

STRICT RULES — NEVER BREAK THESE:
1. NEVER say product was not impacted without checking LIMS results first
2. If ANY LIMS result shows Status=Fail — impact_assessment MUST say product was impacted with exact test name and value
3. NEVER use generic phrases — always use exact values from the data
4. Severity MUST come from Deviation Report severity field — not your own judgment
5. ref_id MUST come from Deviation_ID in the Deviation Report
6. Duration MUST be calculated from Equipment Log timestamps — not estimated
7. Root cause MUST reference exact maintenance log observations — thermocouple, calibration dates, drift values
8. Operator MUST be included from Equipment Log Operator_ID field
9. Batch disposition MUST come from Deviation Report Batch_Disposition field
10. CAPA actions MUST reference actual work order IDs and actions from Maintenance Log

Return JSON only with this exact structure:
{
  "report_metadata": {
    "ref_id": string,
    "revision": "Rev 01",
    "status": "Audit Ready",
    "severity": one of ["Critical", "High", "Medium", "Low"],
    "generated_date": string,
    "batch_id": string,
    "product_name": string,
    "plant": string,
    "confidential": true
  },
  "ai_generated_summary": string,
  "approval_workflow": {
    "qa_reviewer": {
      "name": string,
      "status": one of ["Approved", "Pending", "Rejected"],
      "note": string or null
    },
    "qa_head": {
      "name": string,
      "status": one of ["Approved", "Pending Final Sign Off", "Rejected"]
    }
  },
  "compliance_tags": array of strings,
  "sections": {
    "incident_overview": {
      "batch_number": string,
      "incident_date": string,
      "deviation_type": string,
      "department": string
    },
    "detected_deviations": [
      {
        "signal_exception": string,
        "duration": string,
        "peak_value": string,
        "limit": string,
        "is_deviation": true or false
      }
    ],
    "executive_summary": string,
    "deviation_description": string,
    "timeline": [
      {
        "timestamp": string,
        "event": string,
        "severity": one of ["critical", "warning", "info"]
      }
    ],
    "scope_of_review": string,
    "exceptions_summary": string,
    "root_cause_analysis": {
      "probable_cause": string,
      "methodology": string,
      "conclusion": string
    },
    "capa_summary": string,
    "impact_assessment": string,
    "conclusion": string,
    "regulatory_compliance": [
      {
        "standard": string,
        "status": one of ["Compliant", "Non-Compliant", "Under Review"]
      }
    ]
  },
  "compliance_checklist": [
    {
      "standard": string,
      "description": string,
      "status": one of ["pass", "warn", "fail"]
    }
  ],
  "evidence_coverage_score": number 0-100,
  "confidence_label": one of ["High Confidence", "Medium Confidence", "Low Confidence"],
  "ai_insight": string,
  "export_options": ["Export as PDF", "Export as Word", "Submit to Regulatory"]
}

Section writing rules:

ref_id: use Deviation_ID from Deviation Report exactly e.g. DEV-2024-0312
severity: copy exactly from Deviation Report Severity field

executive_summary (4-5 sentences):
- Name exact batch, product, plant, date
- Name exact parameters that deviated with exact values and limits
- Reference exact equipment ID
- State LIMS outcome — if assay failed state exact % and OOS reference
- State batch disposition from Deviation Report

deviation_description (5-6 sentences):
- Exact timestamp of first deviation from Equipment Log
- Exact operator ID from Equipment Log
- Progressive temperature rise with timestamps from Equipment Log
- Exact peak value reached
- What action was taken and when — from Deviation Report Immediate_Actions

detected_deviations duration:
- Calculate from Equipment Log — time from first Alert status to process stopped
- Do NOT estimate — use actual timestamps

root_cause_analysis.probable_cause:
- Reference exact equipment ID
- Reference calibration due date and overdue days from Maintenance Log
- Reference thermocouple drift value (+X°C) from Maintenance Log breakdown inspection
- Reference work order ID

root_cause_analysis.conclusion (4-5 sentences):
- Name the exact root cause with evidence
- Reference Maintenance Log dates and observations
- Reference Equipment Log notes at Alert rows
- Reference calibration overdue status

impact_assessment — CRITICAL RULE:
- CHECK LIMS results first — if any Status=Fail → product WAS impacted
- State exact test name, result value, specification, OOS reference number
- State batch disposition — HOLD or released
- If assay failed — state this clearly: "Assay result of X% is below specification of Y%-Z%"
- NEVER say "no impact" if LIMS has any Fail result

capa_summary:
- List actual CAPA actions from Maintenance Log Action_Taken field
- Reference work order IDs
- Reference new parts installed
- Reference requalification report if available

conclusion:
- State current batch status from Deviation Report Batch_Disposition
- State OOS investigation reference if LIMS failed
- State whether equipment was returned to service

Data to generate report from:
<content>
"""


def get_base_url(request: Request) -> str:
    return str(request.base_url).rstrip("/")


async def generate_report_json(data: dict) -> dict:
    try:
        data_str = json.dumps(data, indent=2)
        prompt = REPORT_PROMPT.replace("<content>", data_str[:10000])

        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {
                    "role": "system",
                    "content": """You are a senior pharma quality investigator.
CRITICAL INSTRUCTIONS:
- Always check LIMS results before writing impact assessment
- If LIMS has any Fail result — product was impacted — say so with exact values
- Never say product was not impacted without evidence
- Use exact values from data — no generic statements
- Severity comes from Deviation Report — not your judgment
- ref_id comes from Deviation_ID in Deviation Report
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)
        return result

    except Exception as e:
        return {"status": "error", "error": str(e)}


def generate_pdf(report: dict, filename: str) -> Path:
    filepath = REPORTS_DIR / filename
    doc = SimpleDocTemplate(
        str(filepath),
        pagesize=A4,
        rightMargin=0.75 * inch,
        leftMargin=0.75 * inch,
        topMargin=0.75 * inch,
        bottomMargin=0.75 * inch
    )

    styles = getSampleStyleSheet()
    story = []

    dark = colors.HexColor("#1a1916")
    muted = colors.HexColor("#7a7869")
    light_bg = colors.HexColor("#f5f4f0")

    title_style = ParagraphStyle("Title", parent=styles["Normal"],
        fontSize=22, fontName="Helvetica-Bold", textColor=dark,
        spaceAfter=4, leading=28)
    sub_style = ParagraphStyle("Sub", parent=styles["Normal"],
        fontSize=10, textColor=muted, spaceAfter=2)
    h1_style = ParagraphStyle("H1", parent=styles["Normal"],
        fontSize=14, fontName="Helvetica-Bold", textColor=dark,
        spaceBefore=16, spaceAfter=6)
    body_style = ParagraphStyle("Body", parent=styles["Normal"],
        fontSize=10, textColor=dark, leading=16, spaceAfter=8)
    label_style = ParagraphStyle("Label", parent=styles["Normal"],
        fontSize=8, textColor=muted, fontName="Helvetica-Bold",
        spaceAfter=2, leading=12)

    meta = report.get("report_metadata", {})
    sections = report.get("sections", {})
    checklist = report.get("compliance_checklist", [])
    severity = meta.get("severity", "Critical").upper()

    # ── Header
    story.append(Paragraph(
        f'INVESTIGATION REPORT  <font color="#c0392b">[{severity} SEVERITY]</font>',
        title_style
    ))
    story.append(Paragraph(
        f'Ref ID: {meta.get("ref_id", "DEV-2024-00001")}  |  {meta.get("revision", "Rev 01")}  |  {"CONFIDENTIAL" if meta.get("confidential") else ""}',
        sub_style
    ))
    story.append(Paragraph(
        f'Status: {meta.get("status", "Audit Ready")}  |  Generated: {meta.get("generated_date", datetime.now().strftime("%Y-%m-%d"))}',
        sub_style
    ))
    story.append(Spacer(1, 10))

    # ── Batch info
    batch_data = [
        ["Batch ID", meta.get("batch_id", "—"), "Product", meta.get("product_name", "—")],
        ["Plant", meta.get("plant", "—"), "Severity", severity]
    ]
    batch_table = Table(batch_data, colWidths=[1.2*inch, 2.5*inch, 1.2*inch, 2.5*inch])
    batch_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), light_bg),
        ("FONTNAME", (0, 0), (0, -1), "Helvetica-Bold"),
        ("FONTNAME", (2, 0), (2, -1), "Helvetica-Bold"),
        ("FONTSIZE", (0, 0), (-1, -1), 9),
        ("TEXTCOLOR", (0, 0), (-1, -1), dark),
        ("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#e2e0d8")),
        ("PADDING", (0, 0), (-1, -1), 6),
    ]))
    story.append(batch_table)
    story.append(Spacer(1, 14))
    story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#e2e0d8")))

    # ── AI Summary
    ai_summary = report.get("ai_generated_summary", "")
    if ai_summary:
        story.append(Spacer(1, 10))
        story.append(Paragraph("AI Generated Summary", h1_style))
        story.append(Paragraph(ai_summary, body_style))

    def add_section(number, title, content):
        story.append(Spacer(1, 10))
        story.append(Paragraph(f"{number}. {title}", h1_style))
        story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#e2e0d8")))
        story.append(Spacer(1, 6))
        if content:
            story.append(Paragraph(str(content), body_style))

    # ── Section 01 Incident Overview
    inc = sections.get("incident_overview", {})
    if inc:
        story.append(Spacer(1, 10))
        story.append(Paragraph("01. Incident Overview", h1_style))
        story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#e2e0d8")))
        story.append(Spacer(1, 6))
        inc_data = [
            ["BATCH NUMBER", "INCIDENT DATE", "DEVIATION TYPE", "DEPARTMENT"],
            [
                inc.get("batch_number", "—"),
                inc.get("incident_date", "—"),
                inc.get("deviation_type", "—"),
                inc.get("department", "—")
            ]
        ]
        inc_table = Table(inc_data, colWidths=[1.75*inch, 1.75*inch, 2*inch, 1.75*inch])
        inc_table.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#e2e0d8")),
            ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
            ("FONTSIZE", (0, 0), (-1, -1), 9),
            ("TEXTCOLOR", (0, 0), (-1, -1), dark),
            ("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#e2e0d8")),
            ("PADDING", (0, 0), (-1, -1), 8),
        ]))
        story.append(inc_table)

    # ── Section 02 Detected Deviations
    devs = sections.get("detected_deviations", [])
    if devs:
        story.append(Spacer(1, 10))
        story.append(Paragraph("02. Detected Deviations", h1_style))
        story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#e2e0d8")))
        story.append(Spacer(1, 6))
        dev_data = [["SIGNAL/EXCEPTION", "DURATION", "PEAK VALUE", "LIMIT"]]
        for d in devs:
            dev_data.append([
                d.get("signal_exception", "—"),
                d.get("duration", "—"),
                d.get("peak_value", "—"),
                d.get("limit", "—")
            ])
        dev_table = Table(dev_data, colWidths=[2.5*inch, 1.2*inch, 1.5*inch, 2*inch])
        dev_table.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#e2e0d8")),
            ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
            ("FONTSIZE", (0, 0), (-1, -1), 9),
            ("TEXTCOLOR", (0, 0), (-1, -1), dark),
            ("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#e2e0d8")),
            ("PADDING", (0, 0), (-1, -1), 8),
            ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, light_bg]),
        ]))
        story.append(dev_table)

    add_section(3, "Executive Summary", sections.get("executive_summary", ""))
    add_section(4, "Deviation Description", sections.get("deviation_description", ""))

    # ── Section 05 RCA
    story.append(Spacer(1, 10))
    story.append(Paragraph("05. Root Cause Analysis", h1_style))
    story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#e2e0d8")))
    story.append(Spacer(1, 6))
    rca = sections.get("root_cause_analysis", {})
    if rca:
        rca_data = [
            ["PROBABLE CAUSE", "METHODOLOGY"],
            [rca.get("probable_cause", "—"), rca.get("methodology", "—")],
            ["CONCLUSION", ""],
            [rca.get("conclusion", "—"), ""]
        ]
        rca_table = Table(rca_data, colWidths=[3.5*inch, 3.5*inch])
        rca_table.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#e2e0d8")),
            ("BACKGROUND", (0, 2), (-1, 2), colors.HexColor("#e2e0d8")),
            ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
            ("FONTNAME", (0, 2), (-1, 2), "Helvetica-Bold"),
            ("FONTSIZE", (0, 0), (-1, -1), 9),
            ("TEXTCOLOR", (0, 0), (-1, -1), dark),
            ("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#e2e0d8")),
            ("PADDING", (0, 0), (-1, -1), 8),
            ("SPAN", (0, 2), (1, 2)),
            ("SPAN", (0, 3), (1, 3)),
        ]))
        story.append(rca_table)

    add_section(6, "Scope of Review", sections.get("scope_of_review", ""))
    add_section(7, "Exceptions", sections.get("exceptions_summary", ""))
    add_section(8, "CAPA", sections.get("capa_summary", ""))
    add_section(9, "Impact Assessment", sections.get("impact_assessment", ""))
    add_section(10, "Conclusion", sections.get("conclusion", ""))

    # ── Section 11 Regulatory Compliance
    reg_compliance = sections.get("regulatory_compliance", [])
    if reg_compliance:
        story.append(Spacer(1, 10))
        story.append(Paragraph("11. Regulatory Compliance", h1_style))
        story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#e2e0d8")))
        story.append(Spacer(1, 6))
        reg_data = [["Standard", "Status"]]
        for r in reg_compliance:
            reg_data.append([r.get("standard", "—"), r.get("status", "—")])
        reg_table = Table(reg_data, colWidths=[4*inch, 3.2*inch])
        reg_table.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#e2e0d8")),
            ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
            ("FONTSIZE", (0, 0), (-1, -1), 9),
            ("TEXTCOLOR", (0, 0), (-1, -1), dark),
            ("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#e2e0d8")),
            ("PADDING", (0, 0), (-1, -1), 8),
            ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, light_bg]),
        ]))
        story.append(reg_table)

    # ── Compliance checklist
    if checklist:
        story.append(Spacer(1, 10))
        story.append(Paragraph("Compliance Checklist", h1_style))
        story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#e2e0d8")))
        story.append(Spacer(1, 6))
        check_data = [["Standard", "Description", "Status"]]
        for item in checklist:
            status_text = "✓ Pass" if item["status"] == "pass" else "⚠ Review" if item["status"] == "warn" else "✗ Fail"
            check_data.append([item["standard"], item["description"], status_text])
        check_table = Table(check_data, colWidths=[2*inch, 4*inch, 1.2*inch])
        check_table.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#e2e0d8")),
            ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
            ("FONTSIZE", (0, 0), (-1, -1), 9),
            ("TEXTCOLOR", (0, 0), (-1, -1), dark),
            ("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#e2e0d8")),
            ("PADDING", (0, 0), (-1, -1), 6),
            ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, light_bg]),
        ]))
        story.append(check_table)

    # ── Footer
    story.append(Spacer(1, 14))
    story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#e2e0d8")))
    story.append(Spacer(1, 6))
    story.append(Paragraph(
        f'Evidence Coverage Score: {report.get("evidence_coverage_score", 0)}% — {report.get("confidence_label", "")}',
        label_style
    ))
    ai_insight = report.get("ai_insight", "")
    if ai_insight:
        story.append(Paragraph(f"AI Insight: {ai_insight}", body_style))

    doc.build(story)
    return filepath


async def generate_full_report(data: dict, base_url: str) -> dict:
    report_json = await generate_report_json(data)
    batch_id = report_json.get("report_metadata", {}).get("batch_id", "BATCH")
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"Investigation_Report_{batch_id}_{timestamp}.pdf"
    generate_pdf(report_json, filename)
    report_json["pdf_filename"] = filename
    report_json["download_url"] = f"{base_url}/reports/download/{filename}"
    report_json["status"] = "completed"
    return report_json