"""System prompt management."""

from __future__ import annotations

import uuid
from dataclasses import dataclass
from datetime import datetime, timezone
from typing import Any

from database import Database
from logging_config import get_logger

log = get_logger(__name__)


@dataclass
class SystemPrompt:
    """A saved system prompt template."""

    id: str
    name: str
    content: str
    created_at: str
    updated_at: str
    is_active: bool

    def to_dict(self) -> dict[str, Any]:
        return {
            "id": self.id,
            "name": self.name,
            "content": self.content,
            "created_at": self.created_at,
            "updated_at": self.updated_at,
            "is_active": self.is_active,
        }

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> SystemPrompt:
        return cls(
            id=data["id"],
            name=data["name"],
            content=data["content"],
            created_at=data["created_at"],
            updated_at=data["updated_at"],
            is_active=bool(data.get("is_active", False)),
        )


class PromptStore:
    """SQLite-backed system prompt management."""

    def __init__(self, db: Database) -> None:
        self._db = db
        self._log = log.bind(component="prompt_store")

    @staticmethod
    def _row_to_prompt(row: Any) -> SystemPrompt:
        return SystemPrompt(
            id=row["id"],
            name=row["name"],
            content=row["content"],
            created_at=row["created_at"],
            updated_at=row["updated_at"],
            is_active=bool(row["is_active"]),
        )

    def add(self, name: str, content: str) -> SystemPrompt:
        """Add a new system prompt."""
        now = datetime.now(timezone.utc).isoformat()
        prompt = SystemPrompt(
            id=uuid.uuid4().hex[:8],
            name=name,
            content=content,
            created_at=now,
            updated_at=now,
            is_active=False,
        )
        self._db.conn.execute(
            """INSERT INTO system_prompts
               (id, name, content, created_at, updated_at, is_active)
               VALUES (?, ?, ?, ?, ?, ?)""",
            (prompt.id, prompt.name, prompt.content, prompt.created_at, prompt.updated_at, 0),
        )
        self._db.conn.commit()
        self._log.info("prompt_added", prompt_id=prompt.id, name=name)
        return prompt

    def update(self, prompt_id: str, content: str) -> SystemPrompt | None:
        """Update a prompt's content. Returns updated prompt or None if not found."""
        now = datetime.now(timezone.utc).isoformat()
        cursor = self._db.conn.execute(
            "UPDATE system_prompts SET content = ?, updated_at = ? WHERE id = ?",
            (content, now, prompt_id),
        )
        self._db.conn.commit()
        if cursor.rowcount == 0:
            return None
        row = self._db.conn.execute("SELECT * FROM system_prompts WHERE id = ?", (prompt_id,)).fetchone()
        return self._row_to_prompt(row)

    def delete(self, prompt_id: str) -> bool:
        """Delete a prompt. Returns True if deleted."""
        cursor = self._db.conn.execute("DELETE FROM system_prompts WHERE id = ?", (prompt_id,))
        self._db.conn.commit()
        if cursor.rowcount > 0:
            self._log.info("prompt_deleted", prompt_id=prompt_id)
            return True
        return False

    def list_all(self) -> list[SystemPrompt]:
        """List all prompts, active first then by updated_at desc."""
        rows = self._db.conn.execute("SELECT * FROM system_prompts ORDER BY is_active DESC, updated_at DESC").fetchall()
        return [self._row_to_prompt(row) for row in rows]

    def get_active(self) -> SystemPrompt | None:
        """Get the currently active system prompt, if any."""
        row = self._db.conn.execute("SELECT * FROM system_prompts WHERE is_active = 1").fetchone()
        if row is None:
            return None
        return self._row_to_prompt(row)

    def set_active(self, prompt_id: str) -> bool:
        """Set a prompt as active (deactivates all others). Returns False if not found."""
        row = self._db.conn.execute("SELECT id FROM system_prompts WHERE id = ?", (prompt_id,)).fetchone()
        if row is None:
            return False
        self._db.conn.execute("UPDATE system_prompts SET is_active = 0")
        self._db.conn.execute("UPDATE system_prompts SET is_active = 1 WHERE id = ?", (prompt_id,))
        self._db.conn.commit()
        self._log.info("prompt_activated", prompt_id=prompt_id)
        return True
