"""
Lightweight in-memory DatabaseService for local development/tests.

Provides job tracking, traces, simple agent registry, and per-agent memory.
"""
from __future__ import annotations

import time
from typing import Any, Dict, List, Optional


class DatabaseService:
    def __init__(self, database_url: str | None = None):  # noqa: ARG002 (url unused for in-memory)
        self._jobs: Dict[str, Dict[str, Any]] = {}
        self._traces: List[Dict[str, Any]] = []
        self._agents: Dict[str, Dict[str, Any]] = {}
        # memory[agent_name][job_id or "__global__"][key] = value
        self._memory: Dict[str, Dict[str, Dict[str, Any]]] = {}

    # Optional setup for SQL backends; no-op here
    def create_tables(self) -> None:
        return

    # --- Jobs ---
    def create_job(self, job_id: str, pipeline: str | None = None, inputs: dict | None = None, **kwargs) -> None:
        pipeline_name = kwargs.get("pipeline_name") or pipeline or "pipeline"
        self._jobs[job_id] = {
            "job_id": job_id,
            "pipeline_name": pipeline_name,
            "inputs": inputs or {},
            "outputs": {},
            "status": "pending",
            "error": None,
            "created_at": time.time(),
            "completed_at": None,
        }

    def save_result(self, job_id: str, outputs: dict, status: str = "completed", error: Optional[str] = None) -> None:
        job = self._jobs.setdefault(job_id, {"job_id": job_id})
        job["outputs"] = outputs or {}
        job["status"] = status
        job["error"] = error
        job["completed_at"] = time.time()

    def get_result(self, job_id: str) -> dict | None:
        return self._jobs.get(job_id)

    def list_jobs(self, limit: int = 20) -> list[dict]:
        jobs = sorted(self._jobs.values(), key=lambda j: j.get("created_at", 0), reverse=True)
        return jobs[: max(1, int(limit))]

    # --- Traces ---
    def append_trace(self, job_id: str, agent_name: str, event_type: str, payload: dict) -> None:
        self._traces.append({
            "job_id": job_id,
            "agent": agent_name,
            "event": event_type,
            "payload": payload,
            "timestamp": time.time(),
        })

    # --- Agent registry ---
    def register_agent(self, agent_name: str, metadata: dict) -> None:
        self._agents[agent_name] = {**(self._agents.get(agent_name) or {}), **(metadata or {})}

    def list_agents(self) -> list[dict]:
        return [{"name": name, **meta} for name, meta in self._agents.items()]

    # --- Memory ---
    def _mem_scope(self, agent_name: str, job_id: Optional[str]) -> Dict[str, Any]:
        scope = job_id or "__global__"
        agent_store = self._memory.setdefault(agent_name, {})
        return agent_store.setdefault(scope, {})

    def memory_put(self, agent_name: str, key: str, value: Any, job_id: str | None = None) -> None:
        self._mem_scope(agent_name, job_id)[key] = value

    def memory_get(self, agent_name: str, key: str, job_id: str | None = None) -> Any:
        return self._mem_scope(agent_name, job_id).get(key)

    def memory_list(self, agent_name: str, job_id: str | None = None) -> dict:
        return dict(self._mem_scope(agent_name, job_id))

    # --- Prompts (for CLI prompt list compatibility) ---
    def list_prompts(self, limit: int = 20) -> list[dict]:
        # Alias to jobs for now
        return [
            {
                "prompt_id": j.get("job_id"),
                "prompt_name": j.get("pipeline_name"),
                "status": j.get("status"),
                "created_at": j.get("created_at"),
            }
            for j in self.list_jobs(limit)
        ]
