#!/usr/bin/env python3
"""
postar_30posts.py — Publica os 30 posts layout padrão no Instagram via Graph API.

Uso:
    python3 postar_30posts.py --proximo                  # Posta o próximo pendente
    python3 postar_30posts.py --post 5                   # Posta post específico
    python3 postar_30posts.py --status                   # Mostra status
    python3 postar_30posts.py --post 5 --simulacao       # Simula sem postar
"""

import argparse
import json
import sys
import time
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"
POSTS_FILE = SCRIPT_DIR / "30-posts-layout-padrao.json"
LOG_PATH = SCRIPT_DIR / "log-30posts.json"

BASE_URL = "https://gateway.saraiva.ai/insta-public/30posts-v2"


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


def carregar_log():
    if LOG_PATH.exists():
        with open(LOG_PATH, "r", encoding="utf-8") as f:
            try:
                return json.load(f)
            except json.JSONDecodeError:
                return {"postados": [], "erros": []}
    return {"postados": [], "erros": []}


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


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


def ja_postado(log, post_num):
    for p in log["postados"]:
        if p["post"] == post_num:
            return True
    return False


def url_imagem(post_num):
    return f"{BASE_URL}/post-{post_num:02d}.png"


def postar_graph_api(image_url, caption, config):
    access_token = config.get("instagram_access_token", "")
    account_id = config.get("instagram_business_account_id", "")

    if not access_token or not account_id:
        return False, "Graph API nao configurada em config.json"

    # Passo 1: Criar container
    try:
        params = urllib.parse.urlencode({
            "image_url": image_url,
            "caption": caption,
            "access_token": access_token
        })
        url = f"https://graph.facebook.com/v18.0/{account_id}/media?{params}"
        req = urllib.request.Request(url, method="POST")
        with urllib.request.urlopen(req, timeout=30) as resp:
            data = json.loads(resp.read().decode("utf-8"))
            container_id = data.get("id")

        if not container_id:
            return False, f"Falha ao criar container: {data}"
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", errors="replace")
        return False, f"Erro HTTP container: {e.code} - {body}"
    except Exception as e:
        return False, f"Erro container: {e}"

    # Aguardar processamento do container
    import time as _time
    for attempt in range(6):
        _time.sleep(10)
        try:
            status_url = f"https://graph.facebook.com/v18.0/{container_id}?fields=status_code&access_token={access_token}"
            req_s = urllib.request.Request(status_url)
            with urllib.request.urlopen(req_s, timeout=15) as resp_s:
                status_data = json.loads(resp_s.read().decode("utf-8"))
                status_code = status_data.get("status_code", "")
                if status_code == "FINISHED":
                    break
                print(f"    Container status: {status_code} (tentativa {attempt+1}/6)")
        except Exception:
            pass

    # Passo 2: Publicar
    try:
        params = urllib.parse.urlencode({
            "creation_id": container_id,
            "access_token": access_token
        })
        url = f"https://graph.facebook.com/v18.0/{account_id}/media_publish?{params}"
        req = urllib.request.Request(url, method="POST")
        with urllib.request.urlopen(req, timeout=30) as resp:
            data = json.loads(resp.read().decode("utf-8"))
            media_id = data.get("id")

        if media_id:
            return True, f"Media ID: {media_id}"
        else:
            return False, f"Resposta inesperada: {data}"
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", errors="replace")
        return False, f"Erro HTTP publish: {e.code} - {body}"
    except Exception as e:
        return False, f"Erro publish: {e}"


def postar_um(post_num, config, log, simulacao=False):
    posts = carregar_posts()
    post_data = None
    for p in posts:
        if p["post"] == post_num:
            post_data = p
            break

    if not post_data:
        print(f"[ERRO] Post {post_num} nao encontrado")
        return False

    image_url = url_imagem(post_num)
    caption = post_data["caption"]

    print(f"\n  Post {post_num}/30: {post_data['frase'][:60]}...")
    print(f"  Imagem: {image_url}")
    print(f"  Caption: {len(caption)} chars")

    if simulacao:
        print(f"  [SIMULACAO] Post simulado com sucesso")
        return True

    sucesso, detalhes = postar_graph_api(image_url, caption, config)

    registro = {
        "post": post_num,
        "frase": post_data["frase"],
        "timestamp": datetime.now().isoformat(),
        "detalhes": detalhes
    }

    if sucesso:
        log["postados"].append(registro)
        salvar_log(log)
        print(f"  [OK] Publicado! {detalhes}")
    else:
        registro["erro"] = detalhes
        log["erros"].append(registro)
        salvar_log(log)
        print(f"  [FALHA] {detalhes}")

    return sucesso


def mostrar_status(log):
    posts = carregar_posts()
    print(f"\n{'='*60}")
    print(f"  STATUS 30 POSTS — @saraiva.ai")
    print(f"{'='*60}")

    for p in posts:
        postado = ja_postado(log, p["post"])
        status = "OK" if postado else "  "
        print(f"  [{status}] Post {p['post']:02d}: {p['frase'][:55]}...")

    total = len(log["postados"])
    print(f"\n  Total postados: {total}/30")
    print(f"  Erros: {len(log['erros'])}")
    print(f"{'='*60}")


def proximo_pendente(log):
    posts = carregar_posts()
    for p in posts:
        if not ja_postado(log, p["post"]):
            return p["post"]
    return None


def main():
    parser = argparse.ArgumentParser(description="Postar 30 posts @saraiva.ai")
    parser.add_argument("--post", "-p", type=int, help="Post especifico (1-30)")
    parser.add_argument("--proximo", action="store_true", help="Posta o proximo pendente")
    parser.add_argument("--status", action="store_true", help="Mostra status")
    parser.add_argument("--simulacao", action="store_true", help="Simula sem postar")

    args = parser.parse_args()
    config = carregar_config()
    log = carregar_log()

    if args.status:
        mostrar_status(log)
        return

    if args.proximo:
        post_num = proximo_pendente(log)
        if post_num is None:
            print("Todos os 30 posts ja foram publicados!")
            return
        print(f"Proximo pendente: Post {post_num}")
        postar_um(post_num, config, log, args.simulacao)
        return

    if args.post:
        if ja_postado(log, args.post):
            print(f"Post {args.post} ja foi postado. Use --status para ver.")
            return
        postar_um(args.post, config, log, args.simulacao)
        return

    parser.print_help()


if __name__ == "__main__":
    main()
