# -*- coding: utf-8 -*-
"""封面图上传（强制显示file input后注入）"""
import sys, socket, json, time, base64, os, glob
from base64 import b64encode
sys.stdout.reconfigure(encoding='utf-8')
HOST = "localhost"; PORT = 28800
PAGE_ID = "70039F329097C14448996F189E3A42A1"

# 读图片
IMG_LIST = glob.glob(r'D:\wxpic\*.jpg') + glob.glob(r'D:\wxpic\*.png')
IMG_PATH = max(IMG_LIST, key=os.path.getmtime) if IMG_LIST else None
if not IMG_PATH:
    print("[ERROR] 没有找到图片")
    sys.exit(1)
with open(IMG_PATH, 'rb') as f:
    IMG_B64 = b64encode(f.read()).decode()
ext = os.path.splitext(IMG_PATH)[1].lower()
IMG_MIME = 'image/jpeg' if ext in ['.jpg','.jpeg'] else 'image/png'
print("[INFO] 图片:", IMG_PATH, "大小:", len(IMG_B64))

def ws():
    import urllib.parse
    u = "ws://%s:%s/devtools/page/%s" % (HOST, PORT, PAGE_ID)
    p = urllib.parse.urlparse(u)
    s = socket.create_connection((p.hostname, p.port or 80), timeout=15)
    req = ("GET %s HTTP/1.1\r\nHost: %s:%s\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\n\r\n" % (p.path, p.hostname, p.port))
    s.send(req.encode())
    resp = b''
    while b'\r\n\r\n' not in resp: resp += s.recv(4096)
    return s

def send(s, d):
    d = d.encode('utf-8'); n = len(d); m = b'\x01\x02\x03\x04'
    if n <= 125: h = bytes([0x81, n|0x80]) + m
    elif n <= 65535: h = bytes([0x81, 0xFE]) + n.to_bytes(2,'big') + m
    else: h = bytes([0x81, 0xFF]) + n.to_bytes(8,'big') + m
    s.send(h + bytes(d[i]^m[i%4] for i in range(n)))

def recv(s):
    def rx(n):
        b = b''
        while len(b) < n: b += s.recv(n-len(b))
        return b
    h = rx(2); n = h[1]&0x7f
    if n == 126: n = int.from_bytes(rx(2),'big')
    elif n == 127: n = int.from_bytes(rx(8),'big')
    return rx(n).decode('utf-8')

_mid = 0
def cdp(s, js, timeout=20):
    global _mid
    _mid += 1
    send(s, json.dumps({'id':_mid,'method':'Runtime.evaluate','params':{'expression':js,'returnByValue':True}}))
    s.settimeout(timeout)
    for _ in range(300):
        try:
            r = json.loads(recv(s))
            if r.get('id') == _mid:
                return r.get('result',{}).get('result',{}).get('value','')
        except: pass
    return ''

def mouse_click(s, x, y):
    global _mid
    for t in ['mousePressed','mouseReleased']:
        _mid += 1
        send(s, json.dumps({'id':_mid,'method':'Input.dispatchMouseEvent','params':{'type':t,'x':x,'y':y,'button':'left','clickCount':1}}))
        recv(s)
        time.sleep(0.05)

s = ws()
print("[OK] Connected\n")

# 注入图片 base64
print("[Step 1] 注入图片 base64...")
cdp(s, "window.__COVER_B64__='%s'" % IMG_B64, timeout=5)
cdp(s, "window.__COVER_MIME__='%s'" % IMG_MIME, timeout=5)
r = cdp(s, "window.__COVER_B64__ ? 'len='+window.__COVER_B64__.length : 'null'")
print("  base64 注入:", r[:60])

