#!/usr/bin/env python3
"""
automacao_cta_claude.py — Automação completa de CTA para @saraiva.ai

Quando alguém comenta uma palavra-chave (ex: "CLAUDE", "IA") em um post:
1. Responde o comentário publicamente (engajamento)
2. Envia DM com conteúdo prometido (tutorial, PDF, etc.)
3. Loga tudo para acompanhamento

Roda via cron a cada 3-5 minutos.
"""

import json
import sys
import time
import random
import urllib.request
import urllib.parse
import urllib.error
from datetime import datetime
from pathlib import Path

SCRIPT_DIR = Path(__file__).parent.resolve()
CONFIG_PATH = SCRIPT_DIR / "config.json"
LOG_PATH = SCRIPT_DIR / "log-cta-claude.json"
CTA_CONFIG_PATH = SCRIPT_DIR / "cta-config.json"

# ═══════════════════════════════════════════════════════════════
# CONFIGURAÇÃO DOS CTAs
# ═══════════════════════════════════════════════════════════════

# Config padrão (pode ser sobrescrita por cta-config.json)
CTA_DEFAULT = {
    "triggers": {
        "CLAUDE": {
            "keywords": ["claude", "CLAUDE", "Claude"],
            "resposta_publica": [
                "Mandei no seu direct! 🔥 Confere lá que tem tudo explicado passo a passo.",
                "Já enviei no DM! 💬 Abre lá que tá tudo detalhado pra você configurar.",
                "Boa! Acabei de mandar no seu direct. Qualquer dúvida me chama lá. 🤝",
                "Enviado! 🎯 Corre no direct que o passo a passo tá te esperando.",
                "Pronto! Mandei tudo no DM. Segue o tutorial e qualquer dúvida é só chamar. 💬",
            ],
            "fallback_publica": [
                "@{username} Boa! Pra configurar: 1) instala Claude Code (npm install -g @anthropic-ai/claude-code) 2) roda 'claude' no terminal 3) pede pra ele criar seus posts. Me chama no DM se travar em algum passo! 🤝",
                "@{username} Show! O caminho: instala o Claude Code, abre o terminal e pede 'crie 30 posts sobre [seu nicho]'. Ele faz tudo. Qualquer dúvida, DM aberto! 🔥",
                "@{username} Vamo! Passo rápido: npm install -g @anthropic-ai/claude-code → abre terminal → 'claude' → pede seus posts. Simples assim. Me chama no DM pra eu te ajudar ao vivo! 💬",
            ],
            "dm_mensagens": [
                {
                    "texto": "Fala! Vi que você comentou CLAUDE no post. 🔥\n\nComo prometido, aqui vai o passo a passo pra automatizar seu Instagram inteiro com Claude Code:"
                },
                {
                    "texto": "📋 PASSO A PASSO — Claude Code + Instagram:\n\n1️⃣ Instala o Claude Code: npm install -g @anthropic-ai/claude-code\n\n2️⃣ Configura sua API key da Anthropic (anthropic.com)\n\n3️⃣ No terminal, roda: claude\n\n4️⃣ Pede pra ele: \"Cria 30 posts sobre [seu nicho] pro Instagram com legendas, hashtags e agendamento\"\n\n5️⃣ Ele gera tudo: imagens, textos, hashtags otimizadas\n\n6️⃣ Conecta com a API do Instagram pra postar automaticamente"
                },
                {
                    "texto": "💡 Dica extra: você pode pedir pro Claude Code criar um script que posta automaticamente todos os dias no horário que você quiser.\n\nEu uso isso no meu perfil e funciona 24/7.\n\nQuer saber mais sobre como eu automatizei minha operação inteira? Me manda uma mensagem aqui que eu te explico. 🤝"
                }
            ]
        },
        "IA": {
            "keywords": ["ia", "IA", "I.A.", "i.a.", "inteligencia artificial", "inteligência artificial"],
            "resposta_publica": [
                "Mandei o tutorial completo no seu DM! 🔥 Confere lá.",
                "Boa! Te mandei tudo no direct. Abre lá! 💬",
                "Enviado no DM! 🎯 Segue o passo a passo e qualquer coisa me chama.",
            ],
            "fallback_publica": [
                "@{username} As ferramentas que uso: Claude Code (automação de posts), Gemini (imagens com IA), Python + API do Instagram (agendamento). Tudo no terminal, zero mensalidade. Me chama no DM que te explico! 🤝",
                "@{username} Meu stack: Claude Code pra conteúdo, Gemini pra imagens, scripts Python pra postar automaticamente. Me manda DM que eu detalho tudo! 🔥",
            ],
            "dm_mensagens": [
                {
                    "texto": "Fala! Vi seu comentário sobre IA. 🔥\n\nAqui vai o que eu uso pra automatizar tudo:\n\n🤖 Claude Code — automatiza posts, legendas, hashtags, agendamento\n🎨 Gemini — gera imagens pro feed\n📊 Scripts Python — postagem automática via API\n\nTudo roda no terminal, sem plataforma cara, sem mensalidade."
                },
                {
                    "texto": "Quer que eu te explique como configurar na prática? Me manda \"QUERO\" aqui no direct. 🤝"
                }
            ]
        }
    }
}


