from flask import Blueprint, render_template, request, session, redirect, url_for, flash, jsonify
from backend.db_core import get_connection
from backend.security import requiere_login, requiere_ejecutivo
import os
import time
from werkzeug.utils import secure_filename

conflictos_bp = Blueprint('conflictos', __name__, url_prefix='/conflictos')

@conflictos_bp.route('/')
@requiere_login
def index():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    user_id = session.get('user_id')
    user_rol = session.get('user_rol')

    if user_rol >= 3:
        cursor.execute("""
            SELECT c.*, e.nombre_fantasia as empresa_nombre, u.alias as responsable_nombre
            FROM utrau_conflictos c
            JOIN utrau_empresas e ON c.id_empresa = e.id_empresa
            JOIN utrau_usuarios u ON c.id_responsable = u.id_usuario
            ORDER BY c.estado ASC, c.fecha_creacion DESC
        """)
    else:
        cursor.execute("""
            SELECT c.*, e.nombre_fantasia as empresa_nombre, u.alias as responsable_nombre
            FROM utrau_conflictos c
            JOIN utrau_empresas e ON c.id_empresa = e.id_empresa
            JOIN utrau_usuarios u ON c.id_responsable = u.id_usuario
            LEFT JOIN utrau_conflictos_participantes cp ON c.id_conflicto = cp.id_conflicto
            WHERE c.id_responsable = %s OR cp.id_usuario = %s
            GROUP BY c.id_conflicto
            ORDER BY c.estado ASC, c.fecha_creacion DESC
        """, (user_id, user_id))
    
    lista_conflictos = cursor.fetchall()

    empresas = []
    responsables = []
    grupos = []
    
    if user_rol >= 3:
        cursor.execute("SELECT id_empresa, nombre_fantasia FROM utrau_empresas WHERE estado = 'Activa' ORDER BY nombre_fantasia")
        empresas = cursor.fetchall()
        
        cursor.execute("SELECT id_usuario, alias FROM utrau_usuarios WHERE estado = 'ACTIVO' AND rol >= 2 ORDER BY alias")
        responsables = cursor.fetchall()

        cursor.execute("SELECT id_grupo, nombre_grupo FROM utrau_grupos ORDER BY nombre_grupo")
        grupos = cursor.fetchall()

    cursor.close()
    db.close()

    return render_template('conflictos_lista.html',
                           conflictos=lista_conflictos,
                           empresas=empresas,
                           responsables=responsables,
                           grupos=grupos,
                           user_nom=session.get('user_alias'),
                           user_rol=user_rol)

@conflictos_bp.route('/crear', methods=['POST'])
@requiere_ejecutivo
def crear():
    titulo = request.form.get('titulo').strip()
    id_empresa = request.form.get('id_empresa')
    ambito = request.form.get('ambito')
    id_responsable = request.form.get('id_responsable')
    grupos_ids = request.form.getlist('grupos_ids')

    if not titulo or not id_empresa or not id_responsable:
        flash('Faltan datos obligatorios para abrir el expediente.', 'error')
        return redirect(url_for('conflictos.index'))

    db = get_connection()
    cursor = db.cursor(dictionary=True)

    try:
        # 1. Crear expediente
        cursor.execute("""
            INSERT INTO utrau_conflictos (titulo, id_empresa, ambito, estado, esperando_a, id_responsable)
            VALUES (%s, %s, %s, 'Activo', 'UTRAU', %s)
        """, (titulo, id_empresa, ambito, id_responsable))
        nuevo_id = cursor.lastrowid

        # 2. Lógica de Snapshot de Participantes (Extraer de los grupos seleccionados)
        usuarios_a_insertar = set()
        usuarios_a_insertar.add(str(id_responsable)) # El responsable siempre participa

        if grupos_ids:
            format_strings = ','.join(['%s'] * len(grupos_ids))
            cursor.execute(f"SELECT id_usuario FROM utrau_usuarios_grupos WHERE id_grupo IN ({format_strings})", tuple(grupos_ids))
            for row in cursor.fetchall():
                usuarios_a_insertar.add(str(row['id_usuario']))

        # 3. Guardar la foto de participantes sin duplicados
        for u_id in usuarios_a_insertar:
            cursor.execute("INSERT INTO utrau_conflictos_participantes (id_conflicto, id_usuario) VALUES (%s, %s)", (nuevo_id, u_id))

        # 4. Bitácora automática
        texto_inicio = f"Apertura de Expediente. Ámbito: {ambito}. Estado de Respuesta: UTRAU."
        cursor.execute("""
            INSERT INTO utrau_conflictos_bitacora (id_conflicto, id_usuario, descripcion)
            VALUES (%s, %s, %s)
        """, (nuevo_id, session.get('user_id'), texto_inicio))

        db.commit()
        flash('Expediente registrado correctamente.', 'success')
    except Exception as e:
        db.rollback()
        flash(f'Error al registrar el expediente: {str(e)}', 'error')
    finally:
        cursor.close()
        db.close()

    return redirect(url_for('conflictos.index'))

