"""Unit tests for the prompts module."""

from __future__ import annotations

import sqlite3
from pathlib import Path

import pytest

from core.database import Database
from core.prompts import PromptStore, SystemPrompt


class TestSystemPrompt:
    """Tests for SystemPrompt dataclass."""

    def test_to_dict_and_from_dict_roundtrip(self) -> None:
        prompt = SystemPrompt(
            id="abc123",
            name="default",
            content="You are helpful.",
            created_at="2026-02-04T10:00:00Z",
            updated_at="2026-02-04T10:00:00Z",
            is_active=True,
        )
        data = prompt.to_dict()
        restored = SystemPrompt.from_dict(data)

        assert restored.id == prompt.id
        assert restored.name == prompt.name
        assert restored.content == prompt.content
        assert restored.is_active is True


class TestPromptStore:
    """Tests for PromptStore class."""

    @pytest.fixture
    def store(self, tmp_path: Path) -> PromptStore:
        db = Database(tmp_path / "test.db")
        return PromptStore(db)

    def test_add_creates_prompt(self, store: PromptStore) -> None:
        prompt = store.add("test", "You are a test assistant.")
        assert prompt.id
        assert prompt.name == "test"
        assert prompt.content == "You are a test assistant."
        assert prompt.is_active is False

    def test_add_duplicate_name_raises(self, store: PromptStore) -> None:
        store.add("unique", "first")
        with pytest.raises(sqlite3.IntegrityError):
            store.add("unique", "second")

    def test_list_all_empty(self, store: PromptStore) -> None:
        assert store.list_all() == []

    def test_list_all_returns_prompts(self, store: PromptStore) -> None:
        store.add("a", "content a")
        store.add("b", "content b")
        prompts = store.list_all()
        assert len(prompts) == 2

    def test_get_active_none(self, store: PromptStore) -> None:
        assert store.get_active() is None

    def test_set_active(self, store: PromptStore) -> None:
        p = store.add("test", "content")
        result = store.set_active(p.id)
        assert result is True

        active = store.get_active()
        assert active is not None
        assert active.id == p.id

    def test_set_active_deactivates_others(self, store: PromptStore) -> None:
        p1 = store.add("first", "content 1")
        p2 = store.add("second", "content 2")

        store.set_active(p1.id)
        store.set_active(p2.id)

        active = store.get_active()
        assert active is not None
        assert active.id == p2.id

        # p1 should no longer be active
        prompts = store.list_all()
        p1_entry = next(p for p in prompts if p.id == p1.id)
        assert p1_entry.is_active is False

    def test_set_active_nonexistent(self, store: PromptStore) -> None:
        assert store.set_active("missing") is False

    def test_update_content(self, store: PromptStore) -> None:
        p = store.add("test", "old content")
        updated = store.update(p.id, "new content")
        assert updated is not None
        assert updated.content == "new content"
        assert updated.updated_at >= p.updated_at

    def test_update_nonexistent(self, store: PromptStore) -> None:
        assert store.update("missing", "content") is None

    def test_delete_existing(self, store: PromptStore) -> None:
        p = store.add("test", "content")
        assert store.delete(p.id) is True
        assert store.list_all() == []

    def test_delete_nonexistent(self, store: PromptStore) -> None:
        assert store.delete("missing") is False

    def test_list_all_active_first(self, store: PromptStore) -> None:
        p1 = store.add("inactive", "content 1")
        p2 = store.add("active", "content 2")
        store.set_active(p2.id)

        prompts = store.list_all()
        assert prompts[0].id == p2.id
        assert prompts[0].is_active is True
