from flask import Blueprint, render_template, redirect, url_for, request, session, flash, jsonify
from backend.db_core import get_connection
from backend.security import requiere_ejecutivo
import os
from datetime import datetime
from backend.utils import guardar_archivo, procesar_firma_transparente

config_bp = Blueprint('config', __name__, url_prefix='/configuracion')

@config_bp.route('/')
@requiere_ejecutivo
def panel():
    return render_template('config_panel.html', user_nom=session.get('user_alias'))

@config_bp.route('/terminales')
@requiere_ejecutivo
def terminales():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    cursor.execute("""
        SELECT t.*, u.alias, u.nombre_completo, u.path_foto
        FROM utrau_terminales_activas t
        LEFT JOIN utrau_usuarios u ON t.id_usuario_actual = u.id_usuario
        ORDER BY FIELD (t.estado, 'PENDIENTE', 'CONECTADO', 'DESCONECTADO'), t.ultima_conexion DESC
    """)
    lista_terminales = cursor.fetchall()
    cursor.close()
    db.close()
    return render_template('config_terminales.html', terminales=lista_terminales, user_nom=session.get('user_alias'))

@config_bp.route('/terminales/accion/<uuid>/<accion>')
@requiere_ejecutivo
def accion_terminal (uuid, accion):
    db = get_connection()
    cursor = db.cursor()
    try:
        if accion == 'eliminar':
            cursor.execute("DELETE FROM utrau_terminales_activas WHERE uuid_terminal = %s", (uuid,))
            flash('Terminal eliminada correctamente del sistema.', 'success')
        else:
            estado = 'CONECTADO' if accion == 'autorizar' else 'DESCONECTADO'
            cursor.execute("UPDATE utrau_terminales_activas SET estado = %s, version = version + 1 WHERE uuid_terminal = %s", (estado, uuid))
            flash('Terminal autorizada con éxito.' if accion == 'autorizar' else 'Terminal bloqueada.', 'success' if accion == 'autorizar' else 'warning')
        db.commit()
    except Exception as e:
        db.rollback()
        flash('Error de base de datos.', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('config.terminales'))

@config_bp.route('/cargos')
@requiere_ejecutivo
def cargos():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    cursor.execute("SELECT * FROM utrau_cargos ORDER BY orden ASC")
    lista_cargos = cursor.fetchall()
    cursor.close()
    db.close()
    return render_template('config_cargos.html', user_nom=session.get('user_alias'), lista_cargos=lista_cargos)

@config_bp.route('/cargos/guardar', methods=['POST'])
@requiere_ejecutivo
def guardar_cargo():
    id_cargo = request.form.get('id_cargo')
    nombre_cargo = request.form.get('nombre_cargo').strip()
    es_ejecutivo = 1 if request.form.get('es_ejecutivo') == 'on' else 0
    orden = request.form.get('orden', 0)
    version_actual = request.form.get('version', 1)

    db = get_connection()
    cursor = db.cursor()
    try:
        if id_cargo:
            cursor.execute("UPDATE utrau_cargos SET nombre_cargo = %s, es_ejecutivo = %s, orden = %s, version = version + 1 WHERE id_cargo = %s AND version = %s",
                           (nombre_cargo, es_ejecutivo, orden, id_cargo, version_actual))
            if cursor.rowcount == 0:
                flash('Conflicto detectado: Cargo modificado por otro usuario.', 'error')
            else:
                flash (f'Cargo "{nombre_cargo}" actualizado.', 'success')
        else:
            cursor.execute("INSERT INTO utrau_cargos (nombre_cargo, es_ejecutivo, orden) VALUES (%s, %s, %s)", (nombre_cargo, es_ejecutivo, orden))
            flash (f'Nuevo cargo "{nombre_cargo}" registrado.', 'success')
        db.commit()
    except Exception as e:
        db.rollback()
        flash('Error en la base de datos.', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('config.cargos'))