@conflictos_bp.route('/<int:id_conflicto>')
@requiere_login
def detalle(id_conflicto):
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    user_id = session.get('user_id')
    user_rol = session.get('user_rol')

    cursor.execute("SELECT id_responsable FROM utrau_conflictos WHERE id_conflicto = %s", (id_conflicto,))
    conf_base = cursor.fetchone()

    if not conf_base:
        cursor.close()
        db.close()
        flash('El expediente no existe.', 'error')
        return redirect(url_for('conflictos.index'))

    cursor.execute("SELECT id_usuario FROM utrau_conflictos_participantes WHERE id_conflicto = %s AND id_usuario = %s", (id_conflicto, user_id))
    es_participante = cursor.fetchone()

    if user_rol < 3 and not es_participante and conf_base['id_responsable'] != user_id:
        cursor.close()
        db.close()
        flash('Acceso denegado. Registro confidencial.', 'error')
        return redirect(url_for('conflictos.index'))

    cursor.execute("""
        SELECT c.*, e.nombre_fantasia as empresa_nombre, e.rut as empresa_rut, u.alias as responsable_nombre
        FROM utrau_conflictos c
        JOIN utrau_empresas e ON c.id_empresa = e.id_empresa
        JOIN utrau_usuarios u ON c.id_responsable = u.id_usuario
        WHERE c.id_conflicto = %s
    """, (id_conflicto,))
    conflicto = cursor.fetchone()

    cursor.execute("""
        SELECT b.*, u.alias as autor, u.path_foto as autor_foto
        FROM utrau_conflictos_bitacora b
        JOIN utrau_usuarios u ON b.id_usuario = u.id_usuario
        WHERE b.id_conflicto = %s
        ORDER BY b.timestamp DESC
    """, (id_conflicto,))
    bitacora = cursor.fetchall()

    cursor.execute("""
        SELECT d.*, u.alias as subido_por
        FROM utrau_conflictos_docs d
        JOIN utrau_usuarios u ON d.id_usuario = u.id_usuario
        WHERE d.id_conflicto = %s
        ORDER BY d.fecha_carga DESC
    """, (id_conflicto,))
    documentos = cursor.fetchall()

    # Traer participantes con sus grupos (Nombre (Grupo A, Grupo B))
    cursor.execute("""
        SELECT p.id_usuario, u.alias, u.path_foto,
               GROUP_CONCAT(g.nombre_grupo SEPARATOR ', ') as grupos
        FROM utrau_conflictos_participantes p
        JOIN utrau_usuarios u ON p.id_usuario = u.id_usuario
        LEFT JOIN utrau_usuarios_grupos ug ON u.id_usuario = ug.id_usuario
        LEFT JOIN utrau_grupos g ON ug.id_grupo = g.id_grupo
        WHERE p.id_conflicto = %s
        GROUP BY p.id_usuario
        ORDER BY u.alias
    """, (id_conflicto,))
    participantes_actuales = cursor.fetchall()

    cursor.execute("""
        SELECT id_usuario, alias
        FROM utrau_usuarios
        WHERE estado = 'ACTIVO' AND id_usuario NOT IN (
            SELECT id_usuario FROM utrau_conflictos_participantes WHERE id_conflicto = %s
        ) ORDER BY alias
    """, (id_conflicto,))
    usuarios_disponibles = cursor.fetchall()

    cursor.execute("SELECT id_usuario, alias FROM utrau_usuarios WHERE estado = 'ACTIVO' AND rol >= 2 ORDER BY alias")
    responsables = cursor.fetchall()

    cursor.execute("SELECT id_grupo, nombre_grupo FROM utrau_grupos ORDER BY nombre_grupo")
    grupos = cursor.fetchall()

    cursor.close()
    db.close()

    return render_template('conflictos_detalle.html',
                           conflicto=conflicto,
                           bitacora=bitacora,
                           documentos=documentos,
                           participantes=participantes_actuales,
                           usuarios_disponibles=usuarios_disponibles,
                           responsables=responsables,
                           grupos=grupos,
                           user_nom=session.get('user_alias'),
                           user_rol=user_rol,
                           user_id=user_id)

