import sqlite3
import os

DB_PATH = os.environ.get("TAIRUMA_DB_PATH", "tairuma.db")

def init_db():
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    # Activar modo WAL para mejor concurrencia en Windows
    cursor.execute("PRAGMA journal_mode=WAL;")
    
    # Tabla de Usuarios (Numa) - Bloque 1
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS usuarios (
            id TEXT PRIMARY KEY,
            alias TEXT UNIQUE,
            frase_inicial TEXT,
            saldo REAL DEFAULT 0.0,
            password_hash TEXT  -- Hash seguro de la Semilla (Nunca guardar texto plano)
        )
    ''')
    
    # Tabla de Transacciones - Bloque 1 & 4
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS transacciones (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            usuario_id TEXT,
            descripcion TEXT,
            cantidad REAL,
            fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (usuario_id) REFERENCES usuarios (id)
        )
    ''')
    
    # Tabla de Mercado - Bloque 6
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS mercado (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            alias TEXT,
            producto TEXT,
            precio REAL,
            descripcion TEXT,
            categoria TEXT DEFAULT 'Bien', -- Bien, Servicio
            fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')
    
    # Simple migration for existing dev DB
    try:
        cursor.execute("ALTER TABLE mercado ADD COLUMN categoria TEXT DEFAULT 'Bien'")
    except:
        pass # Already exists

    # Migration for Governance (votos_pro, votos_con, estado)
    try: cursor.execute("ALTER TABLE propuestas ADD COLUMN votos_pro INTEGER DEFAULT 0")
    except: pass
    try: cursor.execute("ALTER TABLE propuestas ADD COLUMN votos_con INTEGER DEFAULT 0")
    except: pass
    try: cursor.execute("ALTER TABLE propuestas ADD COLUMN estado TEXT DEFAULT 'Activa'")
    except: pass

    # Migration for Referrals (invited_by)
    try: cursor.execute("ALTER TABLE usuarios ADD COLUMN invited_by TEXT")
    except: pass

    # Migration for Safe Discovery (Zona/Vereda)
    try: cursor.execute("ALTER TABLE usuarios ADD COLUMN zona TEXT DEFAULT 'Bosque Profundo'")
    except: pass
    
    # Tabla de Chat - Bloque 7
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS chat (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            remitente TEXT,
            destinatario TEXT,
            mensaje TEXT,
            grupo_id INTEGER,
            fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')

    # Migration: add grupo_id to existing chat tables
    try: cursor.execute("ALTER TABLE chat ADD COLUMN grupo_id INTEGER")
    except: pass
    
    # Tabla de Actividad (Log) - Bloque 8
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS actividad_log (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            evento TEXT,
            fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')

    # Insertar usuario por defecto si no existe
    cursor.execute("SELECT COUNT(*) FROM usuarios")
    if cursor.fetchone()[0] == 0:
        # Hash de "semilla maestra de numa" + "tairuma_secure_salt"
        founder_hash = "6c4e4b1c9cdd35566b9f9fe52e97e92283d580d2ebb2acca95c55895eed2415f"
        cursor.execute("INSERT INTO usuarios (id, alias, frase_inicial, saldo, password_hash) VALUES (?, ?, ?, ?, ?)",
                      ("root_id", "Numa_Fundador", "Raíz fuerte, fruto seguro.", 1000.0, founder_hash))
        cursor.execute("INSERT INTO transacciones (usuario_id, descripcion, cantidad) VALUES (?, ?, ?)",
                      ("root_id", "Saldo Inicial de Fundación", 1000.0))
    else:
        # Hotfix v3.1.2: Actualizar el hash al salt correcto (tairuma_secure_salt) si tiene el antiguo
        founder_hash_correcto = "6c4e4b1c9cdd35566b9f9fe52e97e92283d580d2ebb2acca95c55895eed2415f"
        founder_hash_antiguo = "d58279b747698c7a658b0af05d97f12a5b5e19a76ae98dd5e8255ab026229ca7"
        cursor.execute("UPDATE usuarios SET password_hash = ? WHERE alias = 'Numa_Fundador' AND (password_hash IS NULL OR password_hash = '' OR password_hash = ?)", 
                      (founder_hash_correcto, founder_hash_antiguo))

    # Tabla de Propuestas de Gobernanza
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS propuestas (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            autor TEXT,
            titulo TEXT,
            descripcion TEXT,
            votos_pro INTEGER DEFAULT 0,
            votos_con INTEGER DEFAULT 0,
            estado TEXT DEFAULT 'Activa',
            fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')
    
    # Tabla de Votos individuales
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS votos (
            propuesta_id INTEGER,
            usuario_alias TEXT,
            opcion TEXT,
            PRIMARY KEY (propuesta_id, usuario_alias)
        )
    ''')
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS reputacion (
            usuario_alias TEXT PRIMARY KEY,
            semillas INTEGER DEFAULT 0,
            votos_positivos INTEGER DEFAULT 0,
            votos_negativos INTEGER DEFAULT 0
        )
    ''')

    # Historial de Votos (Para evitar spam y rate limiting)
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS votos_historial (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            votante TEXT,
            votado TEXT,
            tipo TEXT, -- 'CONFIANZA'
            fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')
    # Unique constraint separate to allow multiple votes over time (we will check date in code)
    # or keep UNIQUE(votante, votado, date(fecha))? 
    # Let's drop the UNIQUE constraint from the CREATE stmt if it causes issues with daily voting, 
    # but since I can't easily alter constraints in SQLite, I'll handle duplicate checks in code 
    # or just assume the previous schema is fine if it was strictly unique forever.
    # The previous schema had `UNIQUE(votante, votado, tipo)`. This limits to 1 vote PER LIFETIME per pair.
    # We want 1 vote PER DAY. 
    # Since I can't easily DROP the constraint in SQLite without recreating the table,
    # I will create a NEW table `votos_confianza_log` for this specific feature to avoid conflicts with legacy/previous attempts.
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS votos_confianza_log (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            votante TEXT,
            votado TEXT,
            fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')

    # Tabla de Nodos Conocidos (Red de Bosque)
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS nodos_red (
            ip TEXT PRIMARY KEY,
            nombre TEXT,
            ultima_conexion TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            estado TEXT DEFAULT 'Activo'
        )
    ''')

    # Tabla de Peers P2P (Gossip Discovery)
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS peers (
            url TEXT PRIMARY KEY,
            alias TEXT,
            version TEXT,
            last_seen TEXT,
            failures INTEGER DEFAULT 0,
            latency_ms REAL DEFAULT 0
        )
    ''')

    # Tabla de Grupos (Círculos)
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS grupos (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            nombre TEXT UNIQUE,
            descripcion TEXT,
            tipo TEXT DEFAULT 'Publico', -- Publico, Privado
            creador_alias TEXT
        )
    ''')

    # Tabla de Miembros de Grupo
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS miembros_grupo (
            grupo_id INTEGER,
            usuario_alias TEXT,
            rol TEXT DEFAULT 'Miembro',
            PRIMARY KEY (grupo_id, usuario_alias)
        )
    ''')
    
    # Tabla de Vetados (Desterrados)
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS vetados_grupo (
            grupo_id INTEGER,
            usuario_alias TEXT,
            fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (grupo_id, usuario_alias)
        )
    ''')
    
    # Tabla de Invitaciones (Sistema de Brotes)
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS invitaciones (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            codigo TEXT UNIQUE,
            creador_alias TEXT,
            usado_por_alias TEXT,
            estado TEXT DEFAULT 'Pendiente', -- Pendiente, Usada
            fecha_creacion TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')

    # Insertar reputación inicial para el fundador
    cursor.execute("INSERT OR IGNORE INTO reputacion (usuario_alias, semillas) VALUES (?, ?)", 
                  ("Numa_Fundador", 100))
    
    # Insertar usuario Tesoro (Caja Comunitaria)
    cursor.execute("INSERT OR IGNORE INTO usuarios (id, alias, frase_inicial, saldo) VALUES (?, ?, ?, ?)", 
                  ("tesoro_id", "Numa_Tesoro", "El ahorro de la comunidad para el futuro.", 500.0))
    
    # Insertar Nodo Madre (Bootstrap) para que no esté vacío
    cursor.execute("INSERT OR IGNORE INTO nodos_red (ip, nombre, estado) VALUES (?, ?, ?)", 
                  ("192.168.1.1", "Nodo Madre (Raíz)", "Activo"))
    
    # Insertar Primera Invitación (Origen) para que Numa pueda invitar
    cursor.execute("INSERT OR IGNORE INTO invitaciones (codigo, creador_alias, estado) VALUES (?, ?, ?)", 
                  ("NUMA-ORIGEN", "Numa_Fundador", "Pendiente"))
    
    # Crear Grupo Global por defecto
    cursor.execute("INSERT OR IGNORE INTO grupos (id, nombre, descripcion, tipo) VALUES (1, 'Bosque Global', 'El gran círculo de todos los seres.', 'Publico')")
    
    # Tabla de Blockchain
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS blockchain (
            block_index INTEGER PRIMARY KEY,
            timestamp TEXT,
            transactions TEXT, -- JSON array
            previous_hash TEXT,
            hash TEXT
        )
    ''')

    conn.commit()
    conn.close()

def get_ledger_hash():
    """Calcula una huella digital única (Hash) de todo el historial de transacciones"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    # Obtenemos todas las transacciones ordenadas para asegurar determinismo
    cursor.execute("SELECT id, usuario_id, cantidad, fecha FROM transacciones ORDER BY id ASC")
    txs = cursor.fetchall()
    conn.close()
    
    if not txs:
        return "genesis_hash"
        
    # Concatenamos datos clave de todas las tx
    ledger_str = "".join([f"{t[0]}-{t[1]}-{t[2]}-{t[3]}" for t in txs])
    import hashlib
    return hashlib.sha256(ledger_str.encode()).hexdigest()

def get_transaction_count():
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    cursor.execute("SELECT COUNT(*) FROM transacciones")
    count = cursor.fetchone()[0]
    conn.close()
    return count

def get_db_connection():
    conn = sqlite3.connect(DB_PATH, timeout=30.0, check_same_thread=False)
    conn.row_factory = sqlite3.Row
    return conn

if __name__ == "__main__":
    init_db()
    print("Base de datos Tairuma inicializada correctamente.")
