#!/usr/bin/env python3
"""
Deploy v6 - Correcao do bug 'tela preta gigante' no fim da page 2873.

Causa raiz confirmada:
- iframe pai tem min-height: 8500px (desktop) / 13000px (mobile) como fallback.
- Quando o postMessage nao roda a tempo (ou o WP calcula body antes do resize),
  o iframe fica travado no min-height e sobra ate 3000px de preto embaixo.
- No mobile o script funciona (recebi 47 mensagens no polling) mas ainda sobra ~150px
  porque body do WP > iframe interno por causa de chrome do The7 (single-share-box,
  ~24px cada, mais o padding do #page).

Fix aplicado:
1. Iframe comeca com height=800px (nao min-height gigante).
2. Script filho manda resize continuo + responde a probe do pai.
3. Script pai:
   a. Escuta o resize e atualiza iframe.style.height (com padding menor: +2px em vez de +10)
   b. Faz polling defensivo: envia probe pro iframe a cada 500ms nos primeiros 6s.
   c. Se apos 4s ainda estiver em <1000px, fallback pra 8500 desktop / 13000 mobile
      (comportamento antigo, mas so como ultima linha de defesa).
4. Fallback CSS removido: min-height so 800px. Se resize falhar completamente,
   apenas fica pequeno em vez de gigante preto.
5. Escondendo tambem .single-share-box e .share-link-description (~24px cada,
   apareceram fora do wrap no diagnostico).
"""
import os
import html
import json
import subprocess
import time
from datetime import datetime
from pathlib import Path

BASE = Path("/opt/mia/workspace/clientes/px3lab/site_produtos/server_photorf/site")
INDEX = BASE / "index.html"
BACKUPS = Path("/opt/mia/workspace/clientes/px3lab/backups")
ENV = Path("/opt/mia/config/px3lab_wordpress/.env")

# Carrega env
env = {}
for line in ENV.read_text().splitlines():
    line = line.strip()
    if not line or line.startswith("#"):
        continue
    k, _, v = line.partition("=")
    env[k.strip()] = v.strip().strip("'").strip('"')

WP_URL = env["WP_URL"]
WP_USER = env["WP_USER"]
WP_APP_PASSWORD = env["WP_APP_PASSWORD"]

# 1. Backup do estado atual
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_json = BACKUPS / f"wp_page_2873_pre_v6_black_fix_{ts}.json"
print(f"[1/6] Backup do estado atual em {backup_json}")
r = subprocess.run([
    "curl", "-s", "-u", f"{WP_USER}:{WP_APP_PASSWORD}",
    f"{WP_URL}/wp-json/wp/v2/pages/2873?context=edit"
], capture_output=True, text=True, check=True)
data = json.loads(r.stdout)
backup_json.write_text(json.dumps(data, indent=2, ensure_ascii=False))
print(f"   OK - backup salvo ({len(r.stdout)} bytes)")

# 2. Le HTML local + injeta script postMessage do filho
print(f"[2/6] Lendo {INDEX}")
raw = INDEX.read_text()

# Script filho v3: mede altura ignorando elementos position:fixed
# (o botao WhatsApp fixed estava inflando documentElement.scrollHeight em 386px no viewport 375)
child_script = """<script>(function(){
  if(window.parent===window)return;
  var lastH=0;
  function measure(){
    // Percorre TODOS elementos visiveis dentro do body, ignora position:fixed,
    // acha o maior bottom real
    var maxBottom=0;
    var all=document.body.getElementsByTagName("*");
    for(var i=0;i<all.length;i++){
      var el=all[i];
      var cs=getComputedStyle(el);
      if(cs.position==="fixed"||cs.display==="none"||cs.visibility==="hidden")continue;
      var r=el.getBoundingClientRect();
      if(r.height<1)continue;
      var b=r.top+window.scrollY+r.height;
      if(b>maxBottom)maxBottom=b;
    }
    // fallback: pelo menos body.scrollHeight
    var bodyH=document.body.scrollHeight;
    return Math.max(Math.ceil(maxBottom),bodyH);
  }
  function send(){
    var h=measure();
    if(Math.abs(h-lastH)>3){
      lastH=h;
      try{window.parent.postMessage({type:"serverphotorf:resize",height:h},"*");}catch(e){}
    }
  }
  window.addEventListener("DOMContentLoaded",send);
  window.addEventListener("load",function(){
    send();
    [100,300,600,1000,1500,2500,4000,6000].forEach(function(t){setTimeout(send,t);});
  });
  window.addEventListener("resize",send);
  if(window.ResizeObserver){new ResizeObserver(send).observe(document.body);}
  window.addEventListener("message",function(ev){
    if(ev.data&&ev.data.type==="serverphotorf:probe"){
      lastH=0;
      send();
    }
  });
})();</script>"""

