from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify
from backend.db_core import get_connection
from backend.security import requiere_login, requiere_ejecutivo
from datetime import datetime
import pytz

agenda_bp = Blueprint('agenda', __name__, url_prefix='/agenda')
tz_uy = pytz.timezone('America/Montevideo')

# --- FUNCIONES AUXILIARES ---
def registrar_en_bitacora(id_conflicto, mensaje, id_usuario):
    if not id_conflicto: return
    db = get_connection()
    cursor = db.cursor()
    try:
        cursor.execute("""
            INSERT INTO utrau_conflictos_bitacora (id_conflicto, id_usuario, descripcion) 
            VALUES (%s, %s, %s)
        """, (id_conflicto, id_usuario, f"AGENDA: {mensaje}"))
        db.commit()
    except Exception as e:
        db.rollback()
        print("Error en bitácora:", e)
    finally:
        cursor.close()
        db.close()

def notificar_participantes(id_evento, mensaje_alerta):
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    try:
        cursor.execute("SELECT id_usuario FROM utrau_agenda_participantes WHERE id_evento = %s", (id_evento,))
        participantes = cursor.fetchall()
        for p in participantes:
            cursor.execute("""
                INSERT INTO utrau_notificaciones (id_usuario, mensaje, fecha) 
                VALUES (%s, %s, %s)
            """, (p['id_usuario'], mensaje_alerta, datetime.now(tz_uy)))
        db.commit()
    except Exception as e:
        db.rollback()
        print("Error en notificación:", e)
    finally:
        cursor.close()
        db.close()

# --- RUTAS DE NAVEGACIÓN ---
@agenda_bp.route('/')
@requiere_login
def vista_agenda():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    
    cursor.execute("SELECT id_conflicto, titulo FROM utrau_conflictos WHERE estado != 'Archivado' ORDER BY fecha_creacion DESC")
    conflictos = cursor.fetchall()

    cursor.execute("SELECT id_usuario, alias, nombre_completo, path_foto FROM utrau_usuarios WHERE estado = 'ACTIVO' ORDER BY nombre_completo")
    lista_usuarios = cursor.fetchall()

    cursor.close()
    db.close()
    
    return render_template('agenda.html', 
                           conflictos=conflictos, 
                           lista_usuarios=lista_usuarios,
                           user_rol=session.get('user_rol'),
                           user_nom=session.get('user_alias'),
                           user_id=session.get('user_id'),
                           tema=session.get('tema_visual', 0))

# --- API: OBTENER EVENTOS (FULLCALENDAR) ---
@agenda_bp.route('/api/eventos', methods=['GET'])
@requiere_login
def get_eventos():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    usuario_actual = session.get('user_id')
    rol_actual = session.get('user_rol')
    
    if rol_actual >= 3:
        cursor.execute("SELECT * FROM utrau_agenda")
    else:
        cursor.execute("""
            SELECT DISTINCT a.* FROM utrau_agenda a 
            LEFT JOIN utrau_agenda_participantes p ON a.id_evento = p.id_evento 
            WHERE a.id_creador = %s OR p.id_usuario = %s
        """, (usuario_actual, usuario_actual))
    
    eventos_raw = cursor.fetchall()
    eventos = []
    
    for ev in eventos_raw:
        cursor.execute("SELECT nombre_completo FROM utrau_usuarios WHERE id_usuario = %s", (ev['id_creador'],))
        creador = cursor.fetchone()
        creador_nombre = creador['nombre_completo'] if creador else 'Desconocido'
        
        cursor.execute("SELECT COUNT(*) as cant FROM utrau_agenda_participantes WHERE id_evento = %s", (ev['id_evento'],))
        cant = cursor.fetchone()['cant']

        color_evento = '#ef4444' if ev['id_conflicto'] else '#3b82f6'

        eventos.append({
            'id': ev['id_evento'],
            'title': ev['titulo'],
            'start': ev['fecha_inicio'].isoformat() if ev['fecha_inicio'] else None,
            'end': ev['fecha_fin'].isoformat() if ev['fecha_fin'] else None,
            'allDay': bool(ev['es_jornada_completa']),
            'color': color_evento,
            'extendedProps': {
                'descripcion': ev['descripcion'] or '',
                'estado': ev['estado'],
                'visibilidad': ev['visibilidad'],
                'creador': creador_nombre,
                'creador_id': ev['id_creador'],
                'participantes': cant,
                'id_conflicto': ev['id_conflicto']
            }
        })
    
    cursor.close()
    db.close()
    return jsonify(eventos)