@conflictos_bp.route('/<int:id_conflicto>/bitacora', methods=['POST'])
@requiere_login
def agregar_bitacora(id_conflicto):
    descripcion = request.form.get('descripcion').strip()
    if not descripcion:
        return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))

    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, session.get('user_id'), descripcion))
        db.commit()
    except Exception as e:
        db.rollback()
        flash(f'Error al registrar comentario: {str(e)}', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))

@conflictos_bp.route('/<int:id_conflicto>/documento', methods=['POST'])
@requiere_login
def subir_documento(id_conflicto):
    if 'archivo' not in request.files:
        flash('No se adjuntó archivo.', 'error')
        return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))
    archivo = request.files['archivo']
    tipo_doc = request.form.get('tipo_documento', 'Otro')
    
    if archivo.filename == '':
        flash('Archivo vacío.', 'error')
        return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))
        
    desc_corta = request.form.get('descripcion_corta', '').strip()
    base_folder = os.path.join('static', 'uploads', 'conflictos')
    upload_folder = os.path.join(base_folder, str(id_conflicto))
    os.makedirs(upload_folder, exist_ok=True)
    
    filename = secure_filename(archivo.filename)
    nombre_final = f"{int(time.time())}_{filename}"
    ruta_guardado = os.path.join(upload_folder, nombre_final)
    ruta_bd = f"/static/uploads/conflictos/{id_conflicto}/{nombre_final}"
    
    db = get_connection()
    cursor = db.cursor()
    try:
        archivo.save(ruta_guardado)
        cursor.execute("INSERT INTO utrau_conflictos_docs (id_conflicto, id_usuario, tipo_documento, descripcion_corta, ruta_archivo) VALUES (%s, %s, %s, %s, %s)", (id_conflicto, session.get('user_id'), tipo_doc, desc_corta, ruta_bd))
        texto_bitacora = f"📄 Archivo anexado [{tipo_doc}]: {desc_corta}"
        cursor.execute("INSERT INTO utrau_conflictos_bitacora (id_conflicto, id_usuario, descripcion) VALUES (%s, %s, %s)", (id_conflicto, session.get('user_id'), texto_bitacora))
        db.commit()
        flash('Documento registrado.', 'success')
    except Exception as e:
        db.rollback()
        flash(f'Error al registrar documento: {str(e)}', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))

@conflictos_bp.route('/<int:id_conflicto>/estado', methods=['POST'])
@requiere_ejecutivo
def cambiar_estado(id_conflicto):
    nuevo_estado = request.form.get('estado')
    db = get_connection()
    cursor = db.cursor()
    try:
        cursor.execute("UPDATE utrau_conflictos SET estado = %s WHERE id_conflicto = %s", (nuevo_estado, id_conflicto))
        texto_bitacora = f"📌 El estado del expediente cambió a: {nuevo_estado.upper()}"
        cursor.execute("INSERT INTO utrau_conflictos_bitacora (id_conflicto, id_usuario, descripcion) VALUES (%s, %s, %s)", (id_conflicto, session.get('user_id'), texto_bitacora))
        db.commit()
        flash('Estado actualizado.', 'success')
    except Exception:
        db.rollback()
        flash('Error al actualizar el estado.', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))

@conflictos_bp.route('/<int:id_conflicto>/esperando', methods=['POST'])
@requiere_ejecutivo
def cambiar_esperando(id_conflicto):
    esperando_a = request.form.get('esperando_a')
    db = get_connection()
    cursor = db.cursor()
    try:
        cursor.execute("UPDATE utrau_conflictos SET esperando_a = %s WHERE id_conflicto = %s", (esperando_a, id_conflicto))
        texto_bitacora = f"⏳ Turno de respuesta asignado a: {esperando_a}"
        cursor.execute("INSERT INTO utrau_conflictos_bitacora (id_conflicto, id_usuario, descripcion) VALUES (%s, %s, %s)", (id_conflicto, session.get('user_id'), texto_bitacora))
        db.commit()
        flash('Responsabilidad de respuesta actualizada.', 'success')
    except Exception:
        db.rollback()
        flash('Error al actualizar.', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))

