from functools import lru_cache
from openai import AsyncClient
from maur.models import CodingTask
from maur.settings import MaurLLMSettings


@lru_cache
def llm_settings() -> MaurLLMSettings:
    return MaurLLMSettings.from_env()

def openai_client(settings: MaurLLMSettings | None = None) -> AsyncClient:
    if not settings:
        settings = llm_settings()

    return AsyncClient(
        api_key=settings.maur_llm_token.get_secret_value(),
        base_url=settings.maur_llm_api.encoded_string()
    )


async def completion(prompt: str, client: AsyncClient | None = None, task: CodingTask | None = None) -> str:

    settings = llm_settings()

    if not client:
        client = openai_client(settings)

    res = await client.completions.create(
        model=settings.maur_llm_model,
        prompt=prompt
    )

    if task and res.usage:
        task.tokens_input += res.usage.prompt_tokens
        task.tokens_output += res.usage.completion_tokens

    return res.choices[0].text


async def summarize_changes(diff: str, client: AsyncClient | None = None, task: CodingTask | None = None) -> str:
    settings = llm_settings()
    summary_prompt = settings.maur_summary_prompt.format(
        git_diff=diff,
        prompt=task.prompt if task else ""
    )
    return await completion(summary_prompt, client=client, task=task)