# --- API: GUARDAR O EDITAR EVENTO ---
@agenda_bp.route('/api/eventos', methods=['POST'])
@requiere_login
def save_evento():
    data = request.json
    id_evento = data.get('id_evento')
    titulo = data.get('titulo')
    allDay = 1 if data.get('allDay') else 0
    visibilidad = data.get('visibilidad', 'Solo Participantes')
    descripcion = data.get('descripcion', '')
    participantes = data.get('participantes', [])
    id_conflicto = data.get('id_conflicto')
    
    # FORZAR FORMATO DE HORA PARA MYSQL (Asegurar los segundos :00)
    start_str = data.get('start')
    if start_str and "T" in start_str:
        start_str = start_str.replace("T", " ")
        if len(start_str) == 16: start_str += ":00"
        
    end_str = data.get('end')
    if end_str and "T" in end_str:
        end_str = end_str.replace("T", " ")
        if len(end_str) == 16: end_str += ":00"
    
    if not id_conflicto or id_conflicto == "": 
        id_conflicto = None
        
    usuario_actual = session.get('user_id')
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    
    try:
        if id_evento:
            cursor.execute("SELECT estado FROM utrau_agenda WHERE id_evento = %s", (id_evento,))
            ev_actual = cursor.fetchone()
            
            if ev_actual['estado'] == 'Fijado' and session.get('user_rol') < 3:
                return jsonify({'success': False, 'error': 'El evento está FIJADO. Solo Administración puede modificarlo.'})
                
            cursor.execute("""
                UPDATE utrau_agenda 
                SET titulo=%s, fecha_inicio=%s, fecha_fin=%s, es_jornada_completa=%s, visibilidad=%s, descripcion=%s, id_conflicto=%s 
                WHERE id_evento=%s
            """, (titulo, start_str, end_str, allDay, visibilidad, descripcion, id_conflicto, id_evento))
            
            cursor.execute("DELETE FROM utrau_agenda_participantes WHERE id_evento = %s", (id_evento,))
            participantes.append(str(usuario_actual))
            for p in set(participantes):
                cursor.execute("INSERT IGNORE INTO utrau_agenda_participantes (id_evento, id_usuario) VALUES (%s, %s)", (id_evento, p))
            
            db.commit()
            notificar_participantes(id_evento, f"CAMBIO DE AGENDA: La actividad '{titulo}' fue modificada.")
            
        else:
            cursor.execute("""
                INSERT INTO utrau_agenda (titulo, descripcion, fecha_inicio, fecha_fin, es_jornada_completa, estado, id_creador, id_conflicto, visibilidad)
                VALUES (%s, %s, %s, %s, %s, 'Propuesto', %s, %s, %s)
            """, (titulo, descripcion, start_str, end_str, allDay, usuario_actual, id_conflicto, visibilidad))
            nuevo_id = cursor.lastrowid
            
            participantes.append(str(usuario_actual))
            for p in set(participantes):
                cursor.execute("INSERT IGNORE INTO utrau_agenda_participantes (id_evento, id_usuario) VALUES (%s, %s)", (nuevo_id, p))
            
            db.commit()
            if id_conflicto:
                registrar_en_bitacora(id_conflicto, f"Actividad agendada (Propuesta): {titulo} para el {start_str}", usuario_actual)
        
        return jsonify({'success': True})
        
    except Exception as e:
        db.rollback()
        return jsonify({'success': False, 'error': str(e)})
    finally:
        cursor.close()
        db.close()

# --- API: CAMBIAR ESTADO (FIJAR CANDADO) ---
@agenda_bp.route('/api/eventos/estado', methods=['POST'])
@requiere_ejecutivo
def cambiar_estado():
    data = request.json
    id_evento = data.get('id_evento')
    nuevo_estado = data.get('estado')
    
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    try:
        cursor.execute("SELECT titulo, id_conflicto FROM utrau_agenda WHERE id_evento = %s", (id_evento,))
        ev = cursor.fetchone()
        
        cursor.execute("UPDATE utrau_agenda SET estado = %s WHERE id_evento = %s", (nuevo_estado, id_evento))
        db.commit()
        
        if nuevo_estado == 'Fijado':
            notificar_participantes(id_evento, f"REUNIÓN FIJADA: '{ev['titulo']}'. Asistencia requerida.")
            if ev['id_conflicto']:
                registrar_en_bitacora(ev['id_conflicto'], f"Actividad FIJADA: {ev['titulo']}", session.get('user_id'))
                
        return jsonify({'success': True})
    except Exception as e:
        db.rollback()
        return jsonify({'success': False, 'error': str(e)})
    finally:
        cursor.close()
        db.close()

