# retoor <retoor@molodetz.nl>

from __future__ import annotations

import logging
from datetime import datetime, timezone
from typing import Any

logger = logging.getLogger("devii.virtual_tools.store")

TABLE = "devii_virtual_tools"
INDEXED_COLUMNS = (["owner_kind", "owner_id"], ["owner_kind", "owner_id", "name"])


def _now_iso() -> str:
    return datetime.now(timezone.utc).isoformat()


def _schema_for(row: dict[str, Any]) -> dict[str, Any]:
    input_description = row.get("input_description") or "Free-form input for this tool."
    return {
        "type": "function",
        "function": {
            "name": row["name"],
            "description": f"{row.get('description', '')} (your custom tool)",
            "parameters": {
                "type": "object",
                "properties": {
                    "input": {"type": "string", "description": input_description},
                },
                "required": [],
                "additionalProperties": False,
            },
        },
    }


class VirtualToolStore:
    def __init__(self, db: Any, owner_kind: str, owner_id: str) -> None:
        self._db = db
        self._owner_kind = owner_kind
        self._owner_id = owner_id
        self._ensure_indexes()

    def _ensure_indexes(self) -> None:
        if TABLE not in self._db.tables:
            return
        table = self._db[TABLE]
        if not table.has_column("deleted_at"):
            table.create_column_by_example("deleted_at", "")
        if not table.has_column("deleted_by"):
            table.create_column_by_example("deleted_by", "")
        for columns in INDEXED_COLUMNS:
            table.create_index(columns)

    @property
    def _table(self) -> Any:
        return self._db[TABLE]

    @property
    def _scope(self) -> dict[str, str]:
        return {"owner_kind": self._owner_kind, "owner_id": self._owner_id}

    def find(self, name: str) -> dict[str, Any] | None:
        if TABLE not in self._db.tables:
            return None
        return self._table.find_one(name=name, deleted_at=None, **self._scope)

    def list(self) -> list[dict[str, Any]]:
        if TABLE not in self._db.tables:
            return []
        return list(self._table.find(deleted_at=None, **self._scope))

    def create(self, record: dict[str, Any]) -> dict[str, Any]:
        now = _now_iso()
        record = {
            "deleted_at": None,
            "deleted_by": None,
            **record,
            **self._scope,
            "created_at": now,
            "updated_at": now,
        }
        existing = self._table.find_one(name=record["name"], **self._scope)
        if existing:
            record["id"] = existing["id"]
            self._table.update(record, ["id"])
        else:
            self._table.insert(record)
        logger.info(
            "Virtual tool created name=%s owner=%s/%s",
            record.get("name"),
            self._owner_kind,
            self._owner_id,
        )
        return record

    def update(self, name: str, changes: dict[str, Any]) -> None:
        row = self._table.find_one(name=name, deleted_at=None, **self._scope)
        if not row:
            return
        changes = {**changes, "id": row["id"], "updated_at": _now_iso()}
        self._table.update(changes, ["id"])
        logger.debug("Virtual tool updated name=%s changes=%s", name, list(changes))

    def delete(self, name: str) -> bool:
        row = self._table.find_one(name=name, deleted_at=None, **self._scope)
        if not row:
            return False
        self._table.update(
            {
                "id": row["id"],
                "deleted_at": _now_iso(),
                "deleted_by": f"{self._owner_kind}:{self._owner_id}",
            },
            ["id"],
        )
        logger.info("Virtual tool soft-deleted name=%s", name)
        return True

    def tool_schemas(self) -> list[dict[str, Any]]:
        return [_schema_for(row) for row in self.list() if row.get("enabled", 1)]