if "serverphotorf:resize" not in raw:
    if "</body>" in raw:
        raw = raw.replace("</body>", child_script + "\n</body>", 1)
    else:
        raw = raw + child_script
    print(f"   OK - script filho injetado")
else:
    # substitui o script antigo se existir (pra caso o local ja tenha uma versao)
    print(f"   OK - script filho ja presente (nao mexi)")

# 3. Escapa HTML pra caber dentro do srcdoc
print(f"[3/6] Escapando HTML pra srcdoc")
srcdoc = html.escape(raw, quote=True)
print(f"   OK - HTML escaped ({len(srcdoc)} chars)")

# 4. Monta wrapper com CSS de override + iframe + script pai
print(f"[4/6] Montando wrapper WordPress")

# CSS de override: esconde chrome do The7, forca #page/#main/#content full-width.
# Adicionei .single-share-box e .share-link-description (apareceram no diagnostico).
# Reduzi iframe min-height de 8500/13000 pra 800 (fallback minimo).
override_style = """<style id="sphotorf-theme-override">body.page-id-2873 .masthead,body.page-id-2873 #masthead,body.page-id-2873 #footer,body.page-id-2873 .footer,body.page-id-2873 .page-title,body.page-id-2873 .breadcrumbs,body.page-id-2873 #sidebar,body.page-id-2873 aside#sidebar,body.page-id-2873 .sidebar,body.page-id-2873 .mobile-header,body.page-id-2873 .dt-back-to-top,body.page-id-2873 .share-buttons,body.page-id-2873 .post-share,body.page-id-2873 .share-title,body.page-id-2873 .entry-share,body.page-id-2873 .single-share,body.page-id-2873 .single-share-box,body.page-id-2873 .share-link-description,body.page-id-2873 .page-share,body.page-id-2873 .post-nav,body.page-id-2873 .post-comments,body.page-id-2873 .comments-area,body.page-id-2873 .related-posts,body.page-id-2873 .author-bio,body.page-id-2873 .gif_whatsapp{display:none!important;visibility:hidden!important;height:0!important;width:0!important;overflow:hidden!important;margin:0!important;padding:0!important}body.page-id-2873 #main.sidebar-right,body.page-id-2873 #main.sidebar-left,body.page-id-2873 #main{display:block!important;grid-template-columns:none!important;grid-template-areas:none!important;gap:0!important}body.page-id-2873 .sidebar-content{display:block!important;grid-template-columns:none!important}body.page-id-2873 #page,body.page-id-2873 #main,body.page-id-2873 #content,body.page-id-2873 .sidebar-content,body.page-id-2873 .content,body.page-id-2873 .entry-content,body.page-id-2873 article.post-2873,body.page-id-2873 article,body.page-id-2873 .post-2873,body.page-id-2873 .hentry,body.page-id-2873 .wf-wrap,body.page-id-2873 .wf-container,body.page-id-2873 .wf-container-main,body.page-id-2873 .wf-td,body.page-id-2873 .dt-css-grid{max-width:100%!important;width:100%!important;min-width:0!important;padding:0!important;margin:0!important;background:#000!important;flex:1 1 100%!important;grid-column:1/-1!important}body.page-id-2873{overflow-x:hidden!important;background:#000!important}body.page-id-2873 #page{background:#000!important;padding:0!important;margin:0!important}body.page-id-2873 #main{padding:0!important;margin:0!important}.sphotorf-wrap{margin:0!important;padding:0!important;width:100%!important;background:#000!important;line-height:0!important;font-size:0!important}.sphotorf-wrap iframe{display:block!important;width:100%!important;border:0!important;height:800px;background:#000!important;line-height:0!important;font-size:0!important}</style>"""