def load_config():
    with open(CONFIG_PATH, "r", encoding="utf-8") as f:
        return json.load(f)


def load_cta_config():
    if CTA_CONFIG_PATH.exists():
        with open(CTA_CONFIG_PATH, "r", encoding="utf-8") as f:
            return json.load(f)
    # Salva config padrão para facilitar edição futura
    with open(CTA_CONFIG_PATH, "w", encoding="utf-8") as f:
        json.dump(CTA_DEFAULT, f, ensure_ascii=False, indent=2)
    return CTA_DEFAULT


def load_log():
    if LOG_PATH.exists():
        try:
            with open(LOG_PATH, "r", encoding="utf-8") as f:
                return json.load(f)
        except json.JSONDecodeError:
            pass
    return {"processados": [], "stats": {"total_respostas": 0, "total_dms": 0, "total_falhas_dm": 0}}


def save_log(log):
    with open(LOG_PATH, "w", encoding="utf-8") as f:
        json.dump(log, f, ensure_ascii=False, indent=2)


# ═══════════════════════════════════════════════════════════════
# API HELPERS
# ═══════════════════════════════════════════════════════════════

def api_get(endpoint, params, token):
    params["access_token"] = token
    url = f"https://graph.facebook.com/v21.0/{endpoint}?{urllib.parse.urlencode(params)}"
    try:
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=30) as resp:
            return json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", errors="replace")
        print(f"  [ERRO GET {e.code}] {endpoint}: {body[:300]}", file=sys.stderr)
        return None
    except Exception as e:
        print(f"  [ERRO] {e}", file=sys.stderr)
        return None


def api_post(endpoint, params, token):
    params["access_token"] = token
    data = urllib.parse.urlencode(params).encode()
    url = f"https://graph.facebook.com/v21.0/{endpoint}"
    try:
        req = urllib.request.Request(url, data=data, method="POST")
        with urllib.request.urlopen(req, timeout=30) as resp:
            return json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", errors="replace")
        print(f"  [ERRO POST {e.code}] {endpoint}: {body[:300]}", file=sys.stderr)
        return None
    except Exception as e:
        print(f"  [ERRO] {e}", file=sys.stderr)
        return None


def api_post_json(endpoint, payload, token, base_url="https://graph.facebook.com/v21.0"):
    """POST com body JSON (para messaging API)."""
    url = f"{base_url}/{endpoint}?access_token={token}"
    data = json.dumps(payload).encode()
    try:
        req = urllib.request.Request(url, data=data, method="POST",
                                     headers={"Content-Type": "application/json"})
        with urllib.request.urlopen(req, timeout=30) as resp:
            return json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", errors="replace")
        print(f"  [ERRO POST JSON {e.code}] {endpoint}: {body[:300]}", file=sys.stderr)
        return None
    except Exception as e:
        print(f"  [ERRO] {e}", file=sys.stderr)
        return None


# ═══════════════════════════════════════════════════════════════
# CORE FUNCTIONS
# ═══════════════════════════════════════════════════════════════

