
import json
from configuraciones import variables

# Cargar variables de entorno ANTES de importar cosas que las necesiten
env_path = variables.variables_entorno()

from fastapi import Body, FastAPI, Form, Request, Response, Query, HTTPException, UploadFile, File, Cookie, WebSocket, WebSocketDisconnect, Depends
from typing import List, Optional
from datetime import datetime
from io import BytesIO
from fastapi.responses import StreamingResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import logging
import requests
from typing import Dict


# Importaciones de los diferentes módulos
from login import login
from administracion import mailing
from administracion import my_profile
from administracion import profiling
from administracion import account
from administracion import employee
from administracion import help_desk
from personas import contactos
from configuraciones import general_information
from soporte import soporte
from soporte import mailing_support
from procesos import contactabilidad
from procesos import encuestas
from procesos import primer_contacto
from procesos import noticias
from procesos import malling_primer_contacto
from procesos import marketing
from procesos import admin_propuestas
from generacion_documentos.excel import crear_excel_de_json, tabla_a_excel_prospectos  # Asegúrate de que la ruta sea correcta





# Importar clases para endpoints POST y PUT
from clases import ObtenerExcelRequest,LoginRequest, NuevoContactoRequest, ActualizarNoticiaRequest, adjuntoFidelizacion, codigoTemporalRequest, EnviarCorreoEmpleadoRequest, ActualizarPerfilRequest, ListProspectosRequest, ListProspectosResponse, ActualizarContraseñaRequest, NuevoPermisoRequest, ActualizarPermisoRequest, ActualizarEmpleadoRequest, ActualizarGeneralInformationRequest, NuevoCuentaServicioRequest, actualizarCuentaServicioRequest, CuentaRequest, CuentaServicioRequest, actualizarCuentadeServicioRequest, ActualizarMesaAyudaRequest, SoporteDataRequest, EnviarCorreoSoporteRequest, NuevoEmpleadoRequest, ActualizarEmpleadoPerfilRequest, NuevoPerfilRequest, ListEncuestadosRequest, ListEncuestadosResponse, TablaSeleccionadaRequest, TablaSeleccionadaResponse, TablaSeleccionadaResponse, CreateNotesResponse, CreateNotesRequest, VoluntarioUpdateRequest, PrimerContactoRequest,EnviarCorreoRequest, updateContacto, NuevoAreaRequest, NuevoCargoRequest, ActualizarAreaRequest, ActualizarCargoRequest, verificacionContactadoRequest, actualizarEstadoEtapaRequest, agregarNuevoProspectoRequest, ObtenerRecordatoriosRequest, ObtenerUrlFirmadaRequest, ObtenerUrlFirmadaResponse, ObtenerUrlFirmadaError, ObtenerPropuestasCrmRequest, ObtenerPropuestasCrmResponse, ObtenerPropuestasCrmError, ProcesamientoResponse, ProcesamientoError, TablaSeleccionadaMarketingRequest, BusquedaPorCamposDinamicosRequest, ActualizarEstadoEtapa, NuevaEncuestaRequest, NuevaPreguntaRequest



# Crear la instancia de la aplicación FastAPI
app = FastAPI(debug=True)

# Configurar CORS para permitir solicitudes desde los orígenes necesarios
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        'http://localhost:3000',
        'http://localhost:4200',
        'https://crm.imparables.com.co',
        "https://dev.crm.imparables.cic-ware.com",
        'https://pru.crm.imparables.com.co',
        'https://pru.imparables.com.co',
        'https://dev.crm.imparables.com.co',
    ],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Configurar logging para capturar y mostrar errores
logging.basicConfig(level=logging.INFO)





""" ======================= Peticiones GET ======================= """
@app.get("/ask/consultarCargos")
async def get_cargos():
    return my_profile.consultarCargos()



@app.get("/ask/consultarPermisos/{id_perfil}")
async def consultar_permisos(id_perfil: int):
    return profiling.consultarPermisos(id_perfil)



@app.get("/ask/consultarPermisosVistas/{idPerfil}")
async def consultar_permisos_vistas(idPerfil: int):
    return profiling.consultarPermisosVistas(idPerfil)



@app.get("/ask/consultarElementosPerfil/{id_perfil}")
async def consultar_elementos_perfil(id_perfil: int):
    return profiling.consultarPermisosElementos(id_perfil)



@app.get("/ask/consultarElementos/{id_vista}")
async def consultar_elementos(id_vista: int):
    return profiling.consultarElementos(id_vista)



@app.get("/ask/consultarPerfil")
async def consultar_Perfil():
    return profiling.consultarPerfil()



@app.get("/ask/consultarModulos")
async def consultar_modulos():
    return profiling.consultarModulos()



@app.get("/ask/consultarVistas/{id_modulo}")
async def consultar_vistas(id_modulo: int):
    return profiling.consultarVistas(id_modulo)



@app.get("/ask/consultarPerfil")
async def consultar_Perfil():
    return profiling.consultarPerfil()



@app.get("/ask/consultarCargosByArea/{idArea}")
async def consultar_cargos_by_area(idArea: int):
    return my_profile.consultarCargosByAreas(idArea)



@app.get("/ask/consultarArea")
async def consultar_areas():
    return my_profile.consultarAreas()



@app.get("/ask/consultarGeneralInformation")
async def consultar_gen_info():
    return general_information.consultarGenInfo()



@app.get("/ask/recuperarSoporte/{idEmployee}")
async def recuperar_soporte(idEmployee: int):
    return soporte.recuperarSoporte(idEmployee)



@app.get("/ask/getModulos")
async def get_modulos():
    return soporte.getModulos()



@app.get("/ask/getVistas/{id_modulo}")
async def get_vistas(id_modulo: int):
    return soporte.getVistas(id_modulo)



@app.get("/ask/getTickets/{idEmployee}")
async def consultar_tickets_por_empleado(idEmployee: int):
    return soporte.getTickets(idEmployee)



@app.get("/ask/getListaTablasDB")
async def get_lista_tablas_DB():
    return  await contactabilidad.getListaTablas()

@app.get("/ask/tareasDisponiblesPrimerContacto")
async def get_tareas_disponibles():
    return primer_contacto.getTareasPrimerContacto()


