#!/usr/bin/env python3
"""Real internal balance payment followed by signed device fulfilment."""
import hashlib
import json
from decimal import Decimal
from pathlib import Path
import integrate_20261010 as tool
from integrate_20261011_batches46_48 import item
HERE = Path(__file__).resolve().parent
BASE = 'work_store/apifox/2026-09-30-dm8-interface-acceptance/parallel-prepay-code-scan-20261012/'
REPORT = BASE + 'FULFILL_ROOT_REVIEW.md'

def shape(value):
    if isinstance(value, dict):
        return {k:shape(v) for k,v in sorted(value.items())}
    if isinstance(value, list):
        return [shape(v) for v in value]
    return type(value).__name__

def verify():
    manifest = json.loads((tool.ROOT/BASE/'FULFILL_MANIFEST.json').read_text())
    private = Path(manifest['private_root'])
    assert len(manifest['files']) == 20
    for spec in manifest['files']:
        assert hashlib.sha256((private/spec['name']).read_bytes()).hexdigest() == spec['sha256']
    sources = {
        'store': hashlib.sha256((tool.source_root('store')/'application/api/service/PrepayOrder.php').read_bytes()).hexdigest(),
        'ai': hashlib.sha256((tool.source_root('ai_api')/'app/api/service/PrepayOrder.php').read_bytes()).hexdigest(),
        'pay': hashlib.sha256((tool.source_root('ai_api')/'app/api/service/cashier/MealPayment.php').read_bytes()).hexdigest(),
    }
    shapes = {}
    for lane in ['B','C']:
        receipts = {}
        shapes[lane] = {}
        for step in ['code','scan','balance-pay','success','bad-sign']:
            r = json.loads((private/(lane+'-fulfill-'+step+'-receipt.json')).read_text())
            raw = (private/(lane+'-fulfill-'+step+'-response.raw')).read_bytes()
            assert r['passed'] and r['http_status'] == 200
            assert hashlib.sha256(raw).hexdigest() == r.get('body_sha256', r.get('response_body_sha256'))
            body = json.loads(raw)
            assert type(body.get('code', body.get('status'))) is (str if step in ['code','success','bad-sign'] else int)
            shapes[lane][step] = shape(body)
            receipts[step] = r
        code, scan, pay, success, bad = [receipts[k] for k in ['code','scan','balance-pay','success','bad-sign']]
        assert code['store_service_sha256'] == success['service_source_sha256'] == bad['service_source_sha256'] == sources['store']
        assert scan['ai_service_sha256'] == sources['ai'] and pay['payment_service_sha256'] == sources['pay']
        assert code['price_1_cent'] and code['raw_input_roundtrip'] and code['waiting_unpaid']
        assert scan['wallet_unchanged'] and scan['response_order_id_match'] and scan['prepay_user_match']
        before, after = pay['before_rows'], pay['after_rows']
        assert Decimal(before['wallet'][0]) == Decimal('0.05') and Decimal(after['wallet'][0]) == Decimal('0.04')
        assert before['settlement_count'] == 0 and len(after['settlements']) == len(after['balance_logs']) == 1
        assert Decimal(str(after['settlements'][0]['amount'])) == Decimal('0.01')
        assert Decimal(str(after['balance_logs'][0]['money'])) == Decimal('-0.01')
        assert int(before['meal_pay_status']) == 10 and int(after['meal_pay_status']) == 20
        assert pay['external_stub_events_new'] == ['user_sync'] and pay['other_wallets_unchanged']
        before, after = success['before_rows'], success['after_rows']
        assert success['response_code'] == '1' and success['input_roundtrip']
        for key in ['meal','wallet','settlements']:
            assert before[key] == after[key]
        assert int(before['prepay']['prepay_status']) == 1 and int(after['prepay']['prepay_status']) == 5
        assert int(before['prepay']['ship_status']) == 0 and int(after['prepay']['ship_status']) == 1
        assert after['prepay']['ship_time'] != before['prepay']['ship_time']
        assert after['prepay']['raw_request_b_sha256'] and before['prepay']['raw_request_b_sha256'] is None
        assert bad['response_code'] == '0' and bad['before_rows'] == bad['after_rows']
    assert shapes['B'] == shapes['C']

if __name__ == '__main__':
    audit = HERE/'integration-20261012-batch119.json'
    assert not audit.exists()
    targets = [item('store','POST','/api/prepayOrder/fulfillResult',BASE,evidence=REPORT,
        success_case='partial-evidence-new-owned-paid-not-refunded-order-signed-fulfilment',
        readback='tested-pass-prepay-status1-to5-ship0-to1-time-and-input-roundtrip-wallet-order-ledgers-unchanged',
        invalid_type='partial-evidence-invalid-signature-rejected-and-all-four-source-groups-unchanged',
        parity='partial-evidence-entire-response-field-paths-and-types-equal-own-order-identifiers-verified',
        cleanup='own-marked-fulfilled-orders-retained-0.01-internal-balance-only-no-real-device-third-party-queue')]
    for repo,path in [('store','/api/prepayOrder/code'),('ai_api','/api/PrepayOrder/scan'),('ai_api','/api/MealCashier/orderPay')]:
        targets.append(item(repo,'POST',path,BASE,evidence=REPORT,evidence_only=True))
    tool.main(targets,audit,verify)
