"""Gemini Vision utility — extract data dari foto laporan shift SPBU."""

import base64
import json
import logging

import httpx

from app.core.config import settings

logger = logging.getLogger(__name__)

GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta"

EXTRACT_PROMPT = """
Kamu adalah sistem OCR untuk laporan shift SPBU (Stasiun Pengisian Bahan Bakar Umum) Indonesia.

Ekstrak data dari foto laporan shift ini dan kembalikan dalam format JSON.

INSTRUKSI:
- Baca semua angka dengan teliti
- Tanggal format: YYYY-MM-DD
- Shift: kembalikan angka romawi atau angka sesuai yang tertulis (I, II, III, atau 1, 2, 3)
- Teller: angka meter pompa (bisa 5-7 digit)
- Pecahan uang: jumlah LEMBAR per denominasi (bukan nilai total)
- Kalau tidak terbaca / tidak ada, kembalikan null

Kembalikan JSON dengan struktur PERSIS seperti ini (tanpa markdown, tanpa penjelasan):
{
  "tanggal": "YYYY-MM-DD",
  "shift": "II",
  "nozzles": [
    {
      "nama": "1A",
      "teller_awal_manual": "1234567",
      "teller_akhir_manual": "1240000",
      "teller_awal_digital": "1234567",
      "teller_akhir_digital": "1240000"
    }
  ],
  "harga": [
    {"produk": "Pertalite", "harga": 10000},
    {"produk": "Pertamax", "harga": 12350},
    {"produk": "Biosolar", "harga": 6800},
    {"produk": "Pertamax Turbo", "harga": null}
  ],
  "pecahan": {
    "100000": 162,
    "50000": 175,
    "20000": 14,
    "10000": 48,
    "5000": 44,
    "2000": 80,
    "1000": 13,
    "500": 0,
    "200": 0,
    "100": 0
  }
}
"""


async def extract_from_image(image_bytes: bytes, mime_type: str) -> dict:
    """
    Kirim gambar ke Gemini Vision dan ekstrak data laporan shift.

    Returns dict dengan keys: tanggal, shift, nozzles, harga, pecahan
    """
    api_key = settings.GEMINI_API_KEY
    if not api_key:
        raise ValueError("GEMINI_API_KEY not configured")

    image_b64 = base64.b64encode(image_bytes).decode("utf-8")

    url = f"{GEMINI_BASE_URL}/models/{settings.GEMINI_MODEL}:generateContent?key={api_key}"

    body = {
        "contents": [
            {
                "parts": [
                    {
                        "inlineData": {
                            "mimeType": mime_type,
                            "data": image_b64,
                        }
                    },
                    {"text": EXTRACT_PROMPT},
                ]
            }
        ],
        "generationConfig": {
            "temperature": 0.1,  # Rendah = lebih konsisten untuk OCR
            "responseMimeType": "application/json",
        },
    }

    import asyncio
    async with httpx.AsyncClient(timeout=60) as client:
        for attempt in range(3):
            resp = await client.post(url, json=body)
            if resp.status_code == 429:
                if attempt < 2:
                    wait = (attempt + 1) * 10  # 10s, 20s
                    logger.warning("Gemini rate limit, retry in %ds (attempt %d/3)", wait, attempt + 1)
                    await asyncio.sleep(wait)
                    continue
                raise ValueError("Gemini sedang sibuk (rate limit). Tunggu 1 menit lalu coba lagi.")
            resp.raise_for_status()
            break
        data = resp.json()

    candidates = data.get("candidates", [])
    if not candidates:
        raise ValueError("Gemini tidak mengembalikan hasil")

    parts = candidates[0].get("content", {}).get("parts", [])
    raw_text = ""
    for part in parts:
        if "text" in part:
            raw_text += part["text"]

    # Parse JSON dari response
    raw_text = raw_text.strip()
    if raw_text.startswith("```"):
        # Strip markdown code block kalau ada
        lines = raw_text.split("\n")
        raw_text = "\n".join(lines[1:-1])

    result = json.loads(raw_text)
    logger.info("GeminiVision: extracted tanggal=%s shift=%s nozzles=%d",
                result.get("tanggal"), result.get("shift"), len(result.get("nozzles", [])))
    return result