@app.get("/ask/tareasDisponibles")
async def get_tareas_disponibles():
    return primer_contacto.getTareasDisponibles()


@app.get("/ask/consultarNotasContacto/{id}")
async def consultar_notas_contacto(id: int):
    try:
        return await contactabilidad.getNotesContact({"id_contacto_origen": id})
    except Exception as e:
        logging.error(f"Error al consultar las notas de contacto: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de consulta de notas de contacto")


@app.get("/ask/logSftpConfig")
async def log_sftp_config():
    return noticias.log_sftp_configuration()





@app.get("/ask/tablasSegunContacto/{tipo_contacto}")
async def consultar_notas_contacto(tipo_contacto: str):
    try:
        return marketing.get_lista_tablas_tipo_contacto(tipo_contacto)
    except Exception as e:
        logging.error(f"Error al consultar las tablas segun el tipo de contacto: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de consulta de las tablas segun el tipo de contacto")



# Paso 3 - Columnas obligatorias en la BD
@app.get(
    "/ask/procesamientoExcel/prospectos/paso3/columnasObligatorias",
    response_model=ProcesamientoResponse,
    responses={400: {"model": ProcesamientoError}, 500: {"model": ProcesamientoError}},
    tags=["Procesamiento Excel - Prospectos"],
)
async def endpoint_paso_3():
    try:
        resultado = await contactabilidad.procesamiento_principal_paso_3_obtener_columnas_obligatorias_base_de_datos()
        if not resultado.get("success", False):
            raise HTTPException(status_code=400, detail=resultado.get("message", "Error al obtener columnas obligatorias"))
        return ProcesamientoResponse(success=True, message=resultado.get("message", ""), data=resultado.get("data"))
    except HTTPException:
        raise
    except Exception as e:
        logging.error(f"Error en paso 3: {e}")
        raise HTTPException(status_code=500, detail="Error interno")


# Paso 4 - Columnas opcionales en la BD
@app.get(
    "/ask/procesamientoExcel/prospectos/paso4/columnasOpcionales",
    response_model=ProcesamientoResponse,
    responses={400: {"model": ProcesamientoError}, 500: {"model": ProcesamientoError}},
    tags=["Procesamiento Excel - Prospectos"],
)
async def endpoint_paso_4():
    try:
        resultado = await contactabilidad.procesamiento_principal_paso_4_obtener_columnas_opcionales_base_de_datos()
        if not resultado.get("success", False):
            raise HTTPException(status_code=400, detail=resultado.get("message", "Error al obtener columnas opcionales"))
        return ProcesamientoResponse(success=True, message=resultado.get("message", ""), data=resultado.get("data"))
    except HTTPException:
        raise
    except Exception as e:
        logging.error(f"Error en paso 4: {e}")
        raise HTTPException(status_code=500, detail="Error interno")




@app.get("/ask/obtenerRespuestasPrimerContacto/{id}")
def obtener_respuestas_primer_contacto(id: int):
    try:
        return contactos.get_respuestas_primer_contacto(id)
    except Exception as e:
        logging.error(f"Error al obtener las respuestas del primer contacto: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de respuestas del primer contacto")



@app.get("/ask/estadosEtapas")
async def consultar_estados_etapas():
    try:
        return marketing.traer_estados_etapas()
    except Exception as e:
        logging.error(f"Error al consultar los estados etapas: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de consulta de estados etapas")



@app.get("/ask/consultarEncuestas")
async def consultar_encuestas():
    try:
        return encuestas.traer_lista_encuestas()
    except Exception as e:
        logging.error(f"Error al consultar Encuestas: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de consultar encuestas")



