# -*- coding: utf-8 -*-
r"""B165: mở hội thoại LỘC QC -> dump khối tin HÔM NAY -> tải CHỈ ảnh thuộc hôm nay (theo epoch trong id ảnh).
Ghi tiến độ + dữ liệu thô ra C:\Claw 2\QC\_qc_loc1410\."""
import base64, hashlib, json, os, re, subprocess, time

S = 'qcloc1410'
RA = r'C:\Claw 2\QC\_qc_loc1410'
ANH = r'C:\Claw 2\QC\images\_zalo_loc_1410'
os.makedirs(RA, exist_ok=True)
os.makedirs(ANH, exist_ok=True)
LOG = os.path.join(RA, 'tien_do.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)


def mo_phien():
    for lan in range(6):
        r = chay(['--session', S, 'browser', 'open', 'direct_local_123687895331504232',
                  'https://chat.zalo.me'], t=150)
        if 'url=' in r or 'title=' in r:
            ghi('mở Zalo OK (lần %d)' % (lan + 1))
            return True
        ghi('  mở lần %d: %s' % (lan + 1, r[-60:].replace('\n', ' ')))
        time.sleep(12)
    return False


if not mo_phien():
    ghi('KHÔNG mở được Zalo')
    raise SystemExit(1)
time.sleep(15)
ghi('trạng thái: ' + ev("JSON.stringify({t:document.title, s:!!document.querySelector('#contact-search-input')})")[-120:])

# mở hội thoại Lộc QC bằng ô tìm kiếm
ghi('tìm: ' + ev("""(()=>{const s=document.querySelector('#contact-search-input'); if(!s) return 'KHONG CO O TIM';
 s.focus(); document.execCommand('selectAll',false,null); document.execCommand('insertText',false,'Loc QC'); return 'ok';})()""")[-30:])
time.sleep(5)
ghi('kết quả: ' + ev("""(()=>{const ds=[...document.querySelectorAll('div[id^=friend-item-].conv-item')];
 return JSON.stringify({so:ds.length, ten:ds.slice(0,4).map(e=>e.innerText.split('\\n')[0])});})()""")[-200:])
ghi('bấm: ' + ev("""(()=>{const ds=[...document.querySelectorAll('div[id^=friend-item-].conv-item')];
 const t=ds.find(e=>/loc\\s*qc/i.test(e.innerText)); if(!t) return 'KHONG THAY'; t.click(); return t.innerText.split('\\n')[0];})()""")[-50:])
time.sleep(7)
ghi('tiêu đề: ' + ev("(()=>{const h=document.querySelector('.header-title'); return h? h.innerText.trim():'(khong co)';})()")[-60:])

# cuộn lên cho nạp đủ rồi dump
for i in range(3):
    ev("""(()=>{const sc=document.querySelector('.chat-message-list, .message-list, #messageList')||document.scrollingElement;
      sc.scrollTop = (sc.scrollHeight||0)*0.05; return 1;})()""")
    time.sleep(3)

d = ev(r"""(()=>{const ra={so_khoi:0, khoi:[]};
 const ks=[...document.querySelectorAll('.block-date')]; ra.so_khoi=ks.length;
 ks.forEach((k,i)=>{
   const o={i:i, gio:(k.querySelector('.card-send-time__sendTime')||{}).innerText||'', tin:[]};
   [...k.querySelectorAll('.chat-message')].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;}).filter(Boolean);
     if(t.length>0 || ids.length>0) o.tin.push({chu:/\bme\b/.test(e.className||''), dai:t.length, ids:ids, text:t.slice(0,2000)});
   });
   ra.khoi.push(o);
 });
 return JSON.stringify(ra);})()""", t=200)
with open(os.path.join(RA, 'zalo_all.json'), 'w', encoding='utf-8') as f:
    f.write(d)
j = json.loads(d)
for k in j['khoi']:
    vs = [(x['dai'], len(x['ids']), (min(x['ids']) if x['ids'] else 0)) for x in k['tin']]
    ghi('khối %d giờ=%s | %d tin | (dài, số ảnh, epoch nhỏ nhất): %s' % (k['i'], k['gio'], len(k['tin']), vs[:4]))

moc = time.mktime(time.strptime('2026-10-14 00:00:00', '%Y-%m-%d %H:%M:%S')) * 1000
can = [(k['i'], k['gio'], m['text'][:50], e) for k in j['khoi'] for m in k['tin'] for e in m['ids'] if e >= moc]
ghi('ảnh HÔM NAY: %d | epoch mốc: %d' % (len(can), moc))

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, 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 (ki, gio, txt, eid) in can:
    ev("""(()=>{const t=[...document.querySelectorAll('img.zimg-el')].find(x=>x.id && x.id.indexOf('img-%d')>=0);
      if(!t) return 'KHONG_THAY'; t.scrollIntoView({block:'center'}); t.dispatchEvent(new MouseEvent('click',{bubbles:true})); return 'ok';})()""" % eid, t=120)
    time.sleep(2.5)
    c = ''
    for lan in range(4):
        c = ev(JS_CAP, t=180)
        if c.startswith('{'):
            break
        time.sleep(2.5)
    if not c.startswith('{'):
        ghi('  id=%d: %s' % (eid, c[:50]))
        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('  id=%d TRÙNG %s' % (eid, md5))
        continue
    ten = 'loc1410_%02d_%s.jpg' % (len(da) + 1, md5[:6])
    with open(os.path.join(ANH, ten), 'wb') as f:
        f.write(raw)
    da.append((md5, ten, o['w'], o['h'], len(raw)))
    ghi('  ảnh %d: %s %dx%d %d byte | id=%d (%s)' % (len(da), ten, o['w'], o['h'], len(raw), eid,
        time.strftime('%H:%M:%S', time.localtime(eid / 1000))))
ev("(()=>{document.dispatchEvent(new KeyboardEvent('keydown',{key:'Escape',bubbles:true})); return 1;})()", t=60)
ghi('XONG: %d ảnh hôm nay -> %s' % (len(da), ANH))
