#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Within-molecule US/EU starch source disclosure comparison + exact McNemar."""
import json, re, sys, collections
from math import comb

S = re.compile(r'starch|amylum|dextrin|dextrate', re.I)
SRC = ('maize','corn','potato','wheat','rice','tapioca','pea')

def sourced(terms):
    return any(s in t.lower() for t in terms for s in SRC)

def main():
    us = json.load(open('us_excip_cache.json'))
    rec = json.load(open('ema_data.json'))['records']
    eu = collections.defaultdict(list)
    for v in rec.values():
        inn = (v.get('inn') or '').strip().lower()
        if inn:
            eu[inn] += [x for x in v.get('excipients', []) if S.search(x)]

    rows = []
    for inn, d in us.items():
        if not d.get('ok'): continue
        ust = sorted({x for x in d['excipients'] if S.search(x)})
        eut = sorted(set(eu.get(inn, [])))
        if not ust or not eut: continue
        rows.append({'inn': inn, 'us_starch_terms': ust, 'eu_starch_terms': eut,
                     'us_sourced': sourced(ust), 'eu_sourced': sourced(eut)})

    n = len(rows)
    b = sum(1 for r in rows if r['us_sourced'] and not r['eu_sourced'])
    c = sum(1 for r in rows if r['eu_sourced'] and not r['us_sourced'])
    disc = b + c
    p = (sum(comb(disc, k) for k in range(min(b, c) + 1)) / 2 ** disc * 2) if disc else 1.0

    out = {'paired_molecules': n,
           'us_disclosure_pct': round(100 * sum(r['us_sourced'] for r in rows) / n, 1),
           'eu_disclosure_pct': round(100 * sum(r['eu_sourced'] for r in rows) / n, 1),
           'both': sum(1 for r in rows if r['us_sourced'] and r['eu_sourced']),
           'us_only': b, 'eu_only': c,
           'neither': sum(1 for r in rows if not r['us_sourced'] and not r['eu_sourced']),
           'mcnemar_exact_two_sided_p': p}
    json.dump(rows, open('paired_rows.json', 'w'), indent=1)
    json.dump(out, sys.stdout, indent=2); print()

if __name__ == '__main__':
    main()
