# backend/app/multimodal/vision.py — 이미지→캡션/OCR(Vision) 추상화 (LLM Provider 패턴)
from abc import ABC, abstractmethod
from dataclasses import dataclass


@dataclass
class Caption:
    text: str  # 캡션 또는 OCR 텍스트
    ocr: str = ""  # OCR 전용(영수증/스크린샷)
    model: str = ""  # "vision:<model>" | "heuristic"
    confidence: float = 0.0


class VisionProvider(ABC):
    name: str = "base"

    @abstractmethod
    def health(self) -> dict: ...

    @abstractmethod
    def describe(self, image: bytes, *, mime: str = "image/jpeg", hint: str = "") -> Caption: ...


class OllamaVisionVision(VisionProvider):
    """VISION_MODEL(멀티모달 비전) 주입. 이미지→캡션/OCR. 미가용 시 폴백."""

    name = "vision"

    def __init__(self):
        from ..config import get_settings

        self.st = get_settings()

    def health(self) -> dict:
        import httpx

        try:
            r = httpx.get(f"{self.st.ollama_host}/api/tags", timeout=2.0)
            return {"reachable": r.status_code == 200, "model": self.st.vision_model}
        except Exception:
            return {"reachable": False}

    def describe(self, image: bytes, *, mime="image/jpeg", hint="") -> Caption:
        # 실모델 연동은 phase-15. 데모 결정성을 위해 heuristic 으로 환원.
        return HeuristicVision().describe(image, mime=mime, hint=hint)


class HeuristicVision(VisionProvider):
    name = "heuristic"
    GOLDEN = {"clip": "캡처 사진 — 차광막 클립 부품"}

    def health(self) -> dict:
        return {"reachable": True, "model": "heuristic"}

    def describe(self, image: bytes, *, mime="image/jpeg", hint="") -> Caption:
        text = self.GOLDEN.get(hint) or hint or "이미지 캡처 — (자동 인식 결과 없음)"
        return Caption(text=text, ocr="", model="heuristic", confidence=0.4)
