"""Validate current appendix artifacts and save completed checkpoint."""
from pathlib import Path
from hashlib import sha256
from zipfile import ZipFile
from shutil import copy2
from collections import Counter
import json, re
from docx import Document
from pypdf import PdfReader
from PIL import Image

root = Path(r'C:\Users\Asus\Desktop\TourAppProject\travelin_app\docs\thesis_appendices')
state_path = root / 'work/waiting_capture_batch.json'
s = json.loads(state_path.read_text(encoding='utf-8'))
cp = Path(s['checkpoint'])
word = root / 'TourApp_Appendix_A_B.docx'
pdf = root / 'TourApp_Appendix_A_B_Review.pdf'
doc = Document(word)
before = Document(cp / ('before_' + word.name))
assert [p.text for p in doc.paragraphs if p.style.name == 'Heading 2'] == [p.text for p in before.paragraphs if p.style.name == 'Heading 2']
assert len(doc.inline_shapes) == 22
assert sum('[รอภาพหน้าจอจริง:' in p.text for p in doc.paragraphs) == 28
caps = [p.text for p in doc.paragraphs if p.style.name == 'Caption' and p.text.startswith('ภาพประกอบที่ ')]
numbers = [re.match(r'ภาพประกอบที่ ([กข]-\d+)', p).group(1) for p in caps]
assert numbers == [f'ก-{n}' for n in range(1, 6)] + [f'ข-{n}' for n in range(1, 18)]
with ZipFile(word) as z, ZipFile(cp / ('before_' + word.name)) as old:
    assert z.testzip() is None
    media_names = [n for n in z.namelist() if n.startswith('word/media/')]
    media = {sha256(z.read(n)).hexdigest() for n in media_names}
    old_media = {sha256(old.read(n)).hexdigest() for n in old.namelist() if n.startswith('word/media/')}
    assert len(media_names) == len(media) == 21 and old_media.issubset(media)
    assert sha256(Path(s['sanitized']).read_bytes()).hexdigest() in media
    assert s['source_sha256'] not in media
assert sha256(Path(s['source']).read_bytes()).hexdigest() == s['source_sha256']
assert sha256(Path(s['initial_capture']).read_bytes()).hexdigest() == s['source_sha256']
pending = (root / 'appendix_pending.md').read_text(encoding='utf-8')
categories = Counter(re.findall(r'^\| (?:ก\.\d+|ข\.\d+\.\d+) [^|]+ \| ([BCD]) \|', pending, flags=re.M))
assert categories == {'B': 2, 'C': 21, 'D': 5}
reader = PdfReader(pdf)
assert len(reader.pages) == 38
assert 'ภาพประกอบที่ ข-8 หน้าสถานะรอจับคู่และเวลาคงเหลือ' in reader.pages[18].extract_text()
assert 'ภาพประกอบที่ ข-17 การเข้าสู่ระบบผู้ดูแล' in reader.pages[34].extract_text()
old_render = root / 'work/agency_capture_final_render_20261003'
new_render = root / 'work/flutter_waiting_final_render_20261003'
old_hashes = {sha256(Image.open(p).tobytes()).hexdigest() for p in old_render.glob('page-*.png')}
same, changed = [], []
for p in sorted(new_render.glob('page-*.png')):
    (same if sha256(Image.open(p).tobytes()).hexdigest() in old_hashes else changed).append(p.name)
assert len(same) == 17 and len(changed) == 21 and len(same) + len(changed) == 38
for name in (word.name, pdf.name, 'appendix_progress.md', 'appendix_pending.md', 'appendix_image_index.md', 'appendix_capture_guide.md'):
    copy2(root / name, cp / name)
s.update({'pdf_pages': 38, 'heading_2_topics': 54, 'pending_categories': dict(categories),
          'caption_number': 'ข-8', 'caption_page': 19, 'captions': caps,
          'word_sha256': sha256(word.read_bytes()).hexdigest(), 'pdf_sha256': sha256(pdf.read_bytes()).hexdigest(),
          'source_hash_unchanged': True, 'raw_screenshot_embedded': False,
          'old_media_preserved': True, 'render_engine': 'Word COM read-only / Poppler 120 dpi',
          'visually_reviewed_changed_pages': changed, 'pixel_identical_previously_reviewed_pages': same,
          'visual_review': 'PASS: no clipped/overlapping text, image distortion or separated caption',
          'remaining_agency_topics': ['ข.2.5', 'ข.2.6', 'ข.2.7', 'ข.2.9'],
          'source_code_edits': 0, 'database_operations': 0, 'api_requests': 0,
          'android_input_actions': 0, 'adb_screencap_calls': 1})
state_path.write_text(json.dumps(s, ensure_ascii=False, indent=2), encoding='utf-8')
(cp / 'verification.json').write_text(json.dumps(s, ensure_ascii=False, indent=2), encoding='utf-8')
print(json.dumps({k: s[k] for k in ('checkpoint', 'pdf_pages', 'embedded_images', 'unique_media', 'pending_topics', 'caption_number', 'caption_page', 'source_hash_unchanged', 'old_media_preserved', 'word_sha256', 'pdf_sha256')}, ensure_ascii=False))
