"""Format semantic outputs. No raw database reads and no SQL/semantic bypass."""
from time_series_support import *
from decimal import Decimal

def stock_report(plans):
    known={r['last_entity']:r for r in plans['known']}
    rows=[{'entity':r['entity_key'],'asOfRecord':known.get(r['entity_key'],{}).get('last_date'),
           'quantity':known.get(r['entity_key'],{}).get('quantity')} for r in plans['directory']]
    complete=all(r['quantity'] is not None for r in rows)
    return {'rows':rows,'knownQuantity':sum(r['quantity'] for r in rows if r['quantity'] is not None),
            'coveredEntities':sum(r['quantity'] is not None for r in rows),'totalEntities':len(rows),
            'complete':complete,'totalQuantity':sum(r['quantity'] for r in rows) if complete else None}

def retention_report(plans,end_exclusive):
    # Full calendar months only. end_exclusive must be a first-of-month cutoff.
    from datetime import date
    end=date.fromisoformat(end_exclusive); assert end.day==1
    end_index=end.year*12+end.month-1
    active={(r['first_month'],r['month_offset']):r['active_customers'] for r in plans['retained']}
    rows=[]
    for cohort in plans['sizes']:
        start=cohort['first_month'];size=cohort['cohort_size']
        cells=[]
        for offset in range(3):
            observed=start+offset<end_index
            count=active.get((start,offset),0) if observed else None
            rate=Decimal(count)/Decimal(size) if observed else None
            cells.append({'monthOffset':offset,'observed':observed,'customers':count,'rate':str(rate) if rate is not None else None})
        rows.append({'cohortMonth':f'{start//12:04}-{start%12+1:02}','cohortSize':size,'cells':cells})
    return {'observationEndExclusive':end_exclusive,'meaning':'sample-visible first purchase, monthly purchase recurrence; not login retention or true acquisition','rows':rows}

if __name__=='__main__':
    e=latest()
    def plans(name): return json.loads((e/(name+'-execute.json')).read_text(encoding='utf-8'))['data']['value']['plans']
    for suffix in ['jan4','jan5','empty']:save(e/('19-report-'+suffix+'.json'),stock_report(plans('19-15-separate-'+suffix)))
    for name,end in [('21-01-cohort','2009-07-01'),('21-07-boundary-jan','2024-02-01'),('21-08-boundary-feb','2024-03-01'),('21-09-no-history','2023-01-01'),('21-10-full-chinook','2014-01-01')]:
        save(e/(name+'-report.json'),retention_report(plans(name),end))
    print('Reports saved. These only merge/format exposed results; engine limitations remain recorded.')
