"""Servidor Webhook: recebe os dados enviados pela Plataforma Rubeus.

A Rubeus envia dados em tempo real via POST (Content-Type: application/json)
para uma URL fixa (veja https://docs.rubeus.com.br/webhook/). Este servidor
expoe essa URL, classifica e armazena os dados recebidos (contatos, registros
de processo, atividades e eventos) e, opcionalmente, regenera a planilha.

Configuracao da URL na Rubeus:
    Configuracoes (engrenagem) > Integracoes > Webhooks > Adicionar
    URL: http(s)://SEU_HOST:PORTA<RUBEUS_WEBHOOK_PATH>
         (ex.: https://seu-dominio.com.br/webhook/rubeus)

Uso:
    python webhook_server.py
    (host/porta/rota/token vem do .env - veja .env.example)

Endpoints:
    POST <RUBEUS_WEBHOOK_PATH>   -> recebe os dados da Rubeus.
    GET  <RUBEUS_WEBHOOK_PATH>   -> health check simples (para a Rubeus testar).
    GET  /webhook/status         -> contagem de itens armazenados.
    POST /webhook/gerar          -> gera a planilha a partir dos dados recebidos.
"""
from __future__ import annotations

import sys

try:
    from flask import Flask, jsonify, request
except ImportError:  # pragma: no cover
    print(
        "ERRO: o pacote 'flask' nao esta instalado.\n"
        "Instale as dependencias com: pip install -r requirements.txt"
    )
    sys.exit(1)

from config import Config
from webhook_normalizador import classificar_lote
from webhook_store import WebhookStore


def _token_valido(cfg: Config) -> bool:
    """Valida o token compartilhado (se RUBEUS_WEBHOOK_TOKEN estiver definido).

    Aceita o token via header 'X-Webhook-Token' ou query string '?token='.
    Se nenhum token estiver configurado, nao exige autenticacao.
    """
    if not cfg.webhook_token:
        return True
    recebido = (
        request.headers.get("X-Webhook-Token")
        or request.args.get("token")
        or ""
    )
    return recebido == cfg.webhook_token


def criar_app(cfg: Config | None = None) -> "Flask":
    cfg = cfg or Config.carregar()
    store = WebhookStore(cfg.caminho(cfg.webhook_dir))
    app = Flask(__name__)
    app.config["RUBEUS_CFG"] = cfg
    app.config["RUBEUS_STORE"] = store

    def _receber():
        if not _token_valido(cfg):
            return jsonify({"success": False, "erro": "Token invalido."}), 401

        dados = request.get_json(silent=True)
        if dados is None:
            return jsonify({"success": False, "erro": "Corpo nao e um JSON valido."}), 400

        itens = dados if isinstance(dados, list) else [dados]
        grupos = classificar_lote(itens)

        gravados: dict[str, int] = {}
        for tipo, lista in grupos.items():
            if tipo == "desconhecido" or not lista:
                continue
            gravados[tipo] = store.salvar_itens(tipo, lista)

        desconhecidos = len(grupos.get("desconhecido", []))
        resposta = {
            "success": True,
            "recebidos": len(itens),
            "gravados": gravados,
            "ignorados": desconhecidos,
        }

        # Atualiza a planilha sempre que chegarem dados que afetam as linhas
        # (registros de processo) ou o conteudo delas (contatos).
        if cfg.webhook_autogerar and (gravados.get("registro") or gravados.get("contato")):
            try:
                resposta["planilha"] = _gerar_planilha(cfg, store)
            except Exception as exc:  # nao derruba o webhook se a planilha falhar
                resposta["planilha_erro"] = str(exc)

        return jsonify(resposta), 200

    @app.get("/")
    def _raiz():
        return jsonify({"servico": "Webhook Rubeus", "rota": cfg.webhook_path}), 200

    # Health check: a Rubeus (e voce) pode acessar a rota via GET para validar.
    @app.get(cfg.webhook_path)
    def _health():
        return jsonify({"success": True, "mensagem": "Webhook ativo."}), 200

    @app.post(cfg.webhook_path)
    def _post_webhook():
        return _receber()

    @app.get("/webhook/status")
    def _status():
        return jsonify({"success": True, "armazenados": store.contagens()}), 200

    @app.post("/webhook/gerar")
    def _gerar():
        if not _token_valido(cfg):
            return jsonify({"success": False, "erro": "Token invalido."}), 401
        try:
            caminho = _gerar_planilha(cfg, store)
        except Exception as exc:
            return jsonify({"success": False, "erro": str(exc)}), 500
        return jsonify({"success": True, "planilha": caminho}), 200

    return app


def _gerar_planilha(cfg: Config, store: WebhookStore) -> str:
    """Gera a planilha a partir dos dados recebidos pelo webhook."""
    from gerar_planilha import gerar_de_webhook

    return gerar_de_webhook(cfg, store)


def main(argv: list[str] | None = None) -> int:
    cfg = Config.carregar()
    app = criar_app(cfg)
    print(
        f"Webhook Rubeus ouvindo em http://{cfg.webhook_host}:{cfg.webhook_port}"
        f"{cfg.webhook_path}\n"
        f"Dados serao salvos em: {cfg.caminho(cfg.webhook_dir)}\n"
        + ("Autenticacao por token: ATIVA\n" if cfg.webhook_token else "")
        + ("Auto-geracao da planilha: ATIVA\n" if cfg.webhook_autogerar else "")
    )
    app.run(host=cfg.webhook_host, port=cfg.webhook_port)
    return 0


if __name__ == "__main__":
    sys.exit(main())
