import json
from pathlib import Path
p=Path(__file__).parent
# Numeric inputs transcribed and clause-bound to buyer record IDs; assertions protect extraction.
inputs={
 'horizon_years': {'value':2,'source':'BR1','clause':'“两年”'},
 'hours_rate': {'value':200,'source':'BR1','clause':'“含现金及一次内部配置工时每小时200”'},
 'budgets': {'current':120000,'high':160000,'source':'BR1','clause':'“预算CNY当前120000，高量160000”'},
 'annual_volume': {'current':200000,'high':300000,'source':'BR1','clause':'“每年新增当前200000条/高量300000条”'},
 'retention': {'value':'全部保留，起始0','source':'BR1','clause':'“全部保留，起始0”'},
 'A': {'annual':48000,'included':200000,'overage':0.10,'implementation':6000,'hours':60,'exit':2000,'rate':100000,'source':'BR1','clause':'“A：每年48000含200000条，当年超额0.10/条；实施6000一次，内部60小时，退出完整一次2000，保证100000条/天”'},
 'B': {'annual':40000,'included':200000,'overage':0.14,'implementation':4000,'hours':100,'exit':0,'rate':50000,'source':'BR1','clause':'“B：每年40000含200000，超额0.14/条；实施4000，内部100小时；免费退出50000条/天”'},
 'C': {'annual':52000,'included':'unlimited','implementation':0,'hours':20,'exit':1000,'rate':100000,'source':'BR1','clause':'“C：每年52000不限，内部20小时，实施0，退出1000、100000/天；主存与客服内地但备份香港，暂无修改”'},
 'U': {'fee':3000,'rate':80000,'source':'BR1','clause':'“B可选升级U仅构造报价假设：一次3000把退出改成80000/天”'},
 'requirements': {'source':'BR1','clause':'“数据含备份和客服访问必须中国内地；任何财务写入须人工确认；退出要在8天内完整导出含附件元数据开放格式，可收费。”'},
}
assert inputs['horizon_years']['value']==2 and inputs['hours_rate']['value']==200
assert inputs['budgets']=={'current':120000,'high':160000,'source':'BR1','clause':'“预算CNY当前120000，高量160000”'}
assert inputs['annual_volume']=={'current':200000,'high':300000,'source':'BR1','clause':'“每年新增当前200000条/高量300000条”'}
assert inputs['A']['rate']==100000 and inputs['B']['rate']==50000 and inputs['C']['rate']==100000 and inputs['U']['fee']==3000 and inputs['U']['rate']==80000
scenarios=[]
for scale in ('current','high'):
    annual_n=inputs['annual_volume'][scale]; budget=inputs['budgets'][scale]; retained=annual_n*2
    for vendor in ('A','B','C','B+U'):
        base='B' if vendor=='B+U' else vendor; q=inputs[base]
        recurring=q['annual']*2
        overage=0 if q['included']=='unlimited' else round(max(0,annual_n-q['included'])*q['overage']*2)
        implementation=q['implementation']; labor=q['hours']*inputs['hours_rate']['value']; exit_fee=q['exit']; upgrade=inputs['U']['fee'] if vendor=='B+U' else 0
        cash=recurring+overage+implementation+exit_fee+upgrade; total=cash+labor
        rate=inputs['U']['rate'] if vendor=='B+U' else q['rate']
        days=retained/rate
        scenarios.append(dict(scale=scale,vendor=vendor,annual_recurring=recurring/2,annual_overage=overage/2,term_recurring=recurring,term_overage=overage,implementation=implementation,labor_hours=q['hours'],labor=labor,exit_fee=exit_fee,scenario_only=upgrade,cash=cash,total=total,budget=budget,headroom=budget-total,records=retained,rate=rate,days=days,within_8=days<=8))
# compare threshold calculations as same in-scope, all-in cost basis
for scale in ('current','high'):
    aa=next(x for x in scenarios if x['scale']==scale and x['vendor']=='A')
    bb=next(x for x in scenarios if x['scale']==scale and x['vendor']=='B')
    bu=next(x for x in scenarios if x['scale']==scale and x['vendor']=='B+U')
    bu['max_upgrade_budget']=budget-(bb['total']) # overwritten below correctly per scenario scale
    bu['max_upgrade_budget']=bb['budget']-bb['total']
    bu['tie_fee_vs_A']=aa['total']-bb['total']
    bu['quoted_advantage_vs_A']=aa['total']-bu['total']
    bu['strictly_cheaper_fee_limit']=bu['tie_fee_vs_A']
# monetary fields remain integer CNY (all values exact)
for s in scenarios:
    for k in ('annual_recurring','annual_overage','term_recurring','term_overage','implementation','labor','exit_fee','scenario_only','cash','total','budget','headroom'):
        assert s[k] == int(s[k])
    assert s['cash']==s['term_recurring']+s['term_overage']+s['implementation']+s['exit_fee']+s['scenario_only']
    assert s['total']==s['cash']+s['labor']
(p/'computed_scenarios.json').write_text(json.dumps({'inputs':inputs,'scenarios':scenarios},ensure_ascii=False,indent=2))
# Tables are generated directly from computed records.
labels={'current':'当前','high':'高量'}
rows=[]
for s in scenarios:
    rows.append(f"| {labels[s['scale']]} | {s['vendor']} [BR1] | {int(s['annual_recurring']):,} | {int(s['annual_overage']):,} | {s['term_recurring']:,} | {s['term_overage']:,} | {s['implementation']:,} | {s['exit_fee']:,} | {s['scenario_only']:,} | {s['cash']:,} | {s['labor']:,}（{s['labor_hours']}小时） | {s['total']:,} | {s['budget']:,} | {s['headroom']:,} |")
cost='| 规模 | 方案 | 年固定费 | 年超额费 | 两年固定费 | 两年超额费 | 实施现金 | 常规退出现金 | 方案专属升级费 | 现金小计 | 内部配置工时（计价） | 两年全口径总成本 | 预算 | 预算余量（正数） |\n|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|\n'+'\n'.join(rows)
exitrows=[]
for s in scenarios:
    exitrows.append(f"| {labels[s['scale']]} | {s['vendor']} [BR1] | {s['records']:,} | {s['rate']:,} | {s['days']:g} | {'是' if s['within_8'] else '否'} |")
exitt='| 规模 | 方案 | 两年累计保留记录 | 合同导出速率（条/天） | 完整导出天数 | ≤8天 |\n|---|---|---:|---:|---:|:---:|\n'+'\n'.join(exitrows)
(p/'generated_tables.md').write_text('## 两年成本（CNY；内部配置工时按200元/小时计入总成本）\n\n'+cost+'\n\n## 完整退出速度\n\n'+exitt+'\n')
(p/'expected_tables.json').write_text(json.dumps({'cost':cost,'exit':exitt},ensure_ascii=False,indent=2))
