"""Insert one real Waiting screenshot into the existing appendix only."""
from pathlib import Path
from datetime import datetime
from shutil import copy2
from hashlib import sha256
from zipfile import ZipFile
import json, re, sys
from PIL import Image
from docx import Document
from docx.shared import Cm, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH

root = Path(r'C:\Users\Asus\Desktop\TourAppProject\travelin_app\docs\thesis_appendices')
word = root / 'TourApp_Appendix_A_B.docx'
state_path = root / 'work/waiting_capture_batch.json'

if sys.argv[1] == 'prepare':
    source = root / 'work/capture_inbox/tourist/capture_unclassified_20261003_203032.png'
    target = root / 'work/capture_inbox/tourist/tourist_matching_waiting.png'
    clean = root / 'screenshots/appendix_b/tourist/tourist_matching_waiting.png'
    assert source.exists() and not target.exists() and not clean.exists()
    cp = root / 'checkpoints' / ('flutter_waiting_capture_' + datetime.now().strftime('%Y%m%d_%H%M%S'))
    cp.mkdir(exist_ok=False)
    for name in (word.name, 'TourApp_Appendix_A_B_Review.pdf', 'appendix_progress.md', 'appendix_pending.md', 'appendix_image_index.md', 'appendix_capture_guide.md'):
        copy2(root / name, cp / ('before_' + name))
    copy2(source, target)
    with Image.open(target) as im:
        assert im.size == (1080, 2400)
        # Remove device clock/status/navigation bars only. No UI components fabricated.
        im.convert('RGB').crop((0, 100, 1080, 2050)).save(clean)
    state = {'checkpoint': str(cp), 'source': str(target), 'initial_capture': str(source), 'sanitized': str(clean),
             'source_sha256': sha256(target.read_bytes()).hexdigest(),
             'before_word_sha256': sha256(word.read_bytes()).hexdigest(),
             'capture_type': 'Real Android screen; adb screencap only; emulator-5554 / Pixel_6',
             'privacy': 'No account names/contact details/IDs/credentials in visible screen; crop device bars, strip metadata; original unchanged',
             'matching_operations': 0, 'database_operations': 0, 'api_requests': 0,
             'agency_status': 'No accessible Chrome/Edge Portal session in tool inventory; no claim about eligible lead existence'}
    state_path.write_text(json.dumps(state, ensure_ascii=False, indent=2), encoding='utf-8')
    print(json.dumps({'checkpoint': str(cp), 'source': str(target), 'sanitized': str(clean)}, ensure_ascii=False))
elif sys.argv[1] == 'insert':
    s = json.loads(state_path.read_text(encoding='utf-8'))
    assert sha256(word.read_bytes()).hexdigest() == s['before_word_sha256']
    doc = Document(word)
    assert len(doc.inline_shapes) == 21
    old = [(p._p, re.match(r'ภาพประกอบที่ (ข-\d+) ', p.text).group(1)) for p in doc.paragraphs if re.match(r'ภาพประกอบที่ (ข-\d+) ', p.text)]
    marker = next(p for p in doc.paragraphs if p.text == '[รอภาพหน้าจอจริง: สถานะรอจับคู่และกรอบเวลา 24 ชั่วโมง]')
    marker.clear(); marker.style = 'Normal'; marker.alignment = WD_ALIGN_PARAGRAPH.CENTER
    f = marker.paragraph_format
    f.first_line_indent = Cm(0); f.line_spacing = 1
    f.space_before = Pt(6); f.space_after = Pt(6); f.keep_with_next = True
    shape = marker.add_run().add_picture(s['sanitized'], width=Cm(7.2))
    shape._inline.docPr.set('descr', 'หน้าสถานะรอจับคู่จาก Pixel_6 แสดงเวลาคงเหลือและปุ่มยกเลิก; ไม่มีข้อมูลระบุตัวบัญชี')
    caption = marker.insert_paragraph_before('ภาพประกอบที่ ข-0 หน้าสถานะรอจับคู่และเวลาคงเหลือ', style='Caption')
    marker._p.addnext(caption._p)
    caption.alignment = WD_ALIGN_PARAGRAPH.CENTER
    caption.paragraph_format.first_line_indent = Cm(0)
    caption.paragraph_format.keep_with_next = True
    first = next(p for p in doc.paragraphs if p._p is caption._p.getnext())
    first.clear()
    first.add_run('หลังบันทึกความต้องการ หากยังไม่มีสมาชิกที่เหมาะสมเพียงพอ หน้าสถานะการจับคู่จะแสดง กำลังค้นหาเพื่อนร่วมทริป... พร้อมขั้นตอน ความต้องการ กำลังจับคู่ และ กลุ่มพร้อม ผู้ใช้อ่านเวลาคงเหลือและสรุปประเทศ เดือนเดินทาง งบประมาณ และกิจกรรมจากหน้านี้ ภาพตัวอย่างแสดง เหลือเวลา 23 ชม. 58 นาที ซึ่งยังอยู่ในช่วงรอ ค่าเริ่มต้นของบริการกำหนดกรอบเวลา 24 ชั่วโมง แต่ควรยึดค่าที่แสดงตามการตั้งค่าของระบบที่ใช้งาน')
    mapping = {}; n = 0
    for p in doc.paragraphs:
        if re.match(r'ภาพประกอบที่ ข-\d+ ', p.text):
            n += 1
            previous = next((number for element, number in old if element is p._p), None)
            if previous: mapping[previous] = f'ข-{n}'
            text = re.sub(r'ข-\d+', f'ข-{n}', p.text, count=1)
            p.clear(); p.add_run(text)
    for p in doc.paragraphs:
        if p.text.startswith('ภาพประกอบที่ '): continue
        for run in p.runs:
            if re.search(r'ข-\d+', run.text):
                run.text = re.sub(r'ข-\d+', lambda m: mapping.get(m.group(0), m.group(0)), run.text)
    assert len(doc.inline_shapes) == 22
    assert sum('[รอภาพหน้าจอจริง:' in p.text for p in doc.paragraphs) == 28
    assert sum(p.style.name == 'Heading 2' for p in doc.paragraphs) == 54
    doc.core_properties.author = ''; doc.core_properties.last_modified_by = ''
    stage = root / 'work/waiting_capture_staging.docx'; doc.save(stage)
    with ZipFile(stage) as z:
        assert z.testzip() is None
        media = {sha256(z.read(n)).hexdigest() for n in z.namelist() if n.startswith('word/media/')}
        assert sha256(Path(s['sanitized']).read_bytes()).hexdigest() in media
        assert s['source_sha256'] not in media
    stage.replace(word)
    copy2(word, Path(s['checkpoint']) / word.name)
    s.update({'embedded_images': 22, 'unique_media': 21, 'pending_topics': 28,
              'caption_mapping': mapping, 'word_sha256': sha256(word.read_bytes()).hexdigest()})
    state_path.write_text(json.dumps(s, ensure_ascii=False, indent=2), encoding='utf-8')
    print(json.dumps(s, ensure_ascii=False))
else:
    raise SystemExit('Use prepare or insert')