# Script pai v2: escuta resize + probe defensivo + fallback controlado
parent_script = """<script>(function(){
  var f=document.getElementById("sphotorf-frame");
  if(!f)return;
  var isMobile=window.matchMedia("(max-width:768px)").matches;
  var lastReported=0;
  // Aplica altura ao iframe quando recebe resize
  window.addEventListener("message",function(ev){
    var d=ev.data;
    if(d&&d.type==="serverphotorf:resize"&&typeof d.height==="number"&&d.height>200){
      lastReported=d.height;
      f.style.height=(d.height+2)+"px";
    }
  });
  // Probe defensivo: envia sinal pro iframe a cada 500ms nos primeiros 6s
  function probe(){
    try{f.contentWindow.postMessage({type:"serverphotorf:probe"},"*");}catch(e){}
  }
  var probeCount=0;
  var probeInterval=setInterval(function(){
    probeCount++;
    probe();
    if(probeCount>=12){clearInterval(probeInterval);}
  },500);
  // Fallback: se apos 4s nao houve nenhum resize valido, aplica fallback conservador
  setTimeout(function(){
    if(lastReported<200){
      f.style.height=isMobile?"13000px":"8500px";
    }
  },4000);
  // Reprobe em resize da janela (rotate mobile, etc)
  window.addEventListener("resize",function(){
    setTimeout(probe,200);
  });
})();</script>"""

wrapper = f'{override_style}<div class="sphotorf-wrap"><iframe id="sphotorf-frame" srcdoc="{srcdoc}" title="Server PhotoRF" loading="eager" scrolling="no"></iframe></div>{parent_script}'
print(f"   OK - wrapper montado ({len(wrapper)} chars)")

# 5. PUT no WP com headers de browser (mod_security ja bloqueou requests sem)
print(f"[5/6] PUT em /wp-json/wp/v2/pages/2873")
payload = json.dumps({"content": wrapper}, ensure_ascii=False)
payload_file = "/tmp/page_2873_v6_payload.json"
with open(payload_file, "w") as fh:
    fh.write(payload)

r = subprocess.run([
    "curl", "-s", "-w", "\n---HTTP:%{http_code}\n",
    "-u", f"{WP_USER}:{WP_APP_PASSWORD}",
    "-X", "PUT",
    "-H", "Content-Type: application/json",
    "-H", "Accept: application/json",
    "-H", "Origin: https://www.px3lab.com.br",
    "-H", "Referer: https://www.px3lab.com.br/wp-admin/post.php?post=2873&action=edit",
    "-H", "X-Requested-With: XMLHttpRequest",
    "-H", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0 Safari/537.36",
    "--data-binary", f"@{payload_file}",
    f"{WP_URL}/wp-json/wp/v2/pages/2873"
], capture_output=True, text=True)
print(f"   {r.stdout[-200:]}")
if "HTTP:200" not in r.stdout:
    print("   ERRO no PUT!")
    print(r.stdout)
    print(r.stderr)
    raise SystemExit(1)
print(f"   OK - PUT 200")

# 6. Sanity check
print(f"[6/6] Sanity check - leitura pos-deploy")
time.sleep(2)
r = subprocess.run([
    "curl", "-s", "-u", f"{WP_USER}:{WP_APP_PASSWORD}",
    f"{WP_URL}/wp-json/wp/v2/pages/2873?context=edit"
], capture_output=True, text=True, check=True)
data = json.loads(r.stdout)
new_raw = data["content"]["raw"]
if "serverphotorf:probe" in new_raw and "single-share-box" in new_raw and "height:800px" in new_raw:
    print("   OK - v6 confirmado no WP")
else:
    print("   ATENCAO - v6 NAO confirmado")
    print(f"   probe presente: {'serverphotorf:probe' in new_raw}")
    print(f"   single-share-box: {'single-share-box' in new_raw}")
    print(f"   height:800px: {'height:800px' in new_raw}")

print()
print(f"Deploy v6 concluido. URL: {WP_URL}/server-photorf/")
