"""Case evidence projected into the existing stage cards and conversations."""
from pathlib import Path
import copy
import json

HERE=Path(__file__).resolve().parent
PACKS=json.loads((HERE/'case-content.json').read_text(encoding='utf-8'))['cases']


def content_for(case):
    p=copy.deepcopy(PACKS[case['id']])
    p.setdefault('sources',[{'path':'aisa-next/10 Architecture/'+case['source'],'label':case['id']+' evidence, mechanism and delivery census'}])
    p.setdefault('basis','Representative proposed run grounded in the documented case family. Findings and success states illustrate the required checks; they are not new live observations.')
    p.setdefault('similar',case['next'])
    p['falsifier']=case['falsifier']
    return p


CONFIG_FOCUS={
 'S2':('Rating and version selection','Prepare the declared rating/version work; retain the actual template and effective-date inputs.','Rating evidence is a stage result, not proof that offers, access or target delivery are complete.'),
 'S3':('Product catalogue and mapping','Prepare only the catalogue, factor, control or seam relationships this stage owns.','Return populated catalogue/mapping evidence; unrelated stages and external work remain separate obligations.'),
 'S4':('Offer and selection rules','Prepare the package/offer selection and constraint delta against its current rating baseline.','Return allowed/forbidden selection evidence and the resolved tariff mapping.'),
 'S5':('Wiring and visibility','Prepare the requested routes, labels, numbering or print wiring and its external dependencies.','Return evidence from the consuming interface; a row by itself does not prove visible behaviour.')}


