"""
Sistema de banco de dados para conversas contínuas
Gerencia SQLite com histórico de mensagens
Usa banco separado: conversations.db
"""
import sqlite3
from datetime import datetime
from typing import List, Dict, Optional
import json
from pathlib import Path


class ConversationDB:
    """Gerenciador do banco de dados SQLite"""
    
    def __init__(self, db_path: str = "conversations.db"):
        self.db_path = Path(db_path)
        self._init_database()
    
    def _init_database(self):
        """Inicializa tabelas do banco"""
        with sqlite3.connect(self.db_path) as conn:
            conn.execute("""
                CREATE TABLE IF NOT EXISTS conversations (
                    id TEXT PRIMARY KEY,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    title TEXT,
                    metadata TEXT
                )
            """)
            
            conn.execute("""
                CREATE TABLE IF NOT EXISTS messages (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    conversation_id TEXT NOT NULL,
                    role TEXT NOT NULL,
                    content TEXT NOT NULL,
                    metadata TEXT,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    FOREIGN KEY (conversation_id) REFERENCES conversations(id)
                )
            """)
            
            conn.execute("""
                CREATE INDEX IF NOT EXISTS idx_conv_messages 
                ON messages(conversation_id, created_at)
            """)
            
            conn.commit()
    
    def create_conversation(self, conv_id: str, title: str = None, metadata: Dict = None) -> bool:
        """Cria nova conversa"""
        try:
            with sqlite3.connect(self.db_path) as conn:
                conn.execute(
                    """INSERT INTO conversations (id, title, metadata) 
                       VALUES (?, ?, ?)""",
                    (conv_id, title or "Nova Conversa", json.dumps(metadata or {}))
                )
                conn.commit()
            return True
        except sqlite3.IntegrityError:
            return False
    
    def add_message(
        self, 
        conversation_id: str, 
        role: str, 
        content: str, 
        metadata: Dict = None
    ) -> int:
        """Adiciona mensagem à conversa"""
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.execute(
                """INSERT INTO messages (conversation_id, role, content, metadata) 
                   VALUES (?, ?, ?, ?)""",
                (conversation_id, role, content, json.dumps(metadata or {}))
            )
            
            # Atualiza timestamp da conversa
            conn.execute(
                """UPDATE conversations 
                   SET updated_at = CURRENT_TIMESTAMP 
                   WHERE id = ?""",
                (conversation_id,)
            )
            
            conn.commit()
            return cursor.lastrowid
    
    def get_conversation_history(
        self, 
        conversation_id: str, 
        limit: int = None
    ) -> List[Dict]:
        """Recupera histórico de mensagens"""
        with sqlite3.connect(self.db_path) as conn:
            conn.row_factory = sqlite3.Row
            
            query = """
                SELECT role, content, metadata, created_at as timestamp
                FROM messages 
                WHERE conversation_id = ? 
                ORDER BY created_at ASC
            """
            
            if limit:
                query += f" LIMIT {limit}"
            
            cursor = conn.execute(query, (conversation_id,))
            
            messages = []
            for row in cursor:
                messages.append({
                    'role': row['role'],
                    'content': row['content'],
                    'metadata': json.loads(row['metadata']) if row['metadata'] else {},
                    'timestamp': row['timestamp']
                })
            
            return messages
    
    def get_recent_messages(
        self, 
        conversation_id: str, 
        n: int = 5
    ) -> List[Dict]:
        """Retorna últimas N mensagens"""
        with sqlite3.connect(self.db_path) as conn:
            conn.row_factory = sqlite3.Row
            
            cursor = conn.execute(
                """SELECT role, content, metadata, created_at as timestamp
                   FROM messages 
                   WHERE conversation_id = ? 
                   ORDER BY created_at DESC 
                   LIMIT ?""",
                (conversation_id, n)
            )
            
            messages = []
            for row in cursor:
                messages.append({
                    'role': row['role'],
                    'content': row['content'],
                    'metadata': json.loads(row['metadata']) if row['metadata'] else {},
                    'timestamp': row['timestamp']
                })
            
            return list(reversed(messages))
    
    def conversation_exists(self, conversation_id: str) -> bool:
        """Verifica se conversa existe"""
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.execute(
                "SELECT 1 FROM conversations WHERE id = ?",
                (conversation_id,)
            )
            return cursor.fetchone() is not None
    
    def delete_conversation(self, conversation_id: str) -> bool:
        """Remove conversa e suas mensagens"""
        try:
            with sqlite3.connect(self.db_path) as conn:
                conn.execute("DELETE FROM messages WHERE conversation_id = ?", (conversation_id,))
                conn.execute("DELETE FROM conversations WHERE id = ?", (conversation_id,))
                conn.commit()
            return True
        except Exception:
            return False


# Singleton para reutilização
_db_instance = None

def get_db() -> ConversationDB:
    """Retorna instância única do banco"""
    global _db_instance
    if _db_instance is None:
        _db_instance = ConversationDB()
    return _db_instance
