# retoor <retoor@molodetz.nl>

import logging
import re

from devplacepy.config import DEFAULT_MODIFIER_PROMPT, INTERNAL_MODEL
from devplacepy.database import add_modifier_usage, get_setting, get_table
from devplacepy.services.ai_context import build_context
from devplacepy.services.background import background
from devplacepy.services.correction import (
    CORRECTABLE_FIELDS,
    gateway_complete,
    new_usage_totals,
    schedule_pending,
)

logger = logging.getLogger(__name__)

MODIFIER_TIMEOUT_SECONDS = 60.0
AI_DIRECTIVE = re.compile(r"@ai\s+\S", re.IGNORECASE)


def has_ai_directive(text: str | None) -> bool:
    return bool(text) and AI_DIRECTIVE.search(text) is not None


def modifier_model() -> str:
    return get_setting("modifier_model", "") or INTERNAL_MODEL


def modify_text(
    api_key: str, prompt: str, text: str, context: str = ""
) -> tuple[str, dict | None]:
    system = (
        "The user's message contains an inline instruction marked with @ai. "
        + (prompt or DEFAULT_MODIFIER_PROMPT).strip()
        + " Return ONLY the resulting text, with no preamble, no explanation, no "
        "quotes and no code fences."
    )
    if context:
        system += (
            "\n\n# Context (use it to inform the result; never echo this block)\n"
            + context
        )
    return gateway_complete(
        api_key, system, text, MODIFIER_TIMEOUT_SECONDS, None, model=modifier_model()
    )


def schedule_modification(
    user: dict | None, table: str, uid: str, request: object = None
) -> None:
    if not user or table not in CORRECTABLE_FIELDS or not uid:
        return
    if not user.get("ai_modifier_enabled"):
        return
    api_key = (user.get("api_key") or "").strip()
    if not api_key:
        return
    row = get_table(table).find_one(uid=uid)
    if not row:
        return
    if not any(
        has_ai_directive(row.get(field) or "") for field in CORRECTABLE_FIELDS[table]
    ):
        return
    prompt = (user.get("ai_modifier_prompt") or DEFAULT_MODIFIER_PROMPT).strip()
    user_uid = user.get("uid") or ""
    if user.get("ai_modifier_sync") and schedule_pending(
        _run_modification, request, api_key, prompt, table, uid, user_uid, row
    ):
        return
    background.submit(_run_modification, api_key, prompt, table, uid, user_uid)


def _run_modification(
    api_key: str, prompt: str, table: str, uid: str, user_uid: str, row: dict | None = None
) -> None:
    fields = CORRECTABLE_FIELDS.get(table)
    if not fields:
        return
    if row is None:
        row = get_table(table).find_one(uid=uid)
    if not row:
        return
    updates: dict = {}
    totals = new_usage_totals()
    context = None
    for field in fields:
        original = row.get(field) or ""
        if not has_ai_directive(original):
            continue
        if context is None:
            context = build_context(table, uid, row, user_uid)
        modified, usage = modify_text(api_key, prompt, original, context)
        if usage:
            for key in totals:
                totals[key] += usage.get(key, 0)
        if modified and modified != original:
            updates[field] = modified
    if updates:
        updates["uid"] = uid
        get_table(table).update(updates, ["uid"])
        if table == "messages":
            from devplacepy.services.messaging.persist import push_content_revision

            push_content_revision(uid, ai_processed=True)
        if table == "users" and user_uid:
            from devplacepy.utils import clear_user_cache

            clear_user_cache(user_uid, propagate=False)
    if totals["calls"] and user_uid:
        add_modifier_usage(user_uid, totals)
