"""Synthetic Quick Assess API V2 client using Python's standard library.

Run with API_BASE_URL and API_BEARER_TOKEN set in the environment.
"""

from __future__ import annotations

import json
import os
import time
import urllib.error
import urllib.request
import uuid
from pathlib import Path


BASE_URL = os.environ["API_BASE_URL"].rstrip("/")
BEARER_TOKEN = os.environ["API_BEARER_TOKEN"]


def request(method: str, path: str, payload: dict | None = None, idempotency_key: str | None = None) -> tuple[int, dict, dict[str, str]]:
    headers = {
        "Accept": "application/json",
        "Authorization": f"Bearer {BEARER_TOKEN}",
        "X-Request-ID": f"python-example-{uuid.uuid4().hex[:12]}",
    }
    body = None
    if payload is not None:
        headers["Content-Type"] = "application/json"
        body = json.dumps(payload).encode("utf-8")
    if idempotency_key is not None:
        headers["Idempotency-Key"] = idempotency_key

    request_object = urllib.request.Request(BASE_URL + path, data=body, headers=headers, method=method)
    try:
        with urllib.request.urlopen(request_object, timeout=30) as response:
            response_body = json.loads(response.read().decode("utf-8"))
            return response.status, response_body, dict(response.headers)
    except urllib.error.HTTPError as error:
        error_body = json.loads(error.read().decode("utf-8"))
        code = error_body.get("error", {}).get("code", "unknown")
        raise RuntimeError(f"API {error.code} {code}: {error_body.get('error', {}).get('message', 'request failed')}") from error


# 1. Verify the approved token's integration, insurer, employee, and abilities.
_, context, _ = request("GET", "/api/v2/integration/context")
print(json.dumps(context["data"], indent=2))

# 2. Register a synthetic vehicle. Retry a network timeout with this same key and payload.
vehicle_payload = {
    "external_vehicle_reference": "PYTHON-SYNTHETIC-VEHICLE-001",
    "make": "MERCEDES BENZ",
    "model": "C CLASS- W202",
    "manufacture_year": 2001,
    "variant": None,
    "registration_number": "UAA 456Y",
    "chassis_number": "SYNTHETIC-CHASSIS-002",
}
vehicle_key = f"python-vehicle-{uuid.uuid4().hex}"
_, vehicle_response, _ = request("POST", "/api/v2/vehicles", vehicle_payload, vehicle_key)
vehicle_reference = vehicle_response["data"]["vehicle"]["vehicle_reference"]
print("Vehicle:", vehicle_reference)

# 3. Safe vehicle lookup.
_, vehicle, _ = request("GET", f"/api/v2/vehicles/{vehicle_reference}")
print(json.dumps(vehicle["data"]["vehicle"], indent=2))

# 4. Submit an assessment using vehicle_reference.
assessment_payload = {
    "external_client_reference": "PYTHON-SYNTHETIC-CLAIM-001",
    "currency": "UGX",
    "vehicle_reference": vehicle_reference,
    "parts": [{"part_name": "Front Bumper", "quantity": 1, "claimed_amount": 450000}],
}
assessment_key = f"python-assessment-{uuid.uuid4().hex}"
_, submission, _ = request("POST", "/api/v2/assessments", assessment_payload, assessment_key)
request_reference = submission["data"]["request_reference"]
print("Request:", request_reference)

# 5. Poll and retrieve safe JSON. Do not create a new key while the original is processing.
for _ in range(12):
    _, status_response, _ = request("GET", f"/api/v2/assessments/{request_reference}/status")
    status_data = status_response["data"]
    print("Processing status:", status_data["status"])
    if status_data["status"] in {"completed", "pending_catalogue", "failed"}:
        break
    time.sleep(int(status_data.get("poll_after_seconds", 5)))
_, result, _ = request("GET", f"/api/v2/assessments/{request_reference}")
print(json.dumps(result["data"], indent=2))

# 6. After an authorized workflow user finalizes the assessment, download the official PDF.
# This endpoint requires assessments:reports:read and returns private binary bytes.
pdf_request = urllib.request.Request(
    BASE_URL + f"/api/v2/assessments/{request_reference}/report.pdf",
    headers={"Authorization": f"Bearer {BEARER_TOKEN}", "Accept": "application/pdf"},
    method="GET",
)
try:
    with urllib.request.urlopen(pdf_request, timeout=60) as response:
        pdf_bytes = response.read()
        if response.headers.get_content_type() != "application/pdf" or not pdf_bytes.startswith(b"%PDF-"):
            raise RuntimeError("The report endpoint returned a non-PDF response.")
        Path("official-assessment-synthetic.pdf").write_bytes(pdf_bytes)
        print("Saved PDF version:", response.headers.get("X-Assessment-Report-Version"))
except urllib.error.HTTPError as error:
    # Expected until the separate workflow approval/finalization step completes.
    print("PDF not available yet:", error.code)
