#!/usr/bin/env python3
"""
Servidor API REST para predição de glosas
"""

from flask import Flask, request, jsonify
from flask_cors import CORS
from api_predicao import PreditorAPI
import os
import logging
from datetime import datetime

# Configurar logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

app = Flask(__name__)
CORS(app)  # Permitir CORS para todas as origens

# Inicializar preditor
try:
    preditor = PreditorAPI()
    logger.info(f"✅ Preditor inicializado com {len(preditor.modelos)} modelos")
except Exception as e:
    logger.error(f"❌ Erro ao inicializar preditor: {e}")
    preditor = None

@app.route('/', methods=['GET'])
def home():
    """Endpoint raiz com informações da API"""
    return jsonify({
        "api": "Predição de Glosas",
        "versao": "1.0",
        "status": "online",
        "endpoints": {
            "GET /": "Esta página",
            "GET /health": "Status do serviço",
            "POST /predizer": "Predição individual ou múltipla",
            "POST /predizer/batch": "Predição em lote",
            "GET /modelos": "Lista modelos disponíveis"
        }
    })

@app.route('/health', methods=['GET'])
def health():
    """Verifica saúde do serviço"""
    if preditor and preditor.modelos:
        return jsonify({
            "status": "healthy",
            "timestamp": datetime.now().isoformat(),
            "modelos_carregados": len(preditor.modelos),
            "tipos_modelo": list(preditor.modelos.keys())
        })
    else:
        return jsonify({
            "status": "unhealthy",
            "erro": "Modelos não carregados"
        }), 503

@app.route('/modelos', methods=['GET'])
def listar_modelos():
    """Lista modelos disponíveis"""
    if not preditor:
        return jsonify({"erro": "Preditor não inicializado"}), 503
    
    modelos_info = {}
    for nome, modelo_data in preditor.modelos.items():
        modelos_info[nome] = {
            "threshold": round(float(modelo_data.get('best_threshold', 0.5)), 3),
            "features": len(modelo_data.get('feature_names', [])),
            "tipo": nome.replace('tipo_', '').replace('_', ' ').title()
        }
    
    return jsonify({
        "total_modelos": len(preditor.modelos),
        "modelos": modelos_info
    })

@app.route('/predizer', methods=['POST'])
def predizer():
    """
    Endpoint principal de predição
    Aceita JSON único ou array
    """
    try:
        if not preditor:
            return jsonify({"erro": "Serviço não disponível"}), 503
        
        # Log da requisição
        logger.info(f"Nova requisição de predição de {request.remote_addr}")
        
        # Recebe JSON
        dados = request.get_json()
        
        if not dados:
            return jsonify({
                "erro": "Nenhum dado enviado",
                "exemplo": {
                    "protocolo": 123,
                    "tipo_guia": 1,
                    "cod": 31309054,
                    "quantidade": 1
                }
            }), 400
        
        # Faz predição
        inicio = datetime.now()
        resultado = preditor.analisar(dados)
        tempo_ms = (datetime.now() - inicio).total_seconds() * 1000
        
        # Log do resultado
        if isinstance(resultado, dict) and 'resultado' in resultado:
            logger.info(f"Predição concluída - Risco: {resultado['resultado']['risco']} - Tempo: {tempo_ms:.0f}ms")
        
        # Adiciona tempo de processamento
        if isinstance(resultado, dict):
            resultado['tempo_processamento_ms'] = round(tempo_ms, 2)
        elif isinstance(resultado, list):
            for r in resultado:
                r['tempo_processamento_ms'] = round(tempo_ms / len(resultado), 2)
        
        return jsonify(resultado)
        
    except Exception as e:
        logger.error(f"Erro na predição: {str(e)}")
        return jsonify({
            "erro": "Erro ao processar predição",
            "detalhes": str(e)
        }), 500

@app.route('/predizer/batch', methods=['POST'])
def predizer_batch():
    """
    Predição em lote para múltiplos protocolos independentes
    """
    try:
        if not preditor:
            return jsonify({"erro": "Serviço não disponível"}), 503
        
        dados = request.get_json()
        
        if not isinstance(dados, list):
            return jsonify({
                "erro": "Esperado array de protocolos",
                "exemplo": [
                    {"protocolo": 123, "tipo_guia": 1, "cod": 31309054},
                    {"protocolo": 124, "tipo_guia": 2, "cod": 40901220}
                ]
            }), 400
        
        logger.info(f"Processando batch com {len(dados)} protocolos")
        
        resultados = []
        tempo_total = 0
        
        for protocolo_dados in dados:
            inicio = datetime.now()
            try:
                resultado = preditor.analisar(protocolo_dados)
                tempo_ms = (datetime.now() - inicio).total_seconds() * 1000
                
                if isinstance(resultado, dict):
                    resultado['tempo_processamento_ms'] = round(tempo_ms, 2)
                
                resultados.append(resultado)
                tempo_total += tempo_ms
                
            except Exception as e:
                resultados.append({
                    "erro": str(e),
                    "protocolo": protocolo_dados.get('protocolo', 'desconhecido')
                })
        
        return jsonify({
            "total_processados": len(resultados),
            "tempo_total_ms": round(tempo_total, 2),
            "tempo_medio_ms": round(tempo_total / len(resultados), 2) if resultados else 0,
            "resultados": resultados
        })
        
    except Exception as e:
        logger.error(f"Erro no batch: {str(e)}")
        return jsonify({
            "erro": "Erro ao processar lote",
            "detalhes": str(e)
        }), 500

@app.errorhandler(404)
def not_found(error):
    return jsonify({
        "erro": "Endpoint não encontrado",
        "mensagem": "Use GET / para ver endpoints disponíveis"
    }), 404

@app.errorhandler(500)
def internal_error(error):
    return jsonify({
        "erro": "Erro interno do servidor",
        "mensagem": "Verifique os logs para mais detalhes"
    }), 500

if __name__ == '__main__':
    port = int(os.environ.get('PORT', 8010))
    debug = os.environ.get('FLASK_ENV') == 'development'
    
    logger.info(f"🚀 Iniciando servidor na porta {port}")
    logger.info(f"📌 Documentação disponível em http://localhost:{port}/")
    
    app.run(
        host='0.0.0.0',
        port=port,
        debug=debug
    )