def get_page_access_token(config):
    """Obtém Page Access Token a partir do User Access Token."""
    page_id = config.get("facebook_page_id")
    if not page_id:
        print("  [ERRO] facebook_page_id não configurado", file=sys.stderr)
        return None

    result = api_get(f"{page_id}", {"fields": "access_token"}, config["instagram_access_token"])
    if result and "access_token" in result:
        return result["access_token"]
    return None


def obter_posts_recentes(config):
    result = api_get(f"{config['instagram_business_account_id']}/media", {
        "fields": "id,caption,timestamp,comments_count",
        "limit": 10
    }, config["instagram_access_token"])
    if result and "data" in result:
        return result["data"]
    return []


def obter_comentarios(media_id, config):
    result = api_get(f"{media_id}/comments", {
        "fields": "id,text,username,timestamp,from",
        "limit": 100
    }, config["instagram_access_token"])
    if result and "data" in result:
        return result["data"]
    return []


def detectar_trigger(texto, triggers):
    """Detecta se o comentário contém alguma keyword de CTA.
    Retorna (trigger_name, trigger_config) ou (None, None).

    Matching rigoroso: a keyword deve ser uma palavra isolada ou o comentário inteiro.
    Evita falsos positivos como 'secretarIA' matchando 'IA'.
    """
    import re
    texto_clean = texto.strip()
    texto_lower = texto_clean.lower()

    for trigger_name, trigger_cfg in triggers.items():
        for keyword in trigger_cfg["keywords"]:
            kw_lower = keyword.lower()
            # Comentário é exatamente a keyword
            if texto_lower == kw_lower:
                return trigger_name, trigger_cfg
            # Keyword como palavra isolada (word boundary)
            pattern = r'\b' + re.escape(kw_lower) + r'\b'
            if re.search(pattern, texto_lower):
                return trigger_name, trigger_cfg

    return None, None


def responder_comentario(comment_id, mensagem, config):
    """Responde publicamente a um comentário."""
    result = api_post(f"{comment_id}/replies", {
        "message": mensagem
    }, config["instagram_access_token"])
    return result is not None


def enviar_dm_instagram_legacy(user_id, mensagem, page_token):
    """Fallback: envia DM via Facebook Page Token (requer advanced access)."""
    payload = {
        "recipient": {"id": user_id},
        "message": {"text": mensagem}
    }
    result = api_post_json("me/messages", payload, page_token)
    return result is not None


def enviar_dm_instagram(user_id, mensagem, ig_token, ig_account_id):
    """Envia DM via Instagram API (novo endpoint com token IG).
    user_id = Instagram-scoped user ID (IGSID) do campo 'from.id' do comentário.
    ig_account_id = ID da conta IG do remetente (26527672413485308 para saraiva.ai).
    """
    payload = {
        "recipient": {"id": user_id},
        "message": {"text": mensagem}
    }
    result = api_post_json(
        f"{ig_account_id}/messages", payload, ig_token,
        base_url="https://graph.instagram.com/v21.0"
    )
    return result is not None


