#!/usr/bin/env python3
import json
import os
import sys
import traceback

# Configurar limites de threads para estabilidade no cPanel
os.environ['OPENBLAS_NUM_THREADS'] = '1'
os.environ['OMP_NUM_THREADS'] = '1'

try:
    import pyarrow.parquet as pq
    import pandas as pd
    PYARROW_AVAILABLE = True
except ImportError:
    PYARROW_AVAILABLE = False

def application(environ, start_response):
    # Configurações de cabeçalho
    headers = [
        ('Content-Type', 'application/json; charset=utf-8'),
        ('Access-Control-Allow-Origin', '*')
    ]

    # 1. Roteamento simples: Se não for POST, retorna status online
    if environ.get('REQUEST_METHOD') != 'POST':
        start_response('200 OK', headers)
        return [json.dumps({
            "status": "online",
            "pyarrow": PYARROW_AVAILABLE,
            "message": "Envie um POST para processar dados"
        }).encode('utf-8')]

    try:
        # 2. Capturar o corpo da requisição POST
        content_length = int(environ.get('CONTENT_LENGTH', 0))
        post_data = environ['wsgi.input'].read(content_length).decode('utf-8')
        data = json.loads(post_data)

        caminho_arquivo = data.get('caminho_arquivo', '')
        
        # 3. Validações básicas
        if not caminho_arquivo or not os.path.exists(caminho_arquivo):
            raise FileNotFoundError(f"Arquivo não localizado: {caminho_arquivo}")

        if not PYARROW_AVAILABLE:
            raise ImportError("Biblioteca PyArrow/Pandas não instalada no ambiente Python.")

        # 4. Leitura Otimizada (Lendo apenas o necessário)
        # Usamos memory_map=True para não estourar a RAM do servidor
        tabela = pq.read_table(caminho_arquivo, memory_map=True)
        df = tabela.to_pandas()

        # 5. Aplicação de Filtros
        if 'filtros' in data and isinstance(data['filtros'], dict):
            for coluna, valor in data['filtros'].items():
                if coluna in df.columns and valor:
                    # Filtro parcial (contains) sem diferenciar maiúsculas/minúsculas
                    df = df[df[coluna].astype(str).str.contains(str(valor), case=False, na=False)]

        # 6. Preparação do Retorno
        total_encontrado = len(df)
        limite = data.get('limite', 50)
        df_amostra = df.head(limite)

        resultado = {
            "total_registros": total_encontrado,
            "colunas": list(df.columns),
            "amostra": df_amostra.to_dict(orient='records'),
            "status": "sucesso"
        }

        start_response('200 OK', headers)
        return [json.dumps(resultado, ensure_ascii=False).encode('utf-8')]

    except Exception as e:
        start_response('400 Bad Request', headers)
        erro_retorno = {
            "status": "erro",
            "error": str(e),
            "traceback": traceback.format_exc()
        }
        return [json.dumps(erro_retorno).encode('utf-8')]