@config_bp.route('/usuarios')
@requiere_ejecutivo
def usuarios():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    cursor.execute("""
        SELECT u.*, s.nombre as nombre_sector, e.nombre_fantasia as nombre_empresa
        FROM utrau_usuarios u
        LEFT JOIN utrau_sectores s ON u.id_sector = s.id_sector
        LEFT JOIN utrau_empresas e ON u.id_empresa = e.id_empresa
        WHERE u.rol != 4 ORDER BY u.nombre_completo ASC
    """)
    lista_usuarios = cursor.fetchall()
    
    cursor.execute("SELECT * FROM utrau_sectores ORDER BY nombre ASC")
    lista_sectores = cursor.fetchall()
    
    cursor.execute("SELECT id_empresa, nombre_fantasia FROM utrau_empresas ORDER BY nombre_fantasia ASC")
    lista_empresas = cursor.fetchall()
    
    cursor.close()
    db.close()
    return render_template('config_usuarios.html',
                           user_nom=session.get('user_alias'),
                           lista_usuarios=lista_usuarios,
                           lista_sectores=lista_sectores,
                           lista_empresas=lista_empresas)

@config_bp.route('/usuarios/guardar', methods=['POST'])
@requiere_ejecutivo
def guardar_usuario():
    id_usuario = request.form.get('id_usuario')
    alias = request.form.get('alias').strip()
    nombre_completo = request.form.get('nombre_completo').strip()
    pin_firma = request.form.get('pin_firma').strip()
    estado = request.form.get('estado', 'ACTIVO')
    version_actual = request.form.get('version', 1)

    tipo_documento = request.form.get('tipo_documento', 'CI')
    cedula_identidad = request.form.get('cedula_identidad', '').strip()
    fecha_nacimiento = request.form.get('fecha_nacimiento') or None
    whatsapp = request.form.get('whatsapp', '').strip()
    celular = request.form.get('celular', '').strip()
    email = request.form.get('email', '').strip()
    fecha_ingreso = request.form.get('fecha_ingreso') or None
    id_sector = request.form.get('id_sector') or None
    id_empresa = request.form.get('id_empresa') or None
    tipo_contrato = request.form.get('tipo_contrato', 'MENSUAL')

    db = get_connection()
    cursor = db.cursor()
    try:
        cursor.execute("SELECT id_usuario FROM utrau_usuarios WHERE alias = %s AND id_usuario != %s", (alias, id_usuario if id_usuario else 0))
        if cursor.fetchone():
            flash(f'El alias "@{alias}" ya está en uso.', 'error')
            return redirect(url_for('config.usuarios'))

        archivos_paths = {}
        for campo_file in ['foto', 'cedula_frente', 'cedula_atras', 'firma']:
            if campo_file in request.files:
                archivo = request.files[campo_file]
                if archivo.filename != '':
                    ruta = guardar_archivo(archivo, campo_file.upper(), alias)
                    if campo_file == 'firma' and ruta:
                        ruta_transparente = procesar_firma_transparente(ruta)
                        archivos_paths['path_firma'] = ruta_transparente or ruta
                    else:
                        archivos_paths[f'path_{campo_file}'] = ruta

        if id_usuario:
            update_sql = """UPDATE utrau_usuarios SET
                alias=%s, nombre_completo=%s, estado=%s,
                tipo_documento=%s, cedula_identidad=%s, fecha_nacimiento=%s,
                whatsapp=%s, celular=%s, email=%s, fecha_ingreso=%s,
                id_sector=%s, id_empresa=%s, tipo_contrato=%s, version=version+1
            """
            params = [alias, nombre_completo, estado, tipo_documento, cedula_identidad, fecha_nacimiento, whatsapp, celular, email, fecha_ingreso, id_sector, id_empresa, tipo_contrato]

            if pin_firma:
                update_sql += ", pin_firma=%s"
                params.append(pin_firma)

            for col, rut in archivos_paths.items():
                update_sql += f", {col}=%s"
                params.append(rut)

            update_sql += " WHERE id_usuario=%s AND version=%s"
            params.extend([id_usuario, version_actual])

            cursor.execute(update_sql, tuple(params))
            
            if cursor.rowcount == 0:
                flash('Conflicto: El legajo fue modificado desde otra terminal.', 'error')
            else:
                flash(f'Legajo de {nombre_completo} actualizado con éxito.', 'success')
                cursor.execute("INSERT INTO utrau_auditoria_historica (tabla_afectada, id_registro, accion, id_usuario) VALUES (%s, %s, %s, %s)",
                               ('utrau_usuarios', id_usuario, 'UPDATE', session.get('user_id')))
        else:
            rol_base = 1
            cols = ['alias', 'nombre_completo', 'pin_firma', 'rol', 'estado', 'tipo_documento', 'cedula_identidad', 'fecha_nacimiento',
                    'whatsapp', 'celular', 'email', 'fecha_ingreso', 'id_sector', 'id_empresa', 'tipo_contrato']
            vals = [alias, nombre_completo, pin_firma, rol_base, estado, tipo_documento, cedula_identidad, fecha_nacimiento, whatsapp, celular,
                    email, fecha_ingreso, id_sector, id_empresa, tipo_contrato]

            for col, rut in archivos_paths.items():
                cols.append(col)
                vals.append(rut)

            placeholders = ', '.join(['%s'] * len(cols))
            sql = f"INSERT INTO utrau_usuarios ({', '.join(cols)}) VALUES ({placeholders})"
            cursor.execute(sql, tuple(vals))
            nuevo_id = cursor.lastrowid
            
            flash(f'Compañero {nombre_completo} registrado en el padrón.', 'success')
            cursor.execute("INSERT INTO utrau_auditoria_historica (tabla_afectada, id_registro, accion, id_usuario) VALUES (%s, %s, %s, %s)",
                           ('utrau_usuarios', nuevo_id, 'INSERT', session.get('user_id')))
        db.commit()
    except Exception as e:
        db.rollback()
        flash(f'Error en la base de datos: {str(e)}', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('config.usuarios'))

