# ④ 効率重視・小さめの店：向かい合わない3案（夜 20261108_traffic・80回）を、今のまま・1台・0台と同じ種どうしで比べる
# 使い方: python3 traffic_compare.py   （台帳は KIOXIA の unity_ledger_v1.csv を読むだけ）
import csv, json, os, glob, random, statistics as st, collections
U = os.path.expanduser('~/mnt/KIOXIA/r2r2r-data/service_sim/unity')
R = list(csv.DictReader(open(f'{U}/unity_ledger_v1.csv')))
random.seed(0)

def var(f):
    return "案B'" if '_noT26' in f else '案B' if '_lane' in f else '案A' if '_oneway' in f else '今のまま'

def pick(prefix, rb, a, want=None):
    out = {}
    for r in R:
        f = r['run_folder']
        if not f.startswith(prefix) or r['store'] != 'fam_p2' or r['robots'] != rb or r['arrivals_per_h'] != a or '_ruleb' in f:
            continue
        if want and var(f) != want:
            continue
        out[int(r['seed'])] = r
    return out

M = [('entry_wait_mean', '入店待ち（分）'), ('rescues', '動かしに行った回数'), ('dish_wait_mean', '料理が届くまで（分）'),
     ('walk_km_per_staff', '歩く距離（km/人）'), ('staff_util', '手がふさがる割合')]

def ci(df):
    bs = sorted(st.median(random.choices(df, k=len(df))) for _ in range(3000))
    return bs[75], bs[2924]

result = {}
for a, old in [('28', '20261030_night'), ('36', '20261106_night_a36')]:
    print(f'\n==== 来客 {a}組/時（④・スタッフ2人） ====')
    sets = collections.OrderedDict()
    sets['0台（前の版）'] = pick(old, '0', a)
    sets['1台（前の版）'] = pick(old, '1', a)
    sets['2台（前の版）'] = pick(old, '2', a)
    for v in ['今のまま', '案A', '案B', "案B'"]:
        sets[f'2台 {v}'] = pick('20261108_tr', '2', a, v)
    base = sets['2台 今のまま']; one = sets['1台（前の版）']
    for n, d in sets.items():
        cs = d[min(d)]['unity_cs'] if d else ''
        row = {'n': len(d), 'cs': cs}
        txt = []
        for k, lab in M:
            v = st.median(float(d[i][k]) for i in d)
            row[k] = v
            txt.append(f'{lab} {v:.2f}')
        if n.startswith('2台 ') and n != '2台 今のまま':
            s = sorted(set(d) & set(base))
            for k, lab in M:
                df = [float(d[i][k]) - float(base[i][k]) for i in s]
                lo, hi = ci(df)
                row[k + '_vs_now'] = [st.median(df), lo, hi, sum(x < 0 for x in df), len(s)]
                txt.append(f'今のままとの差（{lab}） 中央{st.median(df):+.2f} 95%[{lo:+.2f},{hi:+.2f}] 減った種{sum(x < 0 for x in df)}/{len(s)}')
        if n != '1台（前の版）':
            s = sorted(set(d) & set(one))
            df = [float(d[i]['entry_wait_mean']) - float(one[i]['entry_wait_mean']) for i in s]
            row['entry_vs_one'] = [st.median(df), sum(x < 0 for x in df), len(s)]
            txt.append(f'1台との差（入店待ち） 中央{st.median(df):+.1f} 1台より短い種{sum(x < 0 for x in df)}/{len(s)}')
        print(f'-- {n}（{len(d)}回・{cs}）'); print('   ' + '\n   '.join(txt))
        result[f'{a}|{n}'] = row

# 1本道で待った時間（案B・B'）
print('\n==== 1本道で待った時間（summary.json の traffic） ====')
G = collections.defaultdict(list)
for f in glob.glob(f'{U}/20261108_tr*_lane*/summary.json'):
    t = json.load(open(f))['traffic']; a = '36' if '_a36_' in f else '28'; v = "案B'" if 'noT26' in f else '案B'
    G[(a, v)].append(t)
for (a, v), ts in sorted(G.items()):
    tot = [x['lane_wait_total_s'] for x in ts]
    print(f'来客{a} {v}: 待った合計 中央{st.median(tot):.0f}秒 最大{max(tot):.0f}秒 / 1回の最長 {max(x["lane_wait_max_s"] for x in ts):.0f}秒 / '
          f'待つと決めた回数 中央{st.median(x["lane_holds"] for x in ts)} / 終わりに待ったまま {sum(x["still_holding_at_end"] for x in ts)}回 / 行けない卓 {sum(len(x["unreachable_tables"]) for x in ts)}')
json.dump(result, open('traffic_compare.json', 'w'), ensure_ascii=False, indent=1)