@conflictos_bp.route('/<int:id_conflicto>/transferir', methods=['POST'])
@requiere_ejecutivo
def transferir_responsabilidad(id_conflicto):
    nuevo_resp = request.form.get('nuevo_responsable')
    motivo = request.form.get('motivo_transferencia').strip()

    if not nuevo_resp or not motivo:
        flash('Debe indicar un responsable y el motivo.', 'error')
        return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))

    db = get_connection()
    cursor = db.cursor(dictionary=True)
    try:
        cursor.execute("SELECT alias FROM utrau_usuarios WHERE id_usuario = %s", (nuevo_resp,))
        alias_nuevo = cursor.fetchone()['alias']

        cursor.execute("UPDATE utrau_conflictos SET id_responsable = %s WHERE id_conflicto = %s", (nuevo_resp, id_conflicto))
        cursor.execute("INSERT IGNORE INTO utrau_conflictos_participantes (id_conflicto, id_usuario) VALUES (%s, %s)", (id_conflicto, nuevo_resp))
        
        texto_bitacora = f"🔄 Responsabilidad transferida a @{alias_nuevo}. Motivo: {motivo}"
        cursor.execute("INSERT INTO utrau_conflictos_bitacora (id_conflicto, id_usuario, descripcion) VALUES (%s, %s, %s)", (id_conflicto, session.get('user_id'), texto_bitacora))
        
        db.commit()
        flash('Responsabilidad transferida formalmente.', 'success')
    except Exception as e:
        db.rollback()
        flash('Error al transferir responsabilidad.', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))

@conflictos_bp.route('/<int:id_conflicto>/participantes/agregar', methods=['POST'])
@requiere_ejecutivo
def agregar_participante(id_conflicto):
    id_usuario = request.form.get('id_usuario')
    grupos_ids = request.form.getlist('grupos_ids')

    db = get_connection()
    cursor = db.cursor()
    try:
        usuarios_a_insertar = set()
        
        # Si eligió alguien individual
        if id_usuario:
            usuarios_a_insertar.add(str(id_usuario))

        # Si eligió grupos completos
        if grupos_ids:
            format_strings = ','.join(['%s'] * len(grupos_ids))
            cursor.execute(f"SELECT id_usuario FROM utrau_usuarios_grupos WHERE id_grupo IN ({format_strings})", tuple(grupos_ids))
            for row in cursor.fetchall():
                usuarios_a_insertar.add(str(row[0])) # row[0] trae el ID porque db.cursor() retorna tuplas por defecto acá
        
        # Insertar a todos los que encontró, ignorando duplicados
        for u_id in usuarios_a_insertar:
            cursor.execute("INSERT IGNORE INTO utrau_conflictos_participantes (id_conflicto, id_usuario) VALUES (%s, %s)", (id_conflicto, u_id))
        
        db.commit()
        flash('Compañeros agregados al expediente con éxito.', 'success')
    except Exception as e:
        db.rollback()
        flash('Error al registrar participantes.', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('conflictos.detalle', id_conflicto=id_conflicto))

@conflictos_bp.route('/<int:id_conflicto>/imprimir')
@requiere_login
def imprimir_pdf(id_conflicto):
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    user_id = session.get('user_id')
    user_rol = session.get('user_rol')

    cursor.execute("SELECT id_responsable FROM utrau_conflictos WHERE id_conflicto = %s", (id_conflicto,))
    conf_base = cursor.fetchone()
    if not conf_base:
        return "Expediente no encontrado", 404

    cursor.execute("""
        SELECT c.*, e.nombre_fantasia as empresa_nombre, e.rut as empresa_rut, u.alias as responsable_nombre
        FROM utrau_conflictos c
        JOIN utrau_empresas e ON c.id_empresa = e.id_empresa
        JOIN utrau_usuarios u ON c.id_responsable = u.id_usuario
        WHERE c.id_conflicto = %s
    """, (id_conflicto,))
    conflicto = cursor.fetchone()

    cursor.execute("""
        SELECT b.*, u.alias as autor
        FROM utrau_conflictos_bitacora b
        JOIN utrau_usuarios u ON b.id_usuario = u.id_usuario
        WHERE b.id_conflicto = %s
        ORDER BY b.timestamp DESC
    """, (id_conflicto,))
    bitacora = cursor.fetchall()

    cursor.execute("""
        SELECT u.alias, GROUP_CONCAT(g.nombre_grupo SEPARATOR ', ') as grupos
        FROM utrau_conflictos_participantes p
        JOIN utrau_usuarios u ON p.id_usuario = u.id_usuario
        LEFT JOIN utrau_usuarios_grupos ug ON u.id_usuario = ug.id_usuario
        LEFT JOIN utrau_grupos g ON ug.id_grupo = g.id_grupo
        WHERE p.id_conflicto = %s
        GROUP BY p.id_usuario
        ORDER BY u.alias
    """, (id_conflicto,))
    participantes = cursor.fetchall()

    cursor.close()
    db.close()

    return render_template('conflicto_imprimir.html',
                           conflicto=conflicto,
                           bitacora=bitacora,
                           participantes=participantes)