"""LLM-based extraction of PartQuery using OpenAI structured output (function calling)."""

from __future__ import annotations

import logging

import openai

from agent_samochodowy.config import Settings
from agent_samochodowy.models import PartQuery, Post

logger = logging.getLogger(__name__)

# JSON Schema for OpenAI function calling — mirrors PartQuery exactly
_EXTRACT_FUNCTION = {
    "name": "extract_part_query",
    "description": "Wyciągnij z posta informacje o szukanej części samochodowej.",
    "strict": True,
    "parameters": {
        "type": "object",
        "properties": {
            "is_part_request": {
                "type": "boolean",
                "description": "Czy post jest zapytaniem o część samochodową (kupno, szukanie).",
            },
            "brand": {
                "type": ["string", "null"],
                "description": "Marka pojazdu (np. VOLVO, OPEL, MAN). Null jeśli brak w tekście.",
            },
            "model": {
                "type": ["string", "null"],
                "description": "Model pojazdu (np. FH13, Astra F, TGA). Null jeśli brak.",
            },
            "year": {
                "type": ["string", "null"],
                "description": "Rocznik pojazdu (np. 2015, 98-03). Null jeśli brak.",
            },
            "category": {
                "type": ["string", "null"],
                "description": "Kategoria części (np. pompa wody, alternator, klocki hamulcowe).",
            },
            "engine_code": {
                "type": ["string", "null"],
                "description": "Kod silnika (np. C18NZ, D13A, N47D20). Null jeśli brak.",
            },
            "oe_numbers": {
                "type": "array",
                "items": {"type": "string"},
                "description": "Numery OE/katalogowe z tekstu. Pusta lista jeśli brak.",
            },
            "reason": {
                "type": "string",
                "description": "Krótkie uzasadnienie klasyfikacji (do audytu).",
            },
        },
        "required": [
            "is_part_request", "brand", "model", "year",
            "category", "engine_code", "oe_numbers", "reason",
        ],
        "additionalProperties": False,
    },
}

_SYSTEM_PROMPT = """Jesteś ekspertem od identyfikacji zapytań o części samochodowe w postach z grup na Facebooku.

Twoje zadanie:
1. Ustal czy post jest zapytaniem kupującego o część samochodową (is_part_request).
2. Jeśli tak — wyciągnij z tekstu: markę, model, rocznik, kategorię części, kod silnika, numery OE/katalogowe.
3. Jeśli czegoś nie ma w tekście — daj null (NIE zgaduj).

Rozpoznajesz polski slang motoryzacyjny:
- "strucla" = Opel Astra
- "bumer"/"bemka" = BMW
- "merc" = Mercedes
- "klocki" = klocki hamulcowe
- "turbo"/"turbinka" = turbosprężarka

Posty sprzedażowe (sprzedam, oddam) to NIE jest zapytanie — is_part_request = false.
Posty z pytaniami ogólnymi, off-topic — is_part_request = false.

Zawsze odpowiadaj wywołując funkcję extract_part_query."""


def extract_with_openai(post: Post, settings: Settings) -> PartQuery:
    """Use OpenAI function calling to extract a PartQuery from post text."""
    client = openai.OpenAI(api_key=settings.llm_api_key)

    response = client.chat.completions.create(
        model=settings.llm_model,
        max_completion_tokens=512,
        messages=[
            {"role": "system", "content": _SYSTEM_PROMPT},
            {"role": "user", "content": f"Post z grupy '{post.group}':\n\n{post.text}"},
        ],
        tools=[{"type": "function", "function": _EXTRACT_FUNCTION}],
        tool_choice={"type": "function", "function": {"name": "extract_part_query"}},
    )

    # Extract function call result
    message = response.choices[0].message
    if message.tool_calls:
        import json

        data = json.loads(message.tool_calls[0].function.arguments)
        return PartQuery(
            is_part_request=data.get("is_part_request", False),
            raw_text=post.text,
            brand=data.get("brand"),
            model=data.get("model"),
            year=data.get("year"),
            category=data.get("category"),
            engine_code=data.get("engine_code"),
            oe_numbers=data.get("oe_numbers", []),
            reason=data.get("reason", ""),
        )

    logger.warning("OpenAI did not return function call for post %s", post.post_id)
    return PartQuery(
        is_part_request=False,
        raw_text=post.text,
        reason="OpenAI did not return structured output",
    )