def processar():
    config = load_config()
    cta_config = load_cta_config()
    log = load_log()
    triggers = cta_config.get("triggers", {})

    processados_ids = set(r["comment_id"] for r in log["processados"])

    # Token IG para DMs (novo Instagram API)
    ig_token = config.get("instagram_ig_token")
    ig_account_id = config.get("instagram_ig_account_id")
    if ig_token and ig_account_id:
        print(f"  ✓ IG Token configurado (account: {ig_account_id})")
    else:
        print("  ⚠ IG Token não configurado — tentando Page Token como fallback...")
        ig_token = None
        page_token = get_page_access_token(config)
        if page_token:
            print("  ✓ Page Token obtido (fallback)")
        else:
            print("  ⚠ Nenhum token de DM disponível")

    posts = obter_posts_recentes(config)
    if not posts:
        print("Nenhum post encontrado.")
        return

    total_respostas = 0
    total_dms = 0
    total_falhas = 0

    for post in posts:
        media_id = post["id"]
        caption = (post.get("caption") or "")[:80]
        comments_count = post.get("comments_count", 0)

        if comments_count == 0:
            continue

        comentarios = obter_comentarios(media_id, config)

        for comment in comentarios:
            comment_id = comment["id"]
            if comment_id in processados_ids:
                continue

            username = comment.get("username", "")
            texto = comment.get("text", "")
            user_from = comment.get("from", {})
            user_id = user_from.get("id")

            # Não responder a si mesmo
            if username == "saraiva.ai":
                continue

            # Detectar se é um trigger de CTA
            trigger_name, trigger_cfg = detectar_trigger(texto, triggers)
            if not trigger_name:
                continue

            print(f"\n  🎯 TRIGGER '{trigger_name}' detectado!")
            print(f"     @{username}: \"{texto}\"")
            print(f"     Post: {caption}...")

            # 1. RESPOSTA PÚBLICA
            resposta = random.choice(trigger_cfg["resposta_publica"])
            resp_ok = responder_comentario(comment_id, resposta, config)

            if resp_ok:
                print(f"     ✓ Resposta pública enviada")
                total_respostas += 1
            else:
                print(f"     ✗ Falha na resposta pública")

            # 2. ENVIAR DM
            dm_ok = False
            has_dm = bool(ig_token and ig_account_id) or bool(not ig_token and locals().get('page_token'))
            if has_dm and user_id:
                print(f"     Enviando DM para IGSID {user_id}...")
                for i, dm_msg in enumerate(trigger_cfg["dm_mensagens"]):
                    dm_texto = dm_msg["texto"]
                    if ig_token:
                        result = enviar_dm_instagram(user_id, dm_texto, ig_token, ig_account_id)
                    else:
                        result = enviar_dm_instagram_legacy(user_id, dm_texto, page_token)
                    if result:
                        print(f"     ✓ DM {i+1}/{len(trigger_cfg['dm_mensagens'])} enviada")
                        dm_ok = True
                    else:
                        print(f"     ✗ DM {i+1} falhou")
                        if i == 0:
                            print(f"     ⚠ DM API indisponível — usando resposta pública expandida")
                            break
                    if i < len(trigger_cfg["dm_mensagens"]) - 1:
                        time.sleep(2)

                if dm_ok:
                    total_dms += 1

            # 3. FALLBACK: se DM falhou, manda conteúdo resumido como resposta pública
            if not dm_ok:
                total_falhas += 1
                fallback_list = trigger_cfg.get("fallback_publica")
                if fallback_list:
                    print(f"     Enviando fallback público...")
                    fallback_msg = random.choice(fallback_list).replace("{username}", username)
                    fb_ok = responder_comentario(comment_id, fallback_msg, config)
                    if fb_ok:
                        print(f"     ✓ Fallback público enviado")
                    else:
                        print(f"     ✗ Fallback falhou")

            # 3. REGISTRAR NO LOG
            registro = {
                "comment_id": comment_id,
                "media_id": media_id,
                "username": username,
                "user_id": user_id,
                "texto": texto,
                "trigger": trigger_name,
                "resposta_publica": resposta,
                "dm_enviada": dm_ok,
                "timestamp": datetime.now().isoformat()
            }
            log["processados"].append(registro)
            processados_ids.add(comment_id)

            # Rate limit
            time.sleep(3)

    # Atualizar stats
    log["stats"]["total_respostas"] += total_respostas
    log["stats"]["total_dms"] += total_dms
    log["stats"]["total_falhas_dm"] += total_falhas
    log["stats"]["ultima_execucao"] = datetime.now().isoformat()

    save_log(log)

    print(f"\n{'='*50}")
    print(f"RESUMO:")
    print(f"  Respostas públicas: {total_respostas}")
    print(f"  DMs enviadas: {total_dms}")
    print(f"  DMs falharam: {total_falhas}")
    print(f"  Total histórico: {log['stats']['total_respostas']} respostas, {log['stats']['total_dms']} DMs")
    print(f"{'='*50}")


if __name__ == "__main__":
    print(f"{'='*50}")
    print(f"CTA AUTO-RESPONDER @saraiva.ai | {datetime.now().strftime('%d/%m/%Y %H:%M')}")
    print(f"{'='*50}")
    processar()