@config_bp.route('/sectores/ajax_add', methods=['POST'])
@requiere_ejecutivo
def ajax_add_sector():
    codigo = request.form.get('codigo').strip()
    nombre = request.form.get('nombre').strip()
    db = get_connection()
    cursor = db.cursor()
    try:
        cursor.execute("INSERT INTO utrau_sectores (codigo, nombre) VALUES (%s, %s)", (codigo, nombre))
        db.commit()
        return jsonify({'success': True, 'id_sector': cursor.lastrowid, 'codigo': codigo, 'nombre': nombre})
    except Exception as e:
        db.rollback()
        return jsonify({'success': False, 'error': str(e)})
    finally:
        cursor.close()
        db.close()

@config_bp.route('/empresas/ajax_add', methods=['POST'])
@requiere_ejecutivo
def ajax_add_empresa():
    nombre = request.form.get('nombre').strip()
    db = get_connection()
    cursor = db.cursor()
    try:
        cursor.execute("INSERT INTO utrau_empresas (nombre_fantasia, nombre_fiscal) VALUES (%s, %s)", (nombre, nombre))
        db.commit()
        return jsonify({'success': True, 'id_empresa': cursor.lastrowid, 'nombre': nombre})
    except Exception as e:
        db.rollback()
        return jsonify({'success': False, 'error': str(e)})
    finally:
        cursor.close()
        db.close()

