"""Retrieval/drift/deprecation logging and config mixin."""
from __future__ import annotations

from typing import Optional

from cortex.storage._helpers import _now


class ClaimLoggingMixin:
    """Mixin providing retrieval logging, drift/deprecation logging, and config ops."""

    async def log_retrieval(self, **kwargs) -> None:
        async with self._write_lock:
            conn = await self._get_conn()
            now = _now()
            cols = {
                "owner_id": kwargs.get("owner_id", "default"),
                "session_id": kwargs.get("session_id"),
                "query_text": kwargs.get("query_text", ""),
                "mode": kwargs.get("mode", "hybrid"),
                "token_budget": kwargs.get("token_budget"),
                "tokens_used": kwargs.get("tokens_used"),
                "candidates_json": kwargs.get("candidates_json"),
                "rerank_model": kwargs.get("rerank_model"),
                "selected_json": kwargs.get("selected_json"),
                "final_context_hash": kwargs.get("final_context_hash"),
                "latency_ms": kwargs.get("latency_ms"),
                "created_at": now,
            }
            col_names = ", ".join(cols.keys())
            placeholders = ", ".join("?" for _ in cols)
            await conn.execute(
                f"INSERT INTO retrieval_log ({col_names}) VALUES ({placeholders})",
                list(cols.values()),
            )
            await conn.commit()

    async def log_drift(self, **kwargs) -> None:
        async with self._write_lock:
            conn = await self._get_conn()
            now = _now()
            cols = {
                "cornerstone_id": kwargs["cornerstone_id"],
                "drift_score": kwargs["drift_score"],
                "semantic_sim": kwargs.get("semantic_sim"),
                "length_ratio": kwargs.get("length_ratio"),
                "phrase_preservation": kwargs.get("phrase_preservation"),
                "action_taken": kwargs.get("action_taken", "none"),
                "current_text": kwargs.get("current_text"),
                "golden_text": kwargs.get("golden_text"),
                "checked_at": kwargs.get("checked_at", now),
            }
            col_names = ", ".join(cols.keys())
            placeholders = ", ".join("?" for _ in cols)
            await conn.execute(
                f"INSERT INTO drift_log ({col_names}) VALUES ({placeholders})",
                list(cols.values()),
            )
            await conn.commit()

    async def log_deprecation(self, **kwargs) -> None:
        async with self._write_lock:
            conn = await self._get_conn()
            now = _now()
            cols = {
                "claim_id": kwargs["claim_id"],
                "session_id": kwargs.get("session_id"),
                "action": kwargs["action"],
                "reason": kwargs.get("reason"),
                "classifier": kwargs.get("classifier"),
                "created_at": now,
            }
            col_names = ", ".join(cols.keys())
            placeholders = ", ".join("?" for _ in cols)
            await conn.execute(
                f"INSERT INTO deprecation_log ({col_names}) VALUES ({placeholders})",
                list(cols.values()),
            )
            await conn.commit()

    async def get_config(self, key: str) -> Optional[str]:
        conn = await self._get_conn()
        async with conn.execute(
            "SELECT value FROM cortex_config WHERE key = ?", (key,)
        ) as cur:
            row = await cur.fetchone()
        return row[0] if row else None

    async def set_config(self, key: str, value: str) -> None:
        async with self._write_lock:
            conn = await self._get_conn()
            now = _now()
            await conn.execute(
                """
                INSERT INTO cortex_config (key, value, updated_at)
                VALUES (?, ?, ?)
                ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
                """,
                (key, value, now),
            )
            await conn.commit()
