# -*- coding: utf-8 -*-
r"""B158: (1) cuộn + dump MỌI khối tin HÔM NAY của hội thoại Trí QC; (2) tải ảnh theo cách chuẩn.
Cách chuẩn lấy ảnh: thumbnail trong .chat-message -> bấm lần lượt -> đọc #imageShowMainImage img
-> canvas cắt max 1400 px -> md5 khử trùng. Ghi tiến độ ra file để cha theo dõi."""
import base64, hashlib, io, json, os, re, subprocess, sys, time

S = 'qc1410'
RA = r'C:\Claw 2\QC\_qc1410'
ANH = r'C:\Claw 2\QC\images\_zalo_tri_1410'
os.makedirs(RA, exist_ok=True)
os.makedirs(ANH, exist_ok=True)
LOG = os.path.join(RA, 'tien_do_anh.txt')


def ghi(t):
    with open(LOG, 'a', encoding='utf-8') as f:
        f.write('%s %s\n' % (time.strftime('%H:%M:%S'), t))
    print(t, flush=True)


def chay(args, inp=None, t=240):
    try:
        r = subprocess.run(['browser-act'] + args, input=inp, capture_output=True, text=True,
                           encoding='utf-8', errors='replace', timeout=t)
        return ((r.stdout or '') + (r.stderr or '')).strip()
    except Exception as e:
        return 'LOI: %s' % e


def ev(js, t=240):
    return chay(['--session', S, 'eval', '--stdin'], inp=js, t=t)


# sống lại phiên nếu cần
if 'Zalo' not in ev("document.title", t=60):
    ghi('mở lại phiên…')
    chay(['--session', S, 'browser', 'open', 'direct_local_123687895331504232', 'https://chat.zalo.me'], t=120)
    time.sleep(14)
ghi('trạng thái: ' + ev("JSON.stringify({t:document.title, hd:(document.querySelector('.header-title')||{}).innerText||''})")[-140:])

# ─── 1) cuộn lên 3 vòng rồi dump mọi khối ───
for i in range(3):
    ev("""(()=>{const k=[...document.querySelectorAll('.block-date')]; const p=(k[k.length-1]||{}).parentElement;
      const sc=document.querySelector('.chat-message-list, .message-list, #messageList');
      const el=sc||p||document.scrollingElement;
      el.scrollTop = -1e9; el.scrollTop = (el.scrollHeight||0)*0.1; return 1;})()""")
    time.sleep(3)
JS_DUMP = r"""(()=>{const ra={so_khoi:0, khoi:[]};
 const ks=[...document.querySelectorAll('.block-date')];
 ra.so_khoi=ks.length;
 ks.forEach((k,i)=>{
   const tin=[...k.querySelectorAll('.chat-message')];
   const o={i:i, gio:(k.querySelector('.card-send-time__sendTime')||{}).innerText||'',
            ngay:(k.querySelector('.card-send-time__sendDate')||{}).innerText||'',
            so_tin:tin.length, tin:[]};
   tin.forEach(e=>{
     const t=(e.innerText||'').replace(/\s+/g,' ').trim();
     const ids=[...e.querySelectorAll('img.zimg-el')].filter(x=>(x.src||'').startsWith('blob:'))
               .map(x=>{const m=(x.id||'').match(/img-(\d+)/); return m? +m[1] : 0;});
     if(t.length>0 || ids.length>0)
       o.tin.push({chu:/\bme\b/.test((e.className||'')), dai:t.length, anh:ids.length, ids:ids, text:t.slice(0,1500)});
   });
   ra.khoi.push(o);
 });
 return JSON.stringify(ra);})()"""
d = ev(JS_DUMP, t=200)
with open(os.path.join(RA, 'zalo_all.json'), 'w', encoding='utf-8') as f:
    f.write(d)
try:
    j = json.loads(d)
    for k in j['khoi']:
        ghi('khối %d | ngày=%r giờ=%r | %d tin | ảnh: %s' % (k['i'], k['ngay'], k['gio'], k['so_tin'],
            [x['anh'] for x in k['tin'] if x['anh']]))
except Exception as e:
    ghi('dump lỗi phân tích: %s' % e)

# ─── 2) tải ảnh: bấm từng thumbnail, lấy ảnh lớn ───
JS_CAP = r"""(()=>{const im=document.querySelector('#imageShowMainImage img')||document.querySelector('img.zimage-viewer__img');
 if(!im) return 'CHUA_CO_ANH_LON';
 if(!im.naturalWidth) return 'ANH_CHUA_LOAD';
 const W=im.naturalWidth,H=im.naturalHeight, MAX=1400;
 const sc=Math.min(1, MAX/Math.max(W,H));
 const c=document.createElement('canvas'); c.width=Math.round(W*sc); c.height=Math.round(H*sc);
 c.getContext('2d').drawImage(im,0,0,c.width,c.height);
 return JSON.stringify({w:W,h:H,tw:c.width,th:c.height,data:c.toDataURL('image/jpeg',0.92).split(',')[1]});})()"""

da = []
for k in (j['khoi'] if 'j' in dir() else []):
    for m in k['tin']:
        for idx, eid in enumerate(m.get('ids') or []):
            try:
                r = ev("""(()=>{const t=[...document.querySelectorAll('img.zimg-el')].find(x=>x.id && x.id.indexOf('img-%d')>=0);
                  if(!t) return 'KHONG_THAY_THUMB'; t.dispatchEvent(new MouseEvent('click',{bubbles:true})); return 'da bam';})()""" % eid, t=120)
                time.sleep(2.5)
                for lan in range(3):
                    c = ev(JS_CAP, t=180)
                    if c.startswith('{'):
                        break
                    time.sleep(2.5)
                if not c.startswith('{'):
                    ghi('ảnh id=%s: %s' % (eid, c[:60]))
                    continue
                o = json.loads(c)
                raw = base64.b64decode(o['data'])
                md5 = hashlib.md5(raw).hexdigest()[:12]
                if md5 in [x[0] for x in da]:
                    ghi('ảnh id=%s: TRÙNG (bỏ) %s' % (eid, md5))
                    continue
                ten = 'tri1410_%02d_%s.jpg' % (len(da) + 1, md5[:6])
                p = os.path.join(ANH, ten)
                with open(p, 'wb') as f:
                    f.write(raw)
                da.append((md5, ten, o['w'], o['h'], len(raw)))
                ghi('ảnh %d: %s  %dx%d -> %dx%d  %d byte' % (len(da), ten, o['w'], o['h'], o['tw'], o['th'], len(raw)))
            except Exception as e:
                ghi('ảnh id=%s LỖI: %s' % (eid, e))
                continue
ev("(()=>{document.dispatchEvent(new KeyboardEvent('keydown',{key:'Escape',bubbles:true})); return 1;})()", t=60)
ghi('XONG: tải được %d ảnh (duy nhất) vào %s' % (len(da), ANH))
with open(os.path.join(RA, 'anh_da_tai.json'), 'w', encoding='utf-8') as f:
    json.dump([{'md5': m, 'ten': t, 'rong': w, 'cao': h, 'byte': b} for m, t, w, h, b in da], f, ensure_ascii=False, indent=1)
