<?php
require DENTAL_ROOT . '/app/bootstrap.php';require_login();require_permission('clinical.view',['super_admin','clinic_admin','dentist','dental_assistant']);require DENTAL_ROOT . '/app/layout.php';require DENTAL_ROOT . '/app/module_helpers.php';
$pdo=db();$canScreen=clinical_record_edit_allowed(['dentist','dental_assistant']);$canDentistWrite=clinical_record_edit_allowed(['dentist']);$advanced=documentation_schema_ready();$patients=patient_options();$patientId=(int)($_GET['patient_id']??0);if($patientId)require_patient($patientId);$encounterId=(int)($_GET['id']??0);
if($_SERVER['REQUEST_METHOD']==='POST'){
 verify_csrf();$action=$_POST['action']??'create_encounter';
 if($action==='create_encounter'){throw new RuntimeException('Clinical encounters must be opened from Clinical Day after the patient is checked in and assigned to the treating dentist.');}
 if(!$advanced)throw new RuntimeException('Apply version 0.4.1 to use structured clinical records.');
 if($action==='vitals'){require_clinical_record_editor(['dentist','dental_assistant']);$encounterId=(int)$_POST['encounter_id'];$enc=module_require_encounter_scope($pdo,$encounterId,true);$patientId=(int)$enc['patient_id'];$pdo->prepare('INSERT INTO `' . table('vital_signs') . '` (patient_id,encounter_id,blood_pressure_systolic,blood_pressure_diastolic,pulse_rate,temperature_c,respiratory_rate,weight_kg,pain_score,blood_glucose,pregnancy_status,medical_changes,recorded_by,recorded_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())')->execute([$patientId,$encounterId,$_POST['blood_pressure_systolic']?:null,$_POST['blood_pressure_diastolic']?:null,$_POST['pulse_rate']?:null,$_POST['temperature_c']?:null,$_POST['respiratory_rate']?:null,$_POST['weight_kg']?:null,$_POST['pain_score']?:null,$_POST['blood_glucose']?:null,trim((string)$_POST['pregnancy_status']),trim((string)$_POST['medical_changes']),(int)current_user()['id']]);audit('vital_signs_recorded','clinical_encounter',$encounterId);module_return('clinical.php?patient_id='.$patientId.'&id='.$encounterId,'success','Vital signs recorded.');}
 if($action==='procedure'){throw new RuntimeException('Free-text procedures are disabled. Open the Clinical Treatment Workspace and select an approved service or treatment-plan item.');}
 if($action==='addendum'){$encounterId=(int)$_POST['encounter_id'];$enc=module_require_encounter_scope($pdo,$encounterId,false,true);if(($enc['status']??'')!=='finalized')throw new RuntimeException('Addenda are only used for finalized clinical records. Edit the draft record instead.');if(!active_role_is('dentist')||(int)$enc['dentist_user_id']!==(int)(current_user()['id']??0))throw new RuntimeException('Only the dentist who signed the original record can author this clinical addendum.');$reason=trim((string)$_POST['reason']);$content=trim((string)$_POST['content']);if($reason===''||$content==='')throw new RuntimeException('Enter the addendum reason and content.');$profile=dentist_profile((int)current_user()['id'])?:[];$authorName=$profile?dentist_display_name($profile):(string)(current_user()['name']??'Dentist');$license=trim((string)($profile['license_number']??''))?:null;$signature=trim((string)($profile['signature_path']??''))?:null;$signedAt=date('Y-m-d H:i:s');$hash=hash('sha256',$encounterId.'|'.$reason.'|'.$content.'|'.(current_user()['id']??0).'|'.$signedAt);$pdo->prepare('INSERT INTO `' . table('clinical_note_addenda') . '` (encounter_id,reason,content,author_user_id,author_name_snapshot,author_license_snapshot,signature_path_snapshot,signed_at,addendum_hash,created_at) VALUES (?,?,?,?,?,?,?,?,?,NOW())')->execute([$encounterId,$reason,$content,(int)current_user()['id'],$authorName,$license,$signature,$signedAt,$hash]);audit('clinical_addendum_added','clinical_encounter',$encounterId,['signed_at'=>$signedAt,'hash'=>$hash]);module_return('clinical.php?id='.$encounterId,'success','Signed addendum added without changing the original record.');}
}
$encounter=null;$vitals=$procedures=$addenda=[];if($encounterId){$stmt=$pdo->prepare('SELECT c.*,CONCAT(p.first_name," ",p.last_name) patient,p.patient_no,p.medical_alerts FROM `' . table('clinical_encounters') . '` c JOIN `' . table('patients') . '` p ON p.id=c.patient_id WHERE c.id=?');$stmt->execute([$encounterId]);$encounter=$stmt->fetch();if($encounter){module_require_encounter_scope($pdo,$encounterId,false,true);}if($encounter&&$advanced){$stmt=$pdo->prepare('SELECT v.*,u.name recorder FROM `' . table('vital_signs') . '` v LEFT JOIN `' . table('users') . '` u ON u.id=v.recorded_by WHERE encounter_id=? ORDER BY recorded_at DESC');$stmt->execute([$encounterId]);$vitals=$stmt->fetchAll();$stmt=$pdo->prepare('SELECT * FROM `' . table('procedures') . '` WHERE encounter_id=? ORDER BY created_at');$stmt->execute([$encounterId]);$procedures=$stmt->fetchAll();$stmt=$pdo->prepare('SELECT a.*,u.name author FROM `' . table('clinical_note_addenda') . '` a LEFT JOIN `' . table('users') . '` u ON u.id=a.author_user_id WHERE encounter_id=? ORDER BY created_at');$stmt->execute([$encounterId]);$addenda=$stmt->fetchAll();}}
if($encounter){$patientId=(int)$encounter['patient_id'];}
$dentists=dentist_options();render_header('Clinical Records');render_module_intro('Clinical encounters','Examination, diagnosis, SOAP documentation, procedures, vital signs, and immutable addenda. Open new encounters from Clinical Day after check-in.');render_patient_filter($patients,'clinical.php',$patientId);
if($patientId){
    $selectedPatient=null;foreach($patients as $patientOption){if((int)$patientOption['id']===$patientId){$selectedPatient=$patientOption;break;}}
    ?><section class="card patient-clinical-context"><div class="card-head"><div><span class="eyebrow">Selected patient context</span><h2><?=e($selectedPatient?patient_full_name($selectedPatient):'Patient #'.$patientId)?></h2><p>All related treatment records below keep this patient selected.</p></div></div><div class="status-actions"><a class="btn ghost" href="clinical.php?patient_id=<?=$patientId?>">All encounters</a><a class="btn ghost" href="treatment.php?patient_id=<?=$patientId?>">Treatment plans</a><a class="btn ghost" href="odontogram.php?patient_id=<?=$patientId?>">Odontogram</a><a class="btn ghost" href="prescriptions.php?patient_id=<?=$patientId?>">Prescriptions</a><a class="btn ghost" href="consents.php?patient_id=<?=$patientId?>">Consents</a><a class="btn ghost" href="patients.php?action=view&id=<?=$patientId?>&amp;tab=clinical">Patient profile</a></div></section><?php
}
if($encounter):?><section class="card"><div class="card-head"><div><h2><?=e($encounter['patient'])?></h2><p><?=e($encounter['patient_no'])?> · <?=e($encounter['dentist_name'])?> · <?=e(date('M j, Y g:i A',strtotime($encounter['created_at'])))?></p></div><span class="badge"><?=e(module_status($encounter['status']))?></span></div><?php if($encounter['medical_alerts']):?><div class="alert error"><strong>Dental safety alerts</strong><br><?=nl2br(e($encounter['medical_alerts']))?></div><?php endif;?><div class="record-grid"><div><h3>Chief complaint</h3><p><?=nl2br(e($encounter['chief_complaint']))?></p></div><div><h3>Diagnosis</h3><p><?=nl2br(e($encounter['diagnosis']))?></p></div><div><h3>Examination</h3><p><?=nl2br(e($encounter['examination']))?></p></div><div><h3>Treatment plan</h3><p><?=nl2br(e($encounter['treatment_plan']))?></p></div><div class="wide"><h3>SOAP note</h3><p><?=nl2br(e($encounter['soap_note']))?></p></div></div><?php if($advanced):?><div class="status-actions"><?php if($encounter['status']!=='finalized'&&$canScreen):?><a class="btn ghost" href="clinical_workspace.php?encounter_id=<?=$encounterId?>&amp;patient_id=<?=(int)$encounter['patient_id']?>&amp;focus=intake#intake">Record / review vital signs</a><?php endif;?><?php if($encounter['status']!=='finalized'&&$canDentistWrite):?><a class="btn primary" href="clinical_workspace.php?encounter_id=<?=$encounterId?>&amp;patient_id=<?=(int)$encounter['patient_id']?>#treatment">Open Treatment Workspace</a><?php endif;?><?php if($encounter['status']==='finalized'&&active_role_is('dentist')&&(int)$encounter['dentist_user_id']===(int)(current_user()['id']??0)):?><button class="btn primary" data-open="addendum-form">Add signed addendum</button><?php endif;?><a class="btn ghost" href="odontogram.php?patient_id=<?=(int)$encounter['patient_id']?>&amp;encounter_id=<?=$encounterId?>">Open dental chart</a></div><?php endif;?></section><?php if($advanced):?><div class="record-grid"><section class="card"><h2>Vital signs</h2><?php foreach($vitals as $row):[$bpSys,$bpDia,$bpRepeated]=clinical_vitals_effective_bp($row);?><article class="timeline-item"><h4><?=$bpSys!==null?e((string)$bpSys).'/'.e((string)$bpDia).' mmHg':'Screening'?><?=$bpRepeated?' · repeat':''?></h4><p>Pulse <?=e((string)($row['pulse_rate']??'—'))?> bpm · SpO₂ <?=e((string)($row['oxygen_saturation']??'—'))?>% · Temperature <?=e((string)($row['temperature_c']??'—'))?> °C · Pain <?=e((string)($row['pain_score']??'—'))?>/10<?=isset($row['bmi'])&&$row['bmi']!==null?' · BMI '.e((string)$row['bmi']):''?></p><small><?=e(date('M j, Y g:i A',strtotime($row['recorded_at'])))?> · <?=e($row['recorder']?:'Staff')?></small></article><?php endforeach;?></section><section class="card"><h2>Procedures</h2><?php foreach($procedures as $row):?><article class="timeline-item"><h4><?=e($row['procedure_name'])?> <?=e($row['tooth_region'])?></h4><p><?=nl2br(e($row['outcome']))?></p><span class="badge"><?=e(module_status($row['status']))?></span></article><?php endforeach;?></section><section class="card wide"><h2>Addenda</h2><?php foreach($addenda as $row):?><article class="timeline-item"><h4><?=e($row['reason'])?></h4><p><?=nl2br(e($row['content']))?></p><small><?=e($row['author']?:'Staff')?> · <?=e(date('M j, Y g:i A',strtotime($row['created_at'])))?></small></article><?php endforeach;?><?php if(!$addenda):?><p class="muted">No addenda.</p><?php endif;?></section></div><?php endif;?>
<?php else:?><div class="card table-wrap"><table><thead><tr><th>Date</th><th>Patient</th><th>Dentist</th><th>Diagnosis</th><th>Status</th><th></th></tr></thead><tbody><?php $sql='SELECT c.*,CONCAT(p.first_name," ",p.last_name) patient FROM `' . table('clinical_encounters') . '` c JOIN `' . table('patients') . '` p ON p.id=c.patient_id WHERE 1=1';$args=[];if($patientId){$sql.=' AND c.patient_id=?';$args[]=$patientId;}[$scopeSql,$scopeArgs]=task_patient_scope_condition('c.patient_id');$sql.=$scopeSql;$args=array_merge($args,$scopeArgs);$sql.=' ORDER BY c.created_at DESC LIMIT 100';$stmt=$pdo->prepare($sql);$stmt->execute($args);foreach($stmt as $row):?><tr><td><?=e(date('M j, Y',strtotime($row['created_at'])))?></td><td><?=e($row['patient'])?></td><td><?=e($row['dentist_name'])?></td><td><?=e($row['diagnosis'])?></td><td><span class="badge"><?=e(module_status($row['status']))?></span></td><td><a href="clinical.php?patient_id=<?=(int)$row['patient_id']?>&amp;id=<?=(int)$row['id']?>">Open</a></td></tr><?php endforeach;?></tbody></table></div><?php endif;?>
<?php if($advanced&&$encounter):?><dialog id="addendum-form" class="wide-dialog"><form method="post" class="form-grid"><button type="button" class="dialog-close" data-close>×</button><h2 class="wide">Add clinical addendum</h2><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="addendum"><input type="hidden" name="encounter_id" value="<?=$encounterId?>"><label class="wide">Reason<input name="reason" required></label><label class="wide">Addendum<textarea name="content" required></textarea></label><button class="btn primary">Add without changing original note</button></form></dialog><?php endif;?>
<?php render_footer();
