import json
import urllib.request
import urllib.error
from archo.llm.prompt import SYSTEM_PROMPT
from archo.llm.providers.llm_base import LLMProvider
from archo.schemas.architecture import ArchitectureResponse


class OllamaProvider(LLMProvider):
    def __init__(self, model: str, ollama_host: str):
        self.host = ollama_host
        self.model = model

    def call(self, file_bundle: str) -> ArchitectureResponse:
        """Send file bundle to Ollama and return response text."""
        url = f"{self.host}/api/chat"

        payload = json.dumps({
            "model": self.model,
            "stream": False,
            "format": "json",
            "messages": [
                {"role": "system", "content": SYSTEM_PROMPT},
                {"role": "user", "content": file_bundle},
            ],
        }).encode("utf-8")

        print(f"Sending to Ollama ({self.model} @ {self.host})...")

        req = urllib.request.Request(url, data=payload, headers={"Content-Type": "application/json"})

        try:
            with urllib.request.urlopen(req) as resp:
                body = json.loads(resp.read().decode("utf-8"))
        except urllib.error.URLError as e:
            raise RuntimeError(f"Could not connect to Ollama at {self.host} — is it running? ({e.reason})")
        except json.JSONDecodeError:
            raise RuntimeError("Ollama returned an invalid response.")

        text = body.get("message", {}).get("content", "")
        if not text:
            raise RuntimeError("Ollama returned an empty response.")

        try:
            architecture_response = ArchitectureResponse.model_validate_json(text)
            return architecture_response
        except Exception as e:
            raise RuntimeError(f"Failed to parse Ollama response: {e}")