"""OpenAI recipe provider."""

import logging
import os

from openai import OpenAI, RateLimitError
from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_exponential_jitter

from ..models import Recipe
from .base import RecipeProvider

logger = logging.getLogger(__name__)


def _log_retry(retry_state):
    """Log retry attempts."""
    sleep_time = retry_state.next_action.sleep
    logger.info(
        "OpenAI rate limited. Retrying in %.1fs (attempt %d/10)",
        sleep_time,
        retry_state.attempt_number,
    )


class OpenAIProvider(RecipeProvider):
    """Recipe extraction using OpenAI."""

    DEFAULT_MODEL = "gpt-4o-mini"

    def __init__(self, model: str | None = None):
        api_key = os.getenv("OPENAI_API_KEY")
        if not api_key:
            raise ValueError(
                "OPENAI_API_KEY environment variable is required. "
                "Get your key at: https://platform.openai.com/api-keys"
            )
        self._client = OpenAI(api_key=api_key)
        self._model = model or self.DEFAULT_MODEL

    @retry(
        retry=retry_if_exception_type(RateLimitError),
        wait=wait_exponential_jitter(initial=2, max=60, jitter=5),
        stop=stop_after_attempt(10),
        before_sleep=_log_retry,
    )
    def extract_recipe(self, system_prompt: str, context: str) -> Recipe:
        schema = Recipe.model_json_schema()
        response = self._client.chat.completions.create(
            model=self._model,
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": context},
            ],
            response_format={
                "type": "json_schema",
                "json_schema": {
                    "name": "recipe",
                    "strict": True,
                    "schema": schema,
                },
            },
        )
        return Recipe.model_validate_json(response.choices[0].message.content)
