from __future__ import annotations
from typing import Any, List, Optional

from .base import ProviderConfig, LLMMessage, LLMResponse

class OpenAIProvider:
    """OpenAI Provider (real implementation).

    Uses the official `openai` Python SDK and the **Responses API** for text generation.
    """
    def __init__(self, config: ProviderConfig):
        self.config = config
        try:
            from openai import AsyncOpenAI  # type: ignore
        except Exception as e:  # pragma: no cover
            raise RuntimeError("Install provider extra: pip install adi-agentic-agi[openai]") from e

        kwargs: dict[str, Any] = {}
        if config.api_key:
            kwargs["api_key"] = config.api_key
        if config.base_url:
            kwargs["base_url"] = config.base_url
        # openai SDK supports default timeout/retries via httpx, but keep minimal here
        self._client = AsyncOpenAI(**kwargs)

    @staticmethod
    def _system_and_user(messages: List[LLMMessage]) -> tuple[str, str]:
        system_parts = [m.content for m in messages if m.role == "system" and m.content]
        user_parts = [m.content for m in messages if m.role in {"user", "developer"} and m.content]
        # keep it simple for now: single user string
        system = "\n\n".join(system_parts).strip()
        user = "\n\n".join(user_parts).strip()
        return system, user

    async def generate(self, messages: List[LLMMessage], **kwargs: Any) -> LLMResponse:
        system, user = self._system_and_user(messages)
        # prefer Responses API
        resp = await self._client.responses.create(
            model=self.config.model,
            instructions=system or None,
            input=user,
            **kwargs,
        )
        # SDK exposes `output_text`
        text = getattr(resp, "output_text", None) or ""
        return LLMResponse(text=text, raw={"id": getattr(resp, "id", None)})