# --- API: SEMÁFORO DE CHOQUES ---
@agenda_bp.route('/verificar_disponibilidad', methods=['POST'])
@requiere_login
def verificar_disponibilidad():
    data = request.json
    usuarios_ids = data.get('usuarios', [])
    fecha_inicio = data.get('fecha_inicio')
    fecha_fin = data.get('fecha_fin')
    
    if not usuarios_ids or not fecha_inicio or not fecha_fin:
        return jsonify({'ocupados': []})
        
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    format_strings = ','.join(['%s'] * len(usuarios_ids))
    
    query = f"""
        SELECT DISTINCT u.nombre_completo 
        FROM utrau_agenda_participantes p
        JOIN utrau_agenda a ON p.id_evento = a.id_evento
        JOIN utrau_usuarios u ON p.id_usuario = u.id_usuario
        WHERE p.id_usuario IN ({format_strings})
        AND a.estado != 'Cerrado'
        AND (
            (a.fecha_inicio <= %s AND a.fecha_fin > %s) OR 
            (a.fecha_inicio < %s AND a.fecha_fin >= %s) OR
            (a.fecha_inicio >= %s AND a.fecha_fin <= %s)
        )
    """
    params = tuple(usuarios_ids) + (fecha_fin, fecha_inicio, fecha_fin, fecha_inicio, fecha_inicio, fecha_fin)
    cursor.execute(query, params)
    ocupados = cursor.fetchall()
    cursor.close()
    db.close()
    
    nombres = [o['nombre_completo'] for o in ocupados]
    return jsonify({'ocupados': nombres})

# --- API: FORO PRIVADO DE COORDINACIÓN ---
@agenda_bp.route('/foro/<int:id_evento>', methods=['GET', 'POST'])
@requiere_login
def foro_evento(id_evento):
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    usuario_actual = session.get('user_id')
    
    cursor.execute("SELECT COUNT(*) as acceso FROM utrau_agenda_participantes WHERE id_evento = %s AND id_usuario = %s", (id_evento, usuario_actual))
    tiene_acceso = cursor.fetchone()['acceso'] > 0
    
    if not tiene_acceso and session.get('user_rol') < 3:
        cursor.close()
        db.close()
        return jsonify({'error': 'Privado'}), 403
        
    if request.method == 'POST':
        mensaje = request.form.get('mensaje')
        cursor.execute("INSERT INTO utrau_agenda_foro (id_evento, id_usuario, mensaje) VALUES (%s, %s, %s)", (id_evento, usuario_actual, mensaje))
        db.commit()
        cursor.close()
        db.close()
        return jsonify({'status': 'ok'})
    else:
        # ARREGLO DE LA FECHA %d/%m/%Y
        cursor.execute("""
            SELECT f.mensaje, DATE_FORMAT(f.fecha, '%d/%m/%Y %H:%i') as fecha_fmt, u.alias
            FROM utrau_agenda_foro f
            JOIN utrau_usuarios u ON f.id_usuario = u.id_usuario
            WHERE f.id_evento = %s
            ORDER BY f.fecha ASC
        """, (id_evento,))
        mensajes = cursor.fetchall()
        cursor.close()
        db.close()
        return jsonify(mensajes)

# --- API: LECTURA DE NOTIFICACIONES ---
@agenda_bp.route('/notificaciones/pendientes', methods=['GET'])
@requiere_login
def notifs_pendientes():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    cursor.execute("SELECT mensaje FROM utrau_notificaciones WHERE id_usuario = %s AND leida = 0 ORDER BY fecha DESC", (session.get('user_id'),))
    notifs = cursor.fetchall()
    cursor.close()
    db.close()
    return jsonify(notifs)
    
@agenda_bp.route('/notificaciones/leer', methods=['POST'])
@requiere_login
def leer_notifs():
    db = get_connection()
    cursor = db.cursor()
    cursor.execute("UPDATE utrau_notificaciones SET leida = 1 WHERE id_usuario = %s", (session.get('user_id'),))
    db.commit()
    cursor.close()
    db.close()
    return jsonify({'status': 'ok'})

# --- API: BOT DE CONTROL CENTRALIZADO (HEARTBEAT) ---
@agenda_bp.route('/api/verificar_cambios', methods=['GET'])
@requiere_login
def verificar_cambios():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    user_id = session.get('user_id')
    
    # 1. Chequeo de Notificaciones No Leídas (Agenda)
    cursor.execute("SELECT count(*) as total FROM utrau_notificaciones WHERE id_usuario = %s AND leida = 0", (user_id,))
    notifs_agenda = cursor.fetchone()['total']
    
    # 2. Chequeo de Novedades en Conflictos (Bitácora - Últimos 60 segundos)
    cursor.execute("""
        SELECT count(DISTINCT b.id_bitacora) as total 
        FROM utrau_conflictos_bitacora b
        JOIN utrau_conflictos_participantes p ON b.id_conflicto = p.id_conflicto
        WHERE p.id_usuario = %s 
        AND b.timestamp > NOW() - INTERVAL 1 MINUTE
    """, (user_id,))
    notifs_conflictos = cursor.fetchone()['total']
    
    cursor.close()
    db.close()
    
    return jsonify({
        'agenda': notifs_agenda,
        'conflictos': notifs_conflictos
    })