def narrative(case,journey,s):
    p=journey['ui']['content'];module=s['module'];sid=s['stage'];protocol=s['protocol']
    if case['mode']=='core':
        commercial={            'O1':('Assess required effort','Inspect the current source/dependencies and comparable work. Effort ranges are not yet established by this archive; do not invent them.'),
                    'O2':('Prepare the offer','Bind assessed work to the owner’s actual price/effort basis, delivery terms and exclusions. Missing terms remain open.'),
                    'O3':('Customer offer decision','Offer approval stays unavailable until scope, assessment and owner terms are complete. Approval is commercial, not implementation authority.'),
                    'O4':('Communicate the decision','After the customer decision, communicate the exact accepted/rejected terms and next owner. There is no code implementation step.')}
        heading,body=commercial.get(sid,('Assessment & Offers',p['public_result']))
        rows=[('Scope/evidence',p['findings'][0]),('Effort and offer','Assessment and owner terms pending; no invented figures'),('Customer decision','Not yet available; no complete offer revision')]
        return {'phase':'commercial','heading':heading,'body':body,'operator_message':'Work the proposal in the declared stages; keep missing owner terms and estimate uncertainty visible.',
                'agent_message':body,'root_message':'I retain the original request. Assessment and offer work remains inside this Support case.',
                'previous_message':'The evidence describes shared behaviour: '+p['findings'][0],
                'steps':p['steps'],'rows':rows,'proof':False,'next_action':body,'recovery':p['recovery'],
                'sources':p['sources'],'basis':p['basis'],'similar':p['similar'],'failure':p['failure']}
    phase='work'
    if module=='support':phase={'S1':'arrival','route':'route','closure':'delivery'}[sid]
    elif module=='data':phase={'S2':'investigate','S3':'choice' if '/return' in s['uid'] or protocol=='decision' else 'take','S4':'confirm','S5':'application','S6':'verify','S7':'recover','S8':'learn'}[sid]
    elif module=='configuration':phase='scope' if sid=='S1' else 'preview' if sid=='joint' else 'release' if sid=='release' else 'stage'
    elif module=='source':phase={'S1':'investigate','S2':'confirm','S3':'implement','S4':'review','S5':'release-plan','S6':'release','S7':'verify','S8':'recover'}.get(sid,'learn')
    if protocol=='learning':phase='learn'
    if protocol=='referral':phase='referral'
    if protocol=='reversal':phase='recover'
    if protocol=='application_result':phase='application-result'
    if protocol=='external_report':phase='external-report'
    if protocol=='verification' and module=='configuration':phase='verify'
    if protocol=='send' and module=='support':phase='send'
    if protocol=='scope':phase='scope'
    if protocol=='preview':phase='preview'
    instruction=p['solution'];steps=p['steps'];rows=[];proof=False
    heading=s['label'];body=p['failure'];operator='The request is: '+journey['ui']['request']
    agent='';next_action=''
    if phase in ('arrival','route'):
        heading='The reported problem and requested result';body=p['failure']
        agent='I have classified this as '+journey['ui']['working_module']+' work. '+(journey['ui']['routing_exception']['reason'] if journey['ui']['routing_exception'] else 'The cause still needs current evidence; the request alone does not select a repair.')
        rows=[('Customer asks',journey['ui']['request']),('Failure to resolve',p['failure']),('Required outcome',journey['ui']['outcome'])]
    elif phase=='take':
        heading='A related method exists; first establish which failure this is'
        body=p.get('take','The request resembles a known '+case['title'].lower()+' case. A matching symptom is not yet a proved mechanism.')
        agent=p.get('take_decision','I cannot choose the remedy from the request alone. I will establish: '+p['findings'][0])
        rows=[('Reported',p['failure']),('Still to establish',p['findings'][0]),('Decision before acting',p.get('take_decision','Run the current evidence checks before selecting: '+p['solution']))]
        steps=p.get('take_steps',['Check against current evidence: '+x for x in p['findings']])
    elif phase in ('investigate','scope','referral'):
        heading='What the evidence establishes' if phase=='investigate' else 'Scope and dependencies to confirm'
        body=p['failure'];agent='The relevant evidence is: '+' '.join(p['findings'])
        rows=[('Evidence '+str(i+1),x) for i,x in enumerate(p['findings'])]
        operator=p.get('operator_question','Separate the reported symptom from the mechanism. In particular, do not accept this shortcut: '+p['falsifier'])
    elif phase=='choice':
        heading='The selected solution and the rejected shortcut';body=p['solution'];agent='The evidence supports this remedy: '+p['solution']
        rows=[('Chosen remedy',p['solution']),('Rejected shortcut',p['falsifier']),('Retained dependency',p['steps'][-1])]
        operator='The investigation changes the proposal: '+p['solution']+' Keep its recovery and customer-result checks in the packet.'
    elif phase in ('confirm','release-plan','review'):
        heading='Review the concrete plan' if phase!='review' else 'Review the change against its original failure';body=p['solution']
        agent='The packet contains these bounded steps: '+' '.join(p['steps'])
        rows=[('Step '+str(i+1),x) for i,x in enumerate(p['steps'])]
        operator='Approve only this scope. The counterexample that must remain blocked is: '+p['falsifier']
    elif phase in ('application','release'):
        waiting=protocol=='external';heading='The assigned action and required receipt' if waiting else 'Before dispatch: exact action and expected evidence'
        body=p['solution'];agent=('The assigned owner is '+str(journey['ui']['external_owner'])+'. ' if waiting else 'No execution is claimed by showing this packet. ')+p['steps'][1]
        rows=[('Required action '+str(i+1),x) for i,x in enumerate(p['steps'])]
        next_action='Record what actually landed, then check: '+p['checks'][0]
    elif phase in ('application-result','external-report'):
        heading='Execution evidence received; verification still follows';body=p.get('archive_result','The positive replay records the declared action receipt. Independent target verification is still required.')
        agent='Keep the actor and effect receipt distinct from verification. '+p['steps'][-1]
        rows=[('Action recorded',p['steps'][1]),('Outcome evidence',p.get('archive_result','The actor reports the scoped action complete; the next stage checks the target.')),('Still to prove',p['checks'][0])]
    elif phase in ('verify','preview','delivery','test'):
        heading={'verify':'The result checked against the original problem','preview':'Working preview: the joined checks','delivery':'The delivered result and remaining lesson','test':'Tests for the reproduced failure'}[phase]
        body=p.get('archive_result',p['solution']) if phase=='delivery' else p['solution']
        agent='The acceptance checks are specific to this failure: '+' '.join(p['checks'])
        rows=[('Check '+str(i+1),x) for i,x in enumerate(p['checks'])];proof=True
        if phase=='test':body='These checks concern the prepared change; target delivery is still open. '+p['failure']
        if journey['ui']['restoration_required'] and module=='data' and sid=='S6':
            rows[-1]=('Restoration still required','S7 must restore and prove the captured baseline before resolution.');proof=False
    elif phase=='recover':
        heading='The recovery for this effect';body=p['recovery'];agent='Use the original effect and current target evidence. '+p['recovery']
        rows=[('Recovery scope',p['recovery']),('Do not repeat',p['falsifier']),('Re-check afterwards',p['checks'][0])]
        steps=[p['recovery'],'Reconcile the current target against the recorded before/after values.','Run the affected checks again and retain any irreversible residue.']
    elif phase=='learn':
        heading='What this case teaches the next request';body=p['memory'];agent='The retained change separates knowledge, method and mechanics: '+p['memory']+' '+p['skill']+' '+p['tool']
        rows=[('Memory',p['memory']),('Skill',p['skill']),('Tool candidate',p['tool'])];steps=[p['memory'],p['skill'],p['tool']]
    elif phase=='implement':
        heading='Implement the change that removes this failure';body=p['solution'];agent=p['steps'][1]
        rows=[('Reproduced failure',p['failure']),('Implementation scope',p['steps'][1]),('Regression to preserve',p['checks'][1])]
    elif phase=='stage':
        focus=CONFIG_FOCUS[sid];specific=p.get('stage_work',{}).get(sid)
        heading=focus[0]+' for this request';body=p['solution'];agent=specific or (focus[1]+' '+p['steps'][1])
        rows=[('Stage work',agent),('Case evidence',p['findings'][{'S2':0,'S3':1,'S4':1,'S5':2}[sid]]),('Stage boundary',focus[2])]
        if specific:steps=[specific,p['checks'][{'S2':0,'S3':1,'S4':0,'S5':1}[sid]],focus[2]]
    elif phase=='send':
        heading='Approve the reply with the actual outcome';body=p['solution'];agent='The message must distinguish completed work and any remaining dependency. '+p.get('archive_result',p['checks'][0])
        rows=[('Result to state',p['solution']),('Evidence to cite',p['checks'][0]),('Still retained',p['memory'])]
    else:
        agent=p['steps'][1];rows=[('Failure',p['failure']),('Work',agent),('Required check',p['checks'][0])]
    root_message=('The reported request is: '+journey['ui']['request']+' '+p.get('take_decision','The current evidence must establish the mechanism before the remedy is selected.')) if phase in ('arrival','route','take') else instruction
    if phase in ('investigate','scope'):root_message='Establish the current evidence and any unresolved input for this failure: '+p['failure']
    if phase=='choice':root_message='Use the investigation to select the narrow remedy and reject the shortcut: '+p['falsifier']
    if phase in ('verify','test','preview'):root_message='Check the promised result independently of the action report. '+p['checks'][0]
    if phase=='learn':root_message='Retain the mechanism and the reusable checks, with this case as evidence. '+p['memory']
    previous={'choice':'Investigation returned: '+' '.join(p['findings']),
              'confirm':'Solution take selected: '+p['solution'],
              'application':'The solution packet covers: '+p['solution']+' Its confirmation does not replace the current effect/send authority.',
              'verify':'The preceding action must supply a receipt for: '+p['steps'][1]+' The checks below establish the customer result.',
              'learn':'The result to learn from was tested by: '+p['checks'][0]}.get(phase,'')
    return {'phase':phase,'heading':heading,'body':body,'operator_message':operator,
        'agent_message':agent,'root_message':root_message,'previous_message':previous,'steps':steps,'rows':[{'label':a,'value':b} for a,b in rows],
        'proof':proof,'next_action':next_action or p['steps'][-1],'recovery':p['recovery'],
        'sources':p['sources'],'basis':p['basis'],'similar':p['similar'],'failure':p['falsifier']}
