"""SQLite-backed chat history for room host.

Persists messages to ~/.brynq/rooms/{room_id}/chat.db so history
survives host restarts. Reconnecting peers get full history from DB.
"""

import json
import logging
import sqlite3
import time
import uuid
from pathlib import Path
from typing import Any, Dict, List, Optional

logger = logging.getLogger("brynq.rooms.chat_store")

ROOMS_DIR = Path.home() / ".brynq" / "rooms"

SCHEMA = """
CREATE TABLE IF NOT EXISTS messages (
    id          TEXT PRIMARY KEY,
    room_id     TEXT NOT NULL,
    sender_id   TEXT NOT NULL,
    sender_name TEXT NOT NULL,
    content     TEXT NOT NULL,
    type        TEXT NOT NULL DEFAULT 'chat',
    timestamp   TEXT NOT NULL,
    created_at  REAL NOT NULL
);

CREATE INDEX IF NOT EXISTS idx_messages_room ON messages(room_id);
CREATE INDEX IF NOT EXISTS idx_messages_time ON messages(created_at);
"""


class RoomChatStore:
    """Persistent chat history for a single room."""

    def __init__(self, room_id: str):
        self.room_id = room_id
        self._db_path = ROOMS_DIR / room_id / "chat.db"
        self._db_path.parent.mkdir(parents=True, exist_ok=True)
        self._conn = sqlite3.connect(str(self._db_path))
        self._conn.row_factory = sqlite3.Row
        self._conn.execute("PRAGMA journal_mode=WAL")
        self._conn.executescript(SCHEMA)
        self._conn.commit()
        logger.info("Chat store initialized: %s", self._db_path)

    def add_message(self, msg: Dict[str, Any]) -> Dict[str, Any]:
        """Store a message and return it with generated id/timestamp if missing."""
        msg_id = msg.get("id") or str(uuid.uuid4())
        timestamp = msg.get("timestamp") or time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
        now = time.time()

        self._conn.execute(
            "INSERT OR IGNORE INTO messages (id, room_id, sender_id, sender_name, content, type, timestamp, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
            (msg_id, self.room_id, msg.get("sender_id", ""), msg.get("sender_name", ""),
             msg.get("content", ""), msg.get("type", "chat"), timestamp, now),
        )
        self._conn.commit()

        return {
            "id": msg_id,
            "room_id": self.room_id,
            "sender_id": msg.get("sender_id", ""),
            "sender_name": msg.get("sender_name", ""),
            "content": msg.get("content", ""),
            "type": msg.get("type", "chat"),
            "timestamp": timestamp,
        }

    def get_history(self, limit: int = 200) -> List[Dict[str, Any]]:
        """Get recent messages for the room, oldest first."""
        cur = self._conn.execute(
            "SELECT id, room_id, sender_id, sender_name, content, type, timestamp FROM messages WHERE room_id = ? ORDER BY created_at DESC LIMIT ?",
            (self.room_id, limit),
        )
        rows = [dict(r) for r in cur.fetchall()]
        rows.reverse()  # oldest first
        return rows

    def count(self) -> int:
        """Count total messages in this room."""
        cur = self._conn.execute("SELECT COUNT(*) FROM messages WHERE room_id = ?", (self.room_id,))
        return cur.fetchone()[0]

    def search_messages(self, query: str, limit: int = 20) -> List[Dict[str, Any]]:
        """Search room messages by keyword (LIKE match).

        Returns matching messages with sender and timestamp, newest first.
        """
        limit = max(1, min(limit, 100))
        safe_q = f"%{query}%"
        cur = self._conn.execute(
            "SELECT id, sender_name, content, timestamp FROM messages "
            "WHERE room_id = ? AND content LIKE ? ORDER BY created_at DESC LIMIT ?",
            (self.room_id, safe_q, limit),
        )
        return [dict(r) for r in cur.fetchall()]

    def close(self):
        """Close the database connection."""
        self._conn.close()