@app.get("/ask/consultarTiposPreguntas")
async def consultar_tipos_preguntas_encuestas():
    try:
        return encuestas.traer_tipos_preguntas()
    except Exception as e:
        logging.error(f"Error al obtener la información de los tipos de preguntas: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.get("/ask/consultarCategorias")
async def consultar_tipos_preguntas_encuestas():
    try:
        return encuestas.traer_categorias_encuestas()
    except Exception as e:
        logging.error(f"Error al obtener la información de las categorias de las encuestas: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



""" ======================= Peticiones POST ======================= """
@app.post("/ask/variablesEntorno")
async def variables_entorno():
    return variables.variables_entorno()



@app.post("/ask/obtenerCuentasServicio")
async def obtenerCuentas():
    return account.obtenerCuentas()



@app.post("/ask/users")
async def get_users():
    return employee.listEmpleados()

@app.post("/ask/obtenerNoticiasCrm")
async def obtener_noticiascrm(fecha: Optional[str] = Query(None, description="Fecha en formato YYYY-MM-DD")):
    return noticias.obtener_noticiascrm(fecha)



@app.post("/ask/insertarNoticiasCrm", response_model=dict, responses={200: {"model": dict}}, tags=["Agregar nueva propuesta"])
async def insertar_noticia_crm(
    principal: str = Form(...),
    fecha_noticia: str = Form(...),
    titulo: str = Form(...),
    link: str = Form(...),
    texto_corto: str = Form(...),
    texto_largo: str = Form(...),
    id_estado: int = Form(...),
    adjunto: UploadFile = File(...)
):
    try:
        # Los datos del formulario ya están disponibles como variables individuales
        data = {
            'principal': principal,
            'fecha_noticia': fecha_noticia,
            'titulo': titulo,
            'link': link,
            'texto_corto': texto_corto,
            'texto_largo': texto_largo,
            'id_estado': id_estado,
            'adjunto': adjunto
        }
        
        # Ahora puedes llamar a la función que maneja la inserción
        resultado = noticias.insertar_noticia(data)
        return resultado

    except HTTPException as e:
        raise e
    except Exception as e:
        logging.error(f"Error al insertar noticia in main: {e}")
        raise HTTPException(status_code=500, detail="Error interno al insertar noticia")

    

@app.post("/ask/obtenerDataMesaAyuda")
async def obtener_datos_mesa_ayuda():
    return help_desk.obtenerDatosMesaAyuda()



@app.post("/ask/login")
async def login_route(request: LoginRequest):  # Usar la clase LoginRequest en lugar de los parámetros individuales
    try:
        data = {
            "email": request.email,
            "password": request.password
        }
        # Pasar los datos al método de login
        return login.login(data)  # Cambia esto por la lógica real de login
    except Exception as e:
        logging.error(f"Error en login: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de login")



@app.post("/ask/codigo")
async def codigo_temporal(request: codigoTemporalRequest):
    try:
        data = {
            "email": request.email
        }
        # Pasar los datos al método de obtener asistentes
        return login.codigoTemporal(data)
    except Exception as e:
        logging.error(f"Error al obtener asistentes: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de obtener asistentes")



@app.post("/ask/sendEmailEmployee")
async def enviar_correo_empleado(request: EnviarCorreoEmpleadoRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "user": request.user,
            "email": request.email,
            "codigo": request.codigo
        }
        # Pasar los datos al método para enviar el correo al empleado
        return mailing.sendEmailEmployee(data)  # Llama al método real para enviar el correo
    except Exception as e:
        logging.error(f"Error al enviar el correo al empleado: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud para enviar el correo")



@app.post("/ask/listProspectos", response_model=ListProspectosResponse, responses={200: {"model": ListProspectosResponse}}, tags=["Listar prospectos"])
async def list_prospectos_endpoint(datos: ListProspectosRequest):
    # Convertir los datos en diccionario para pasarlos a la función
    resultado = contactos.list_prospectos(datos.dict())
    
    # Devolver la respuesta, que ya está formateada en el formato esperado
    return resultado



@app.post("/ask/updateFoto/{idEmp}")
async def update_foto(
    idEmp: int,
    profile_picture: UploadFile = File(...),
    file_name: str = Form(...),
    file_type: str = Form(...),
):
    # Crear un diccionario con los datos del formulario
    data = {
        'profile_picture': profile_picture,
        'file_name': file_name,
        'file_type': file_type
    }
    # Pasar los datos junto con idEmp a la función updateFoto
    return my_profile.updateFoto(idEmp, data)



@app.post("/ask/obtenerCuentas")
async def obtener_cuentas(request: CuentaRequest):
    try:
        data = {
            "id_cuenta": request.id_cuenta
        }
        # Aquí debes llamar al método que obtenga las cuentas
        return account.obtenerCuentasdeServicio(data)  # Cambia esto por la lógica de negocio real
    except Exception as e:
        logging.error(f"Error al obtener cuentas: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.post("/ask/insertarCuentaServicio")
async def insertar_cuenta_servicio(request: NuevoCuentaServicioRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "tipo_cuenta": request.tipo_cuenta,
            "status": request.status
        }
        # Pasar los datos al método para insertar la cuenta de servicio
        return account.insertarCuentaServicio(data)  # Llama al método real para insertar la cuenta
    except Exception as e:
        logging.error(f"Error al insertar la cuenta de servicio: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de inserción de la cuenta de servicio")
    
@app.post("/ask/insertarContactados")
async def insertar_contacto(request: NuevoContactoRequest):  # Usamos la clase para recibir la data
    try:
        data = request.dict()
        # Pasar los datos al método para insertar la cuenta de servicio
        return contactos.insertarContacto(data)  # Llama al método real para insertar la cuenta
    except Exception as e:
        logging.error(f"Error al insertar la cuenta de servicio: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de inserción de la cuenta de servicio")



@app.post("/ask/newPermissions")
async def insertar_permiso(request: NuevoPermisoRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "id_perfil": request.id_perfil,
            "id_modulo": request.id_modulo,
            "id_vista": request.id_vista,
            "id_elemento": request.id_elemento,
            "permiso": request.permiso
        }
        return profiling.insertarPermiso(data)  # Llama al método real para insertar el permiso
    except Exception as e:
        logging.error(f"Error al insertar el permiso: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de inserción del permiso")



@app.post("/ask/updateGeneralInformation/{id}")
async def actualizar_general_information(id: int, request: ActualizarGeneralInformationRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "nombre": request.nombre,
            "tipo_doc": request.tipo_doc,
            "documento": request.documento,
            "correo": request.correo,
            "telefono": request.telefono,
            "direccion": request.direccion
        }

        # Pasar los datos al método para actualizar la información
        return general_information.actualizarGenInfo(id, data)  # Llama al método real para actualizar la información

    except Exception as e:
        logging.error(f"Error al actualizar la información general: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de actualización de información general")



@app.post("/ask/insertarCuentadeServicio")
async def insertar_cuenta_de_servicio(request: CuentaServicioRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "id_cuenta": request.id_cuenta,
            "dato": request.dato,
            "valor": request.valor
        }
        # Pasar los datos al método de inserción
        return account.insertarCuentadeServicio(data)  # Llama al método real de inserción

    except Exception as e:
        logging.error(f"Error al insertar cuenta de servicio: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de insertar cuenta de servicio")



@app.post("/ask/newSupport")
async def enviar_ticket_soporte(request: SoporteDataRequest):
    try:
        data = {
            "prioridad": request.prioridad,
            "modulo": request.modulo,
            "vista": request.vista,
            "asunto": request.asunto,
            "id_empleado": request.id_empleado,
            "observacion": request.observacion
        }
        return soporte.insertarSoporte(data)
    except Exception as e:
        logging.error(f"Error al enviar el correo de PQRS: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.post("/ask/sendEmailSoporte")
async def enviar_correo_soporte(request: EnviarCorreoSoporteRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "asunto": request.asunto,
            "observacion": request.observacion,
            "nombre": request.nombre,
            "modulo_name": request.modulo_name,
            "vista_name": request.vista_name,
        }
        # Llamada a la función para enviar el correo
        return mailing_support.sendEmailSoporte(data)
    except Exception as e:
        logging.error(f"Error al enviar el correo de soporte: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud para enviar el correo de soporte")



@app.post("/ask/newUser")
async def insertar_empleado(request: NuevoEmpleadoRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "nombres": request.nombres,
            "apellidos": request.apellidos,
            "tipo_doc": request.tipo_doc,
            "documento": request.documento,
            "id_area": request.id_area,
            "id_cargo": request.id_cargo,
            "correo_corporativo": request.correo_corporativo,
            "correo_alterno": request.correo_alterno,
            "telefono": request.telefono,
            "direccion": request.direccion,
            "status": request.status,
            "idperfil": request.idperfil,
        }
        # Pasar los datos al método para insertar el empleado
        return employee.insertarEmpleado(data)  # Llama al método real para insertar el empleado
    except Exception as e:
        logging.error(f"Error al insertar el empleado: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de inserción del empleado")



@app.post("/ask/NuevoRecordatorioFidelizacion")
async def insertar_recordatorio_fidelizacion(request: adjuntoFidelizacion):  # Usamos la clase para recibir la data
    try:
        data = {
            "id_contacto_union": request.id_contacto_union,
            "id_agente_creador": request.id_agente_creador,
            "asunto": request.asunto,
            "descripcion": request.descripcion,
            "fecha_hora": request.fecha_hora,
            "id_agente_asignado": request.id_agente_asignado,
            
        }
        # Pasar los datos al método para insertar el empleado
        return contactos.insertarRecordatorioFidelizacion(data)  # Llama al método real para insertar el empleado
    except Exception as e:
        logging.error(f"Error al insertar el recordatorio: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de inserción del empleado")

@app.post("/ask/newProfil")
async def insertar_perfil(request: NuevoPerfilRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "perfiles": request.perfiles,
            "descripcion": request.descripcion,
            "status": request.status
        }
        # Pasar los datos al método para insertar el perfil
        return profiling.insertarPerfil(data)  # Llama al método real para insertar el perfil
    except Exception as e:
        logging.error(f"Error al insertar el perfil: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de inserción del perfil")



@app.post("/ask/listEncuestados", response_model=ListEncuestadosResponse)
async def list_encuestados_endpoint(datos: ListEncuestadosRequest):
    # Ahora ya no pasamos 'fecha' porque no lo estamos utilizando
    resultado = encuestas.obtener_encuestados(
        page=datos.page,
        page_size=datos.pageSize
    )
    return resultado



@app.post("/ask/datosTablaSeleccionada", response_model=TablaSeleccionadaResponse, responses={200: {"model": TablaSeleccionadaResponse}}, tags=["Selección de Tablas contactabilidad"])
async def datos_tabla_seleccionada_endpoint(request: TablaSeleccionadaRequest):
    try:
        data = request.dict()
        # Convertir los datos en diccionario para pasarlos a la función
        resultado = await contactabilidad.datos_tabla_seleccionada(data)
        
        # Devolver la respuesta, que ya está formateada en el formato esperado
        return resultado
    except Exception as e:
        logging.error(f"Error al obtener los datos de la tabla seleccionada: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de obtener los datos de la tabla seleccionada")



@app.post("/ask/notasContacto", response_model=CreateNotesResponse, tags=["Notas de Contacto"])
async def notas_contacto(request: CreateNotesRequest):
    try:
        data = request.dict()
        resultado = await contactabilidad.createNotes(data)

        return resultado
    except Exception as e:
        logging.error(f"Error al crear las notas: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de crear las notas de contacto")


@app.post("/ask/insertarTareaPrimerContacto", response_model=dict, responses={200: {"model": dict}}, tags=["Primer Contacto"])
async def insertar_primer_contacto_endpoint(request: PrimerContactoRequest):
    try:
        data = request.dict()
        resultado = primer_contacto.insertar_primer_contacto(data)
        return resultado
    except Exception as e:
        logging.error(f"Error al insertar primer contacto: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de insertar primer contacto")
    
@app.post("/ask/enviarCorreoPrimerContacto")
async def enviar_correo_primer_contacto(request: EnviarCorreoRequest):
    try:
        return malling_primer_contacto.send_email_primer_contacto(request.dict())  # Pasamos los datos como diccionario
    except Exception as e:
        logging.error(f"Error al enviar correo primer contacto: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar el envío del correo")



@app.post("/ask/newArea")
async def insertar_area(request: NuevoAreaRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "area": request.area,
            "descripcion": request.descripcion
        }

        # Pasar los datos al método para insertar el área
        return my_profile.insertarArea(data)  # Llama al método real para insertar el área

    except Exception as e:
        logging.error(f"Error al insertar el área: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de inserción del área")




@app.post("/ask/newCargos")
async def insertar_cargo(request: NuevoCargoRequest):
    try:
        data = {
            "cargo": request.cargo,
            "descripcion": request.descripcion,
            "idArea": request.idArea
        }

        # Pasar los datos al método para insertar el área
        return my_profile.insertarCargo(data)


    except Exception as e:
        logging.error(f"Error al insertar el área: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de inserción del área")



@app.post("/ask/verificacionContactado", response_model=dict, responses={200: {"model": dict}}, tags=["verificación Contactado"])
async def func(request: verificacionContactadoRequest):
    try:
        data = request.dict()
        resultado = await contactabilidad.verificacion_persona_contactada(data)
        return resultado
    except Exception as e:
        logging.error(f"Error al verficiar el contacto: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de verificación de contacto")



@app.post("/ask/agregarNuevoProspecto", response_model=dict, responses={200: {"model": dict}}, tags=["Agregar nuevo contacto prospecto"])
async def func(request: agregarNuevoProspectoRequest):
    try:
        data = request.dict()
        resultado = await contactabilidad.agregar_prospecto_nuevo(data)
        return resultado
    except Exception as e:
        logging.error(f"Error al agregar un nuevo contacto prospecto: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de agregar un nuevo contacto prospecto")


@app.post("/ask/obtener-recordatorios")
async def obtener_recordatorios_fidelizacion(request: ObtenerRecordatoriosRequest):
    try:
        return contactos.obtener_recordatorios_por_contacto(request.id_contacto_union)
    except Exception as e:
        logging.error(f"Error al obtener recordatorios: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de obtener recordatorios")




""" ======================= APIs Archivos de propuestas ciudadano ======================= """

@app.post("/ask/obtenerUrlFirmada", response_model=ObtenerUrlFirmadaResponse, responses={400: {"model": ObtenerUrlFirmadaError}, 500: {"model": ObtenerUrlFirmadaError}}, tags=["URLs Firmadas"])
async def obtener_url_firmada_endpoint(request: ObtenerUrlFirmadaRequest):
    """
    Obtiene una URL firmada para un archivo específico en S3.
    
    Args:
        request: Contiene el s3_key del archivo
    
    Returns:
        URL firmada con tiempo de expiración
    """
    try:
        resultado = await admin_propuestas.obtener_url_firmada(request.s3_key)
        
        if not resultado["success"]:
            raise HTTPException(status_code=400, detail=resultado["message"])
        
        return ObtenerUrlFirmadaResponse(
            success=True,
            url_firmada=resultado["data"]["signed_url"]
        )
        
    except HTTPException:
        raise  # Re-lanza HTTPExceptions tal cual
    except Exception as e:
        logging.error(f"Error al obtener URL firmada: {str(e)}")
        raise HTTPException(status_code=500, detail="Error interno al generar URL firmada")


@app.post("/ask/obtenerPropuestasCrm", response_model=ObtenerPropuestasCrmResponse, responses={400: {"model": ObtenerPropuestasCrmError}, 500: {"model": ObtenerPropuestasCrmError}}, tags=["Propuestas CRM"])
async def obtener_propuestas_crm_endpoint(request: ObtenerPropuestasCrmRequest):
    """
    Obtiene las propuestas con sus archivos adjuntos de S3, paginadas.
    
    Args:
        request: Contiene page y pageSize para la paginación
    
    Returns:
        Lista paginada de propuestas con sus archivos adjuntos
    """
    try:
        resultado = await admin_propuestas.obtener_propuestas_con_archivos(request.page, request.pageSize)
        
        if not resultado["success"]:
            raise HTTPException(status_code=400, detail=resultado["message"])
        
        return ObtenerPropuestasCrmResponse(
            success=True,
            message=resultado["message"],
            data=resultado["data"],
            totalRecords=resultado["totalRecords"],
            totalPages=resultado["totalPages"],
            currentPage=resultado["currentPage"]
        )
        
    except HTTPException:
        raise  # Re-lanza HTTPExceptions tal cual
    except Exception as e:
        logging.error(f"Error al obtener propuestas CRM: {str(e)}")
        raise HTTPException(status_code=500, detail="Error interno al obtener propuestas")




# Paso 1 - Validación de formato
@app.post(
    "/ask/procesamientoExcel/prospectos/paso1/validacionFormato",
    response_model=ProcesamientoResponse,
    responses={400: {"model": ProcesamientoError}, 500: {"model": ProcesamientoError}},
    tags=["Procesamiento Excel - Prospectos"],
)
async def endpoint_paso_1(excel: UploadFile = File(...)):
    try:
        resultado = await contactabilidad.procesamiento_principal_paso_1_validacion_formato(excel)
        if not resultado.get("success", False):
            raise HTTPException(status_code=400, detail=resultado.get("message", "Error en validación de formato"))
        return ProcesamientoResponse(success=True, message=resultado.get("message", ""), data=resultado.get("id"))
    except HTTPException:
        raise
    except Exception as e:
        logging.error(f"Error en paso 1: {e}")
        raise HTTPException(status_code=500, detail="Error interno")


# Paso 2 - Obtener columnas desde el Excel
@app.post(
    "/ask/procesamientoExcel/prospectos/paso2/obtenerColumnasExcel",
    response_model=ProcesamientoResponse,
    responses={400: {"model": ProcesamientoError}, 500: {"model": ProcesamientoError}},
    tags=["Procesamiento Excel - Prospectos"],
)
async def endpoint_paso_2(excel: str = Body(..., embed=True)):
    try:
        resultado = await contactabilidad.procesamiento_principal_paso_2_obtener_columnas_excel(excel)
        if not resultado.get("success", False):
            raise HTTPException(status_code=400, detail=resultado.get("message", "Error al obtener columnas"))
        return ProcesamientoResponse(success=True, message=resultado.get("message", ""), data=resultado.get("data"))
    except HTTPException:
        raise
    except Exception as e:
        logging.error(f"Error en paso 2: {e}")
        raise HTTPException(status_code=500, detail="Error interno")



@app.post(
    "/ask/procesamientoExcel/prospectos/paso5/validacionOpenAI",
    response_model=ProcesamientoResponse,
    responses={400: {"model": ProcesamientoError}, 500: {"model": ProcesamientoError}},
    tags=["Procesamiento Excel - Prospectos"],
)
async def endpoint_paso_5(excel: str = Body(..., embed=True)):
    try:
        resultado = await contactabilidad.procesamiento_principal_paso_5_validacion_openai(excel)
        if not resultado.get("success", False):
            return ProcesamientoResponse(
                success=False,
                message="El excel no pasó la validación correspondiente",
                data={}
            )
        return ProcesamientoResponse(
            success=True,
            message=resultado.get("message", ""),
            data=resultado.get("data")
        )
    except HTTPException:
        raise
    except Exception as e:
        logging.error(f"Error en paso 5: {e}")
        raise HTTPException(status_code=500, detail="Error interno")




@app.post(
    "/ask/procesamientoExcel/prospectos/paso6/procesarExcel",
    response_model=ProcesamientoResponse,
    responses={400: {"model": ProcesamientoError}, 500: {"model": ProcesamientoError}},
    tags=["Procesamiento Excel - Prospectos"],
)
async def endpoint_paso_6(
    excel: str = Body(..., embed=True),  # ahora viene en el JSON
    mapeo_columnas: str = Form(...),     # se mantiene como Form
):
    try:
        # parsear JSON string a dict real
        try:
            mapeo_dict: Dict[str, str] = json.loads(mapeo_columnas)
        except json.JSONDecodeError:
            raise HTTPException(status_code=400, detail="mapeo_columnas no es un JSON válido")

        resultado = await contactabilidad.procesamiento_principal_paso_6_procesar_excel_y_guardar_en_base_de_datos(
            excel, mapeo_dict
        )

        if not resultado.get("success", False):
            raise HTTPException(
                status_code=400,
                detail=resultado.get("message", "Error al procesar Excel")
            )

        return ProcesamientoResponse(
            success=True,
            message=resultado.get("message", ""),
            data=resultado.get("data"),
        )

    except HTTPException:
        raise
    except Exception as e:
        logging.error(f"Error en paso 6: {e}")
        raise HTTPException(status_code=500, detail="Error interno")



@app.post("/ask/marketing_datosTablaSeleccionada", response_model=TablaSeleccionadaResponse, responses={200: {"model": TablaSeleccionadaResponse}}, tags=["Selección de Tablas contactabilidad"])
async def datos_tabla_seleccionada_marketing(request: TablaSeleccionadaMarketingRequest):
    try:
        data = request.dict()
        # Convertir los datos en diccionario para pasarlos a la función
        resultado = marketing.datos_tabla_seleccionada(data)
        
        # Devolver la respuesta, que ya está formateada en el formato esperado
        return resultado
    except Exception as e:
        logging.error(f"Error al obtener los datos de la tabla seleccionada: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de obtener los datos de la tabla seleccionada")



@app.post("/ask/busquedaDinamicaCampos", response_model=TablaSeleccionadaResponse, responses={200: {"model": TablaSeleccionadaResponse}}, tags=["Selección de Tablas Marketing"])
async def datos_tabla_seleccionada_endpoint(request: BusquedaPorCamposDinamicosRequest):
    try:
        data = request.dict()
        # Convertir los datos en diccionario para pasarlos a la función
        resultado = marketing.filtrado_dinamico_busqueda_campos(data)
        
        # Devolver la respuesta, que ya está formateada en el formato esperado
        return resultado
    except Exception as e:
        logging.error(f"Error al obtener los datos de la tabla filtrada: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de obtener los datos de la tabla filtrada")



@app.post("/ask/insertarEncuesta")
async def insertar_encuesta(request: NuevaEncuestaRequest):
    try:
        data = request.dict()
        # Pasar los datos al método de inserción
        return encuestas.insertar_encuesta(data)  # Llama al método real de inserción

    except Exception as e:
        logging.error(f"Error al insertar encuesta: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de insertar encuesta")



@app.post("/ask/insertarPregunta")
async def insertar_pregunta_encuesta(request: NuevaPreguntaRequest):
    try:
        data = request.dict()
        # Pasar los datos al método de inserción
        return encuestas.insertar_pregunta(data)  # Llama al método real de inserción

    except Exception as e:
        logging.error(f"Error al insertar pregunta en encuesta: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de insertar pregunta en encuesta")

@app.post("/ask/obtenerExcelDeListaJson", tags=["Generar Excel desde JSON"])
async def obtener_excel_de_lista_json(request: ObtenerExcelRequest):
    try:
        buffer: BytesIO = await crear_excel_de_json(request.rows)
        filename = f"export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
        return StreamingResponse(
            buffer,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={"Content-Disposition": f'attachment; filename="{filename}"'}
        )
    except Exception as e:
        logging.error(f"Error al obtener el Excel de la lista JSON: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de obtener el Excel de la lista JSON")

@app.post("/ask/obtenerExcelDeProspectos", tags=["Generar Excel desde Prospectos"])
async def obtener_excel_de_prospectos():
    try:
        buffer: BytesIO = await tabla_a_excel_prospectos()

        # Reposicionar el puntero al inicio del buffer
        buffer.seek(0)

        # Retornar el archivo Excel como respuesta
        return StreamingResponse(
            buffer,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={"Content-Disposition": "attachment; filename=prospectos.xlsx"}
        )

    except Exception as e:
        logging.error(f"Error al obtener el Excel de prospectos: {e}", exc_info=True)
        raise HTTPException(
            status_code=500,
            detail="Error al procesar la solicitud de obtener el Excel de prospectos"
        )
""" ======================= Peticiones PUT ======================= """
@app.put("/ask/updatemyprofil/{id}")
async def actualizar_my_perfil(id: int, request: ActualizarPerfilRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "nombres": request.nombres,
            "apellidos": request.apellidos,
            "tipo_doc": request.tipo_doc,
            "documento": request.documento,
            "correo_corporativo": request.correo_corporativo,
            "correo_alterno": request.correo_alterno,
            "telefono": request.telefono,
            "direccion": request.direccion,
            "id_area": request.id_area,
            "id_cargo": request.id_cargo,
            "status": request.status
        }

        # Pasar los datos al método para actualizar el perfil
        return my_profile.actualizarMyPerfil(id, data)

    except Exception as e:
        logging.error(f"Error al actualizar el perfil: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud para actualizar el perfil")


@app.put("/ask/updateNews/{id}")
async def actualizar_mi_noticia(
    id: int,
    principal: int = Form(...),
    fecha_noticia: str = Form(...),
    titulo: str = Form(...),
    texto_corto: str = Form(...),
    texto_largo: str = Form(...),
    id_estado: int = Form(...),
    link: str = Form(...),
    adjunto: Optional[UploadFile] = File(None)
):
    try:
        # Definir los datos que se van a actualizar
        data = {
            "principal": principal,
            "fecha_noticia": fecha_noticia,
            "titulo": titulo,
            "texto_corto": texto_corto,
            "texto_largo": texto_largo,
            "id_estado": id_estado,
            "link": link,
            "adjunto": adjunto  # El archivo ya viene como UploadFile o None
        }
        
        # Llamar al método para actualizar la noticia en la base de datos
        return noticias.actualizar_noticia(id, data)

    except Exception as e:
        logging.error(f"Error al actualizar la noticia: {e}")
        raise HTTPException(status_code=500, detail=f"Error al procesar la solicitud: {str(e)}")

@app.put("/ask/changepassword/{idUser}")
async def actualizar_contraseña(idUser: int, request: ActualizarContraseñaRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "newPassword": request.newPassword
        }

        # Pasar los datos al método para actualizar la contraseña
        return my_profile.actualizarContraseña(idUser, data)

    except Exception as e:
        logging.error(f"Error al actualizar la contraseña: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud para actualizar la contraseña")



@app.put("/ask/actualizarPermiso/{id}")
async def actualizar_permiso(id: int, request: ActualizarPermisoRequest):
    try:
        data = {
            "id_perfil": request.id_perfil,
            "id_modulo": request.id_modulo,
            "id_vista": request.id_vista,
            "id_elemento": request.id_elemento,
            "permiso": request.permiso
        }

        return profiling.actualizarPermiso(id, data)

    except Exception as e:
        logging.error(f"Error al actualizar: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.put("/ask/updateEmployee/{id}")
async def actualizar_empleado(id: int, request: ActualizarEmpleadoRequest):
    try:
        data = {
            "nombres": request.nombres,
            "apellidos": request.apellidos,
            "tipo_doc": request.tipo_doc,
            "documento": request.documento,
            "correo_corporativo": request.correo_corporativo,
            "correo_alterno": request.correo_alterno,
            "telefono": request.telefono,
            "direccion": request.direccion,
            "id_area": request.id_area,
            "id_cargo": request.id_cargo,
            "idperfil": request.idperfil,
            "status": request.status,
            "nomstatus": request.nomstatus
        }
        return employee.actualizarEmpleado(id, data)
    except Exception as e:
        logging.error(f"Error al actualizar el perfil: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.put("/ask/actualizarCuentaServicio")
async def actualizar_cuenta_servicio(request: actualizarCuentaServicioRequest):
    try:
        data = {
            "id": request.id,
            "tipo_cuenta": request.tipo_cuenta,
            "status": request.status
        }
        return account.actualizarCuentaServicio(data)
    except Exception as e:
        logging.error(f"Error al actualizar: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.put("/ask/actualizarCuentadeServicio")
async def actualizar_cuenta_de_servicio(request: actualizarCuentadeServicioRequest):
    try:
        data = {
            "id": request.id,
            "dato": request.dato,
            "valor": request.valor
        }
        return account.actualizarCuentadeServicio(data)
    except Exception as e:
        logging.error(f"Error al actualizar: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.put("/ask/actualizarMesaAyuda")
async def actualizar_mesa_ayuda(request: ActualizarMesaAyudaRequest):  # Usamos la clase para recibir la data
    try:
        data = {
            "id_reporte": request.id_reporte,
            "respuesta": request.respuesta,
            "id_empleado": request.id_empleado,
            "status": request.status,
            "fecha_respuesta": request.fecha_respuesta
        }
        # Pasar los datos al método para actualizar la mesa de ayuda
        return help_desk.actualizarMesaAyuda(data)
    except Exception as e:
        logging.error(f"Error al actualizar la mesa de ayuda: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud para actualizar la mesa de ayuda")



@app.put("/ask/updateProfil/{id}")
async def actualizar_perfil(id: int, request: ActualizarEmpleadoPerfilRequest):
    try:
        data = {
            "perfiles": request.perfiles,
            "descripcion": request.descripcion,
            "status": request.status
        }
        return profiling.actualizarPerfil(id, data)
    except Exception as e:
        logging.error(f"Error al actualizar: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.put("/ask/actualizar_voluntario/{id}")
async def actualizar_voluntario(id: int, request: VoluntarioUpdateRequest):
    try:
        # Obtener el nombre de la tabla
        nombre_tabla = request.nombre_tabla  # Asegúrate de que el modelo incluye "nombre_tabla"
        
        # Verificar si el nombre_tabla es válido
        if nombre_tabla not in [
            "inscripciones_voluntarios", 
            "union_voluntarios_antiguos", 
            "base_datos_10k", 
            "registros_crm_antiguo",
            "prospectos_manual"
        ]:
            raise HTTPException(status_code=400, detail="Tabla no válida especificada en la solicitud")

        # Mapeo de los campos por nombre_tabla
        tablas_mapping = {
            "inscripciones_voluntarios": {
                "tipo_documento": request.tipo_documento,
                "documento": request.documento,
                "nombres": request.nombres,
                "apellidos": request.apellidos,
                "correos": request.correos,
                "telefono": request.telefono,
                "pais": request.pais,
                "departamento": request.departamento,
                "ciudad": request.ciudad,
                "direccion": request.direccion,
                "genero": request.genero,
                "recomendado": request.recomendado,
                "nombre_recomendador": request.nombre_recomendador,
                "grupo_wp": request.grupo_wp,
                "grupo_wp1": request.grupo_wp1,
                "como_ayudar": request.como_ayudar,
                "pasion": request.pasion
            },
            "base_datos_10k": {
                "fecha_registro": request.fecha_registro,
                "ciudad": request.ciudad,
                "correos": request.correos,
                "departamento": request.departamento,
                "documento": request.documento,
                "telefono": request.telefono,
                "nombres_completos": request.nombres_completos,
                "intereses": request.intereses,
                "autorizacion": request.autorizacion
            },
            "registros_crm_antiguo": {
                "nombres": request.nombres,
                "apellidos": request.apellidos,
                "correos": request.correos,
                "telefono": request.telefono,
                "tipo_documento": request.tipo_documento,
                "documento": request.documento,
                "departamento": request.departamento,
                "ciudad": request.ciudad,
                "localidad": request.localidad,
                "barrio": request.barrio,
                "direccion": request.direccion,
                "fecha_cumpleanos": request.fecha_cumpleanos,
                "genero": request.genero,
                "tipo_sangre": request.tipo_sangre
            },
            "prospectos_manual": {
                "nombres": request.nombres,
                "apellidos": request.apellidos,
                "tipo_documento": request.tipo_documento,
                "documento": request.documento,
                "correos": request.correos,
                "telefono": request.telefono,
                "pais": request.pais,
                "departamento": request.departamento,
                "ciudad": request.ciudad,
                "localidad": request.localidad,
                "barrio": request.barrio,
                "direccion": request.direccion,
                "fecha_cumpleanos": request.fecha_cumpleanos,
                "genero": request.genero,
                "tipo_sangre": request.tipo_sangre,
                "recomendado": request.recomendado,
                "nombre_recomendador": request.nombre_recomendador,
                "grupo_wp": request.grupo_wp,
                "grupo_wp1": request.grupo_wp1,
                "como_ayudar": request.como_ayudar,
                "pasion": request.pasion,
                "intereses": request.intereses,
                "autorizacion": request.autorizacion
            }
        }

        # Obtener los datos de la tabla correspondiente junto con su nombreTabla
        data = tablas_mapping.get(nombre_tabla, {})
        data["nombre_tabla"] = nombre_tabla
        #data = tablas_mapping.get(nombre_tabla)

        if not data:
            raise HTTPException(status_code=400, detail="Datos no encontrados para la tabla especificada")

        # Llamar a la función de actualización en la base de datos
        return await contactabilidad.actualizar_voluntario_db(id, data)

    except Exception as e:
        logging.error(f"Error al actualizar: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")


@app.put("/ask/actualizar_contacto/{id}")
async def actualizar_contacto(id: int, request: updateContacto):
    
    try:
        data = {
            "fecha_registro": request.fecha_registro,
            "tipo_documento": request.tipo_documento,
            "documento": request.documento,
            "nombres": request.nombres,
            "apellidos": request.apellidos,
            "correos": request.correos,
            "telefono": request.telefono,
            "pais": request.pais,
            "departamento": request.departamento,
            "ciudad": request.ciudad,
            "direccion": request.direccion,
            "genero": request.genero,
            "recomendado": request.recomendado,
            "nombre_recomendador": request.nombre_recomendador,
            "grupo_wp": request.grupo_wp,
            "grupo_wp1": request.grupo_wp1,
            "pasion": request.pasion,
            "estado_etapa": request.estado_etapa,
            "localidad": request.localidad,
            "barrio": request.barrio,
            "fecha_cumpleanos": request.fecha_cumpleanos,
            "tipo_sangre": request.tipo_sangre,
            "autorizacion": request.autorizacion,
            "origen_datos": request.origen_datos,
            "como_ayudar": request.como_ayudar,
            "nombre_embajador": request.nombre_embajador,
            "tiempo_primer_contacto": request.tiempo_primer_contacto,
            "intereses": request.intereses,
            "fecha_registro_contacto": request.fecha_registro_contacto,
        }
        resultado = contactos.actualizar_contacto(id, data)
        if not resultado.get("success"):
            raise HTTPException(status_code=500, detail=resultado.get("message", "Error al actualizar el contacto"))
        
        return resultado

    except HTTPException as e:
        raise e
    except Exception as e:
        logging.error(f"Error al actualizar: {e}")
        raise HTTPException(status_code=500, detail=str(e))



@app.put("/ask/updateArea/{id}")
async def actualizar_area(id: int, request: ActualizarAreaRequest):
    try:
        data = {
            "area": request.area,
            "descripcion": request.descripcion
        }

        return my_profile.actualizarArea(id, data)

    except Exception as e:
        logging.error(f"Error al actualizar: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.put("/ask/updateCargos/{id}")
async def actualizar_cargos(id: int, request: ActualizarCargoRequest):
    try:
        data = {
            "cargo": request.cargo,
            "descripcion": request.descripcion,
            "idArea": request.idArea
        }

        return my_profile.actualizarCargo(id, data)


    except Exception as e:
        logging.error(f"Error al actualizar: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud")



@app.put("/ask/actualizarEstadoEtapa", response_model=dict, responses={200: {"model": dict}}, tags=["Actualizar Estado Etapa"])
async def func(request: actualizarEstadoEtapaRequest):
    try:
        data = request.dict()
        resultado = await contactabilidad.actualizar_estado_etapa_verificado(data)
        return resultado
    except Exception as e:
        logging.error(f"Error al actualizar el estado etapa del contacto: {e}")
        raise HTTPException(status_code=500, detail="Error al procesar la solicitud de actualización del estado etapa del contacto")




@app.put("/ask/updatenews/{id}")
async def actualizar_mi_noticia(
    id: int,
    principal: int = Form(...),
    fecha_noticia: str = Form(...),
    titulo: str = Form(...),
    texto_corto: str = Form(...),
    texto_largo: str = Form(...),
    id_estado: int = Form(...),
    link: str = Form(...),
    adjunto: Optional[UploadFile] = File(None)
):
    try:
        # Definir los datos que se van a actualizar
        data = {
            "principal": principal,
            "fecha_noticia": fecha_noticia,
            "titulo": titulo,
            "texto_corto": texto_corto,
            "texto_largo": texto_largo,
            "id_estado": id_estado,
            "link": link,
            "adjunto": adjunto  # El archivo ya viene como UploadFile o None
        }
        
        # Llamar al método para actualizar la noticia en la base de datos
        return noticias.actualizar_noticia(id, data)

    except Exception as e:
        logging.error(f"Error al actualizar la noticia: {e}")
        raise HTTPException(status_code=500, detail=f"Error al procesar la solicitud: {str(e)}")



@app.put("/ask/actualizar_estado_etapa/{id}")
async def actualizar_estado_etapa(id: int, request: ActualizarEstadoEtapa):
    try:
        resultado = contactos.actualizar_estado_etapa_contacto(id, request.estado_etapa)
        
        if not resultado.get("success"):
            raise HTTPException(
                status_code=500, 
                detail=resultado.get("message", "Error al actualizar el estado")
            )
        
        return resultado
    
    except HTTPException as e:
        raise e
    except Exception as e:
        logging.error(f"Error en endpoint actualizar_estado_etapa: {e}")
        raise HTTPException(status_code=500, detail=str(e))
    

""" ======================= Peticiones DELETE ======================= """
@app.delete("/ask/deletePermissions/{id}")
async def eliminar_permiso(id: int):
    return profiling.eliminarPermiso(id)

@app.delete("/ask/eliminarNoticiasCrm/{id}")
async def eliminar_noticia(id: int):
    return noticias.eliminarNoticia(id)

@app.delete("/ask/deleteProfil/{id}")
async def eliminar_perfil(id: int):
    return profiling.eliminarPerfil(id)



@app.delete("/ask/deletearea/{id}")
async def eliminar_area(id: int):
    return my_profile.eliminarArea(id)



@app.delete("/ask/deleteCargos/{id}")
async def eliminar_cargos(id: int):
    return my_profile.eliminarCargos(id)


if __name__ == "__main__":
    import uvicorn
    

    uvicorn.run(app, host="0.0.0.0", port=5000)