# ==============================================================
# MÓDULO: CRM DE EMPRESAS Y ORGANISMOS
# ==============================================================
@config_bp.route('/empresas')
@requiere_ejecutivo
def empresas():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    
    cursor.execute("SELECT * FROM utrau_empresas ORDER BY nombre_fantasia ASC")
    lista_empresas = cursor.fetchall()
    
    cursor.execute("SELECT * FROM utrau_contactos ORDER BY nombre ASC")
    contactos = cursor.fetchall()
    
    for emp in lista_empresas:
        emp['contactos'] = [c for c in contactos if c['id_empresa'] == emp['id_empresa']]
        
    cursor.close()
    db.close()
    return render_template('config_empresas.html', user_nom=session.get('user_alias'), lista_empresas=lista_empresas)

@config_bp.route('/empresas/guardar', methods=['POST'])
@requiere_ejecutivo
def guardar_empresa_crm():
    id_empresa = request.form.get('id_empresa')
    nombre_fantasia = request.form.get('nombre_fantasia', '').strip()
    nombre_fiscal = request.form.get('nombre_fiscal', '').strip()
    rut = request.form.get('rut', '').strip()
    direccion = request.form.get('direccion', '').strip()
    localidad = request.form.get('localidad', '').strip()
    departamento = request.form.get('departamento', '').strip()
    mail_oficial = request.form.get('mail_oficial', '').strip()
    cant_trabajadores = request.form.get('cant_trabajadores')
    tipo = request.form.get('tipo', 'Empresa')
    estado = request.form.get('estado', 'Activa')

    if not cant_trabajadores or cant_trabajadores == '':
        cant_trabajadores = 0

    db = get_connection()
    cursor = db.cursor()
    try:
        if id_empresa:
            cursor.execute("""
                UPDATE utrau_empresas SET 
                nombre_fantasia=%s, nombre_fiscal=%s, rut=%s, direccion=%s, 
                localidad=%s, departamento=%s, mail_oficial=%s, cant_trabajadores=%s, 
                tipo=%s, estado=%s 
                WHERE id_empresa=%s
            """, (nombre_fantasia, nombre_fiscal, rut, direccion, localidad, departamento, mail_oficial, cant_trabajadores, tipo, estado, id_empresa))
            flash('Registro institucional actualizado.', 'success')
        else:
            cursor.execute("""
                INSERT INTO utrau_empresas 
                (nombre_fantasia, nombre_fiscal, rut, direccion, localidad, departamento, mail_oficial, cant_trabajadores, tipo, estado) 
                VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            """, (nombre_fantasia, nombre_fiscal, rut, direccion, localidad, departamento, mail_oficial, cant_trabajadores, tipo, estado))
            flash('Nueva entidad registrada correctamente.', 'success')
        db.commit()
    except Exception as e:
        db.rollback()
        flash(f'Error al guardar en base de datos: {e}', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('config.empresas'))

@config_bp.route('/empresas/contacto/guardar', methods=['POST'])
@requiere_ejecutivo
def guardar_contacto():
    id_empresa = request.form.get('id_empresa_contacto')
    nombre = request.form.get('nombre_contacto').strip()
    cargo = request.form.get('cargo_contacto').strip()
    celular = request.form.get('celular_contacto').strip()
    email = request.form.get('email_contacto').strip()
    
    db = get_connection()
    cursor = db.cursor()
    try:
        cursor.execute("""
            INSERT INTO utrau_contactos (id_empresa, nombre, cargo, celular_whatsapp, email) 
            VALUES (%s, %s, %s, %s, %s)
        """, (id_empresa, nombre, cargo, celular, email))
        db.commit()
        flash('Contacto agregado exitosamente al expediente.', 'success')
    except Exception as e:
        db.rollback()
        flash(f'Error al guardar contacto: {e}', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('config.empresas'))

@config_bp.route('/asignaciones')
@requiere_ejecutivo
def asignaciones():
    db = get_connection()
    cursor = db.cursor(dictionary=True)
    cursor.execute("""
        SELECT a.*, u.nombre_completo, u.alias, u.path_foto, c.nombre_cargo, c.es_ejecutivo
        FROM utrau_asignaciones a
        JOIN utrau_usuarios u ON a.id_usuario = u.id_usuario
        JOIN utrau_cargos c ON a.id_cargo = c.id_cargo
        ORDER BY a.fecha_fin IS NOT NULL, c.orden ASC, a.fecha_inicio DESC
    """)
    lista_asignaciones = cursor.fetchall()
    
    cursor.execute("SELECT id_usuario, alias, nombre_completo FROM utrau_usuarios WHERE rol != 4 AND estado = 'ACTIVO' ORDER BY nombre_completo ASC")
    lista_usuarios = cursor.fetchall()
    
    cursor.execute("SELECT id_cargo, nombre_cargo, es_ejecutivo FROM utrau_cargos ORDER BY orden ASC")
    lista_cargos = cursor.fetchall()
    
    cursor.close()
    db.close()
    return render_template('config_asignaciones.html',
                           user_nom=session.get('user_alias'),
                           lista_asignaciones=lista_asignaciones,
                           lista_usuarios=lista_usuarios,
                           lista_cargos=lista_cargos)

@config_bp.route('/asignaciones/guardar', methods=['POST'])
@requiere_ejecutivo
def guardar_asignacion():
    id_asignacion = request.form.get('id_asignacion')
    id_usuario = request.form.get('id_usuario')
    id_cargo = request.form.get('id_cargo')
    fecha_inicio = request.form.get('fecha_inicio')
    fecha_fin = request.form.get('fecha_fin') or None
    version_actual = request.form.get('version', 1)

    db = get_connection()
    cursor = db.cursor()
    try:
        cursor.execute("SELECT es_ejecutivo FROM utrau_cargos WHERE id_cargo = %s", (id_cargo,))
        cargo_info = cursor.fetchone()
        es_ejecutivo = cargo_info[0] if cargo_info else 0
        
        rol_a_asignar = 3 if es_ejecutivo else 2
        if fecha_fin:
            rol_a_asignar = 1

        if id_asignacion:
            cursor.execute("""
                UPDATE utrau_asignaciones
                SET id_usuario=%s, id_cargo=%s, fecha_inicio=%s, fecha_fin=%s, version=version+1
                WHERE id_asignacion=%s AND version=%s
            """, (id_usuario, id_cargo, fecha_inicio, fecha_fin, id_asignacion, version_actual))
            
            if cursor.rowcount == 0:
                flash('Conflicto: La asignación fue modificada por otro usuario.', 'error')
            else:
                flash('Asignación actualizada correctamente.', 'success')
                cursor.execute("INSERT INTO utrau_auditoria_historica (tabla_afectada, id_registro, accion, id_usuario) VALUES (%s, %s, %s, %s)",
                               ('utrau_asignaciones', id_asignacion, 'UPDATE', session.get('user_id')))
        else:
            cursor.execute("""
                INSERT INTO utrau_asignaciones (id_usuario, id_cargo, fecha_inicio, fecha_fin)
                VALUES (%s, %s, %s, %s)
            """, (id_usuario, id_cargo, fecha_inicio, fecha_fin))
            nuevo_id = cursor.lastrowid
            flash('Compañero asignado al cargo con éxito. Permisos de rol actualizados.', 'success')
            cursor.execute("INSERT INTO utrau_auditoria_historica (tabla_afectada, id_registro, accion, id_usuario) VALUES (%s, %s, %s, %s)",
                           ('utrau_asignaciones', nuevo_id, 'INSERT', session.get('user_id')))

        cursor.execute("UPDATE utrau_usuarios SET rol = %s WHERE id_usuario = %s AND rol != 4", (rol_a_asignar, id_usuario))
        db.commit()
    except Exception as e:
        db.rollback()
        flash(f'Error en la base de datos: {str(e)}', 'error')
    finally:
        cursor.close()
        db.close()
    return redirect(url_for('config.asignaciones'))