import os
import json
import logging
from pathlib import Path

import httpx
from dotenv import load_dotenv
from fastapi import FastAPI, Request

# ---------------------------------------------------------------------
# Inicialização
# ---------------------------------------------------------------------
BASE_DIR = Path(__file__).resolve().parent
load_dotenv(dotenv_path=BASE_DIR / ".env", override=True)

INST_ID      = os.getenv("ZAPI_INSTANCE_ID")
INST_TOKEN   = os.getenv("ZAPI_INSTANCE_TOKEN")
SECURITY_TK  = os.getenv("ZAPI_CLIENT_TOKEN")
OPENAI_KEY   = os.getenv("OPENAI_API_KEY")
OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-3.5-turbo")

SEND_ENDPOINT = (
    f"https://api.z-api.io/instances/{INST_ID}/token/{INST_TOKEN}/send-text"
    if INST_ID and INST_TOKEN else None
)

logging.basicConfig(level=logging.INFO, format="%(levelname)s:%(name)s:%(message)s")
logger = logging.getLogger("main")

app = FastAPI()

# ---------------------------------------------------------------------
# Utilitários
# ---------------------------------------------------------------------
def ler_regras():
    try:
        regras = (BASE_DIR / "regras.txt").read_text(encoding="utf-8")
        logger.info("📜 Regras carregadas:\n%s", regras)
        return regras
    except Exception as e:
        logger.error("Erro ao ler regras.txt: %s", e)
        return "Não consegui acessar as regras agora."

    )
    async with httpx.AsyncClient() as cli:
        r = await cli.post(
            "https://api.openai.com/v1/chat/completions",
            headers={"Authorization": f"Bearer {OPENAI_KEY}"},
            json={"model": OPENAI_MODEL, "messages": [{"role": "user", "content": prompt}]},
            timeout=30,
        )
        r.raise_for_status()
        return r.json()["choices"][0]["message"]["content"].strip()

async def enviar_whats(phone: str, texto: str):
    if not SEND_ENDPOINT:
        raise RuntimeError("SEND_ENDPOINT não configurado")

    payload = {"phone": phone, "message": texto}
    async with httpx.AsyncClient() as cli:
        r = await cli.post(
            SEND_ENDPOINT,
            headers={
                "Client-Token": SECURITY_TK,
                "Content-Type": "application/json",
            },
            json=payload,
            timeout=30,
        )
        if r.status_code == 404 and "Instance not found" in r.text:
            logger.error("❗ Z-API: instância não existe ou está inativa. Verifique ID e TOKEN.")
        r.raise_for_status()

# ---------------------------------------------------------------------
# Webhook principal
# ---------------------------------------------------------------------
@app.post("/webhook")
async def webhook(req: Request):
    client_host = req.client.host
    method = req.method
    headers = dict(req.headers)

    raw_body = await req.body()
    if not raw_body or raw_body.strip() == b"":
        logger.debug("🔁 Ignorado: corpo vazio (provável ping HTTP/2)")
        return {"status": "ignorado"}

    logger.info("📥 Nova requisição: %s %s", method, client_host)
    logger.info("📄 Headers: %s", json.dumps(headers, indent=2))
    logger.info("📦 Body (raw): %s", raw_body)

    try:
        data = await req.json()

        # ✅ Ignora mensagens enviadas por você mesmo (evita loop)
        if data.get("fromMe") is True or data.get("fromApi") is True:
            logger.info("🔁 Ignorado: mensagem enviada por mim mesmo.")
            return {"status": "ignorado"}

        # ✅ Verifica se é mensagem recebida
        if data.get("type") != "ReceivedCallback":
            logger.info("⚠️ Ignorado: tipo não é 'ReceivedCallback' (%s)", data.get("type"))
            return {"status": "ignorado"}

        phone = data.get("phone")
        msg = data.get("text", {}).get("message")

        if not phone or not msg:
            logger.warning("⚠️ Payload incompleto: %s", data)
            return {"status": "ignorado"}

        logger.info("📩 [%s] %s", phone, msg)

        resposta = await gpt_resposta(msg, ler_regras())
        logger.info("✅ GPT: %s", resposta)

        await enviar_whats(phone, resposta)
        return {"status": "ok", "mensagem": resposta}

    except Exception as e:
        logger.exception("❌ Erro no webhook: %s", e)
        return {"status": "erro", "detalhe": str(e)}
