from pathlib import Path
from shutil import copy2
from copy import copy
import hashlib
import json
import zipfile

from PIL import Image
from openpyxl import load_workbook
from openpyxl.drawing.image import Image as XLImage

root = Path(__file__).resolve().parent
out = root / 'output'
history = out / 'history/2026-09-30-two-device-kitchen-rejected'
history.mkdir(parents=True, exist_ok=True)
names = ['张家港市农商行项目-3D场景图.png', '张家港市农商行项目-生成底图.png', '张家港市农商行项目-场景说明.xlsx', 'validation.json']
for name in names:
    if not (history / name).exists():
        copy2(out / name, history / name)

generated = Path('/Users/jack/.codex/generated_images/01a0ed40-cbfa-72b2-8fd0-cee2cc853829/exec-38dd01f3-75c6-4d06-b95a-04c40ff56679.png')
png = out / names[0]
copy2(generated, png)
copy2(generated, out / names[1])
copy2(generated, out / '张家港市农商行项目-前厅双机结算.png')
xlsx = out / names[2]
wb = load_workbook(xlsx)
ws = wb['场景说明']
updates = {
    'A1': '张家港市农商行项目｜前厅双机结算场景说明',
    'F3': '设备外观B级参考；前厅布局D级示意',
    'B4': '员工前厅取餐后，在开阔结算区使用两台AI识别结算设备，完成卡/码支付后进入就餐区。',
    'F4': '数量确认2台；按用户要求改为前厅布局示意',
    'F5': '现场照片仅参考设备外观；前厅空间为示意，未进行实测复原',
    'D9': '前厅取餐动线末端、就餐区入口',
    'E9': '数量2台已确认；前厅摆位为示意',
    'F9': '方案及用户确认两台；参考实拍设备外观；用户要求设备位于前厅开阔区域',
    'A25': '前厅双机结算3D主图与区域说明',
    'A54': '区域/内容', 'B54': '含义', 'C54': '证据状态', 'D54': '说明',
    'D72': '终端型号/SN、前厅实测平面与精确点位、双台交易与对账记录',
}
for cell, value in updates.items():
    ws[cell] = value
rows = [
    ['取餐区', '员工自助取餐', '前厅示意', '面向员工的取餐台；未沿用后厨窗口与配餐作业布局'],
    ['双机结算区', '两台AI识别结算设备', '数量确认；外观参考实拍', '两套独立柜体和识别终端位于开阔前厅；精确摆位为示意'],
    ['就餐区', '结算后进入座席区', '前厅示意', '桌椅、装修与人数仅用于表达就餐场景'],
    ['设备操作', '放盘识别、刷卡/扫码', '项目方案', '图中放盘和刷卡动作展示业务用法，不能证明验收完成'],
    ['本地服务器', '订单处理', '项目方案', '未在本图中表达服务器位置'],
    ['银行接口', '在线核销与状态查询', '项目方案', '功能规则详见业务流程，不作为现场摆位证据'],
    ['照片用途', '设备外观参考', '用户明确要求', '现场图片不作为本版前厅空间、窗口或排队位置的复原模板'],
    ['布局边界', '前厅双机结算', '用户指定场景', '数量为两台；前厅实测尺寸和精确点位待补证'],
]
for row, values in enumerate(rows, 55):
    for col, value in enumerate(values, 1):
        ws.cell(row, col, value)
ws._images.clear()
with Image.open(png) as im:
    width, height = im.size
img = XLImage(png)
img.width = 1100
img.height = 1100 * height / width
ws.add_image(img, 'A26')
src = wb['来源与待补证']
for cell, value in {
    'C9': '设备柜、黑色台面、立式终端及辅助屏外观参考；照片环境不作为本版布局模板',
    'D9': 'B级设备外观参考',
    'E9': '前厅为用户指定的示意场景',
    'C10': '确认两台设备，并要求放在前厅开阔区域；拒绝后厨和角落场景',
    'E10': '照片只作参考；前厅空间为示意',
    'B13': '前厅实测平面、两台设备精确点位、前厅全景',
    'C13': '用于后续由前厅示意升级为现场空间复原',
    'E13': '数量确认2台；前厅布局D级示意',
    'E14': '数量2台已确认；型号和验收信息待核',
}.items():
    src[cell] = value
for col, value in enumerate(['AI生成主图', 'output/张家港市农商行项目-前厅双机结算.png', '前厅取餐、双机结算、就餐三区；设备外观参考实拍', '空间D级示意', '内置图像生成；未按照片后厨空间复原'], 1):
    cell = src.cell(19, col, value)
    cell._style = copy(src.cell(9, col)._style)
src.row_dimensions[19].height = 70
if src.print_area:
    src.print_area = 'A1:J19'
wb.save(xlsx)

index_path = root / 'source-index.json'
index = json.loads(index_path.read_text())
index['evidence_level'] = 'B设备外观参考 / D前厅空间示意'
for entry in index['sources']:
    if entry['path'].endswith('餐线窗口与动线全景.jpg'):
        entry['use'] = '历史参考；按用户要求不再用于本版前厅布局复原'
    if entry['type'] == '用户纠正确认':
        entry['use'] = '数量确认两台；改为前厅开阔结算区；照片仅作参考，拒绝后厨和角落布局'
    if entry['type'] == 'AI现场校准底图':
        entry.update(path=str(generated), type='AI前厅布局示意', use='设备外观参考实拍；数量两台；取餐、双机结算和就餐区为示意')
index['confirmed_facts'] = [x for x in index['confirmed_facts'] if not x.startswith('现场照片确认兑餐窗口') and not x.startswith('设备数量由')]
index['confirmed_facts'].append('方案和用户确认设备数量为两台；用户指定前厅结算场景，照片仅参考设备外观。')
index['layout_assumption'] = '两台设备位于前厅取餐末端、就餐区入口的开阔区域；桌椅、装修、人数和具体位置均为示意。'
index_path.write_text(json.dumps(index, ensure_ascii=False, indent=2) + '\n')

check = load_workbook(xlsx)
assert check['场景说明']['C9'].value == '2台'
assert len(check['场景说明']._images) == 1
assert check['场景说明']['D9'].value.startswith('前厅')
with zipfile.ZipFile(xlsx) as z:
    assert z.testzip() is None
validation = {
    'project': '张家港市农商行项目',
    'revision': 'front-hall-two-devices',
    'evidence_level': index['evidence_level'],
    'can_claim_1_to_1': False,
    'files': {'png': str(png), 'xlsx': str(xlsx), 'generated_source': str(generated)},
    'checks': {'png_size': [width, height], 'landscape_approximately_16_9': abs(width / height - 16 / 9) < .002, 'visible_device_quantity': 2, 'xlsx_device_quantity': '2台', 'xlsx_embedded_images': 1, 'xlsx_zip_ok': True, 'visual_review': '两台设备位于前厅开阔区，取餐台和就餐座席可见，无后厨作业场景', 'old_version_preserved': True},
    'sha256': {p.name: hashlib.sha256(p.read_bytes()).hexdigest() for p in [png, xlsx]},
    'open_gaps': ['前厅实测平面与精确点位', '设备型号和验收证据'],
}
(out / 'validation.json').write_text(json.dumps(validation, ensure_ascii=False, indent=2) + '\n')
print(json.dumps(validation, ensure_ascii=False, indent=2))