# Step 2: 强制显示 file input 并上传
print("\n[Step 2] 强制显示 file input...")
r = cdp(s, """
(function() {
  // 找到 DIV.editor-outter-wrapper 下的 input[type=file]
  var wrappers = document.querySelectorAll('div.editor-outter-wrapper');
  var result = 'no_wrapper';
  for (var w = 0; w < wrappers.length; w++) {
    var inp = wrappers[w].querySelector('input[type=file]');
    if (!inp) continue;
    // 强制显示
    inp.style.setProperty('display', 'block', 'important');
    inp.style.setProperty('visibility', 'visible', 'important');
    inp.style.setProperty('opacity', '1', 'important');
    inp.style.setProperty('width', '200px', 'important');
    inp.style.setProperty('height', '100px', 'important');
    inp.style.setProperty('position', 'fixed', 'important');
    inp.style.setProperty('top', '100px', 'important');
    inp.style.setProperty('left', '100px', 'important');
    inp.style.setProperty('z-index', '999999', 'important');
    inp.style.setProperty('cursor', 'pointer', 'important');

    // 构建 File 对象
    var b64 = window.__COVER_B64__ || '';
    var mime = window.__COVER_MIME__ || 'image/jpeg';
    var byteString = atob(b64);
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) ia[i] = byteString.charCodeAt(i);
    var blob = new Blob([ab], {type: mime});
    var file = new File([blob], 'cover.jpg', {type: mime});

    // 注入 files
    try {
      Object.defineProperty(inp, 'files', {
        value: [file],
        writable: true,
        configurable: true
      });
      // 触发 change
      var evt = new Event('change', {bubbles: true, cancelable: true});
      inp.dispatchEvent(evt);
      result = 'ok:files=' + inp.files.length + ' name=' + inp.files[0].name;
    } catch(e) {
      result = 'err:' + e.message;
    }
    break;
  }
  return result;
})()
""", timeout=20)
print("  上传:", r[:100] if r else 'empty')
time.sleep(3)

# Step 3: 检查封面图是否上传成功
print("\n[Step 3] 检查封面...")
r = cdp(s, """
(function() {
  // 找封面区域
  var all = document.querySelectorAll('*');
  var imgs = [];
  for (var el of all) {
    var t = (el.innerText || '').trim();
    // 找封面图片容器
    var parent = el.parentElement;
    if (parent && parent.className && parent.className.toLowerCase().indexOf('cover') > -1) {
      var imgs2 = el.querySelectorAll ? el.querySelectorAll('img') : [];
      for (var img of imgs2) {
        imgs.push({src: (img.src||'').substring(0,50), w: img.naturalWidth || img.width, h: img.naturalHeight || img.height});
      }
    }
  }
  // 也找大图（可能是封面上传后的预览）
  var allImgs = document.querySelectorAll('img');
  var largeImgs = [];
  for (var img of allImgs) {
    if ((img.naturalWidth || img.width) > 100 && (img.naturalHeight || img.height) > 100) {
      var src = img.src || '';
      if (src.indexOf('vcg') === -1 && src.indexOf('copyright') === -1 && !src.startsWith('data:')) {
        largeImgs.push({src: src.substring(0,60), w: img.naturalWidth, h: img.naturalHeight});
      }
    }
    // data:image
    if ((img.src || '').indexOf('data:image') > -1) {
      largeImgs.push({src: 'data:image...', w: img.naturalWidth, h: img.naturalHeight});
    }
  }
  return JSON.stringify({cover_imgs: imgs, large_imgs: largeImgs.slice(0,5)});
})()
""")
print("  封面状态:", r[:300] if r else 'empty')

# Step 4: 尝试另一种方式：直接在封面板上注入图片元素
print("\n[Step 4] 直接在封面区域注入 img...")
r = cdp(s, """
(function() {
  var b64 = window.__COVER_B64__ || '';
  var mime = window.__COVER_MIME__ || 'image/jpeg';
  if (!b64) return 'no_b64';

  // 找"选择封面"文字附近的 div/label
  var all = document.querySelectorAll('*');
  var targetDiv = null;
  for (var el of all) {
    var t = (el.innerText || '').trim();
    if (t === '选择封面') {
      // 找父级 cover 容器
      var parent = el.parentElement;
      while (parent && parent.children.length < 3) {
        parent = parent.parentElement;
      }
      targetDiv = parent;
      break;
    }
  }

  if (!targetDiv) return 'no_target_div';

  // 创建 img
  var img = document.createElement('img');
  img.src = 'data:' + mime + ';base64,' + b64;
  img.style.cssText = 'max-width:100%;border-radius:4px;margin-top:8px;display:block;width:100%;max-height:200px;object-fit:cover;';
  img.alt = '封面图';

  // 找插入位置（在"选择封面"后面）
  var all2 = document.querySelectorAll('*');
  for (var el of all2) {
    if ((el.innerText||'').trim() === '选择封面' && el.tagName === 'SPAN') {
      var parent = el.parentElement;
      if (parent) parent.appendChild(img);
      else targetDiv.appendChild(img);
      return 'img_injected:src=' + img.src.substring(0,30);
    }
  }
  targetDiv.appendChild(img);
  return 'img_injected_in_cover_div';
})()
""")
print("  注入 img:", r[:100] if r else 'empty')

print("\n✅ 完成，请查看浏览器中封面区域")
s.close()
