<?php
require DENTAL_ROOT . '/app/bootstrap.php';
require_login();
require_documentation_schema();
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();
$schemaReady = clinical_consent_integrity_schema_ready();
$isDentist = has_role('dentist');
$canDraft = clinical_record_edit_allowed(['dentist','dental_assistant']);
$canDecide = $isDentist;
$patients = patient_options();
$patientId = (int) ($_GET['patient_id'] ?? $_POST['patient_id'] ?? 0);
$itemId = (int) ($_GET['item_id'] ?? $_POST['treatment_plan_item_id'] ?? 0);
$encounterId = (int) ($_GET['encounter_id'] ?? $_POST['encounter_id'] ?? 0);
$returnTo = (string) ($_GET['return'] ?? $_POST['return'] ?? '');
if (!in_array($returnTo, ['', 'clinical'], true)) $returnTo = '';
if ($patientId) require_patient($patientId);

function consent_item(PDO $pdo, int $itemId): ?array
{
    if ($itemId < 1) return null;
    $stmt = $pdo->prepare(
        'SELECT i.*,p.patient_id,p.id treatment_plan_id,p.dentist_user_id plan_dentist_id,p.title plan_title '
        . 'FROM `' . table('treatment_plan_items') . '` i '
        . 'JOIN `' . table('treatment_plans') . '` p ON p.id=i.treatment_plan_id WHERE i.id=? LIMIT 1'
    );
    $stmt->execute([$itemId]);
    return $stmt->fetch() ?: null;
}

function consent_patient_name(PDO $pdo, int $patientId): string
{
    if ($patientId < 1) return '';
    $stmt = $pdo->prepare('SELECT first_name,middle_name,last_name FROM `' . table('patients') . '` WHERE id=? LIMIT 1');
    $stmt->execute([$patientId]);
    $patient = $stmt->fetch();
    if (!$patient) return '';
    return trim(implode(' ', array_filter([
        trim((string)($patient['first_name'] ?? '')),
        trim((string)($patient['middle_name'] ?? '')),
        trim((string)($patient['last_name'] ?? '')),
    ], static fn(string $part): bool => $part !== '')));
}

function consent_sync_item(PDO $pdo, ?int $itemId, string $consentStatus): void
{
    if (!$itemId) return;
    $pdo->prepare('UPDATE `' . table('treatment_plan_items') . '` SET consent_status=?,updated_at=NOW() WHERE id=?')
        ->execute([$consentStatus,$itemId]);
}

function consent_return_path(int $patientId, int $itemId, int $encounterId, string $returnTo): string
{
    if ($returnTo === 'clinical' && $encounterId > 0) {
        return 'clinical_workspace.php?encounter_id=' . $encounterId . '#treatment';
    }
    return 'consents.php?patient_id=' . $patientId
        . ($itemId > 0 ? '&item_id=' . $itemId : '')
        . ($encounterId > 0 ? '&encounter_id=' . $encounterId : '');
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    verify_csrf();
    if (!$schemaReady) {
        $missing = clinical_consent_missing_schema_columns();
        throw new RuntimeException('Consent storage is incomplete. Apply Version 0.5.9.8.6 in System Setup before saving consent.' . ($missing ? ' Missing: ' . implode(', ', $missing) . '.' : ''));
    }
    $action = (string) ($_POST['action'] ?? 'create');

    if ($action === 'create') {
        if (!$canDraft) throw new RuntimeException('You are not authorized to prepare consent records.');
        $patientId = (int) ($_POST['patient_id'] ?? 0);
        require_patient($patientId);
        $itemId = (int) ($_POST['treatment_plan_item_id'] ?? 0);
        $encounterId = (int) ($_POST['encounter_id'] ?? 0);
        $returnTo = (string) ($_POST['return'] ?? '');
        if (!in_array($returnTo, ['', 'clinical'], true)) $returnTo = '';
        if ($itemId < 1 && $encounterId < 1) {
            throw new RuntimeException('Link the consent to an exact treatment-plan item or active clinical encounter.');
        }

        $item = $itemId ? consent_item($pdo, $itemId) : null;
        if ($itemId && (!$item || (int)$item['patient_id'] !== $patientId)) {
            throw new RuntimeException('The selected treatment item does not belong to this patient.');
        }
        if ($item && in_array((string)$item['status'], ['completed','cancelled'], true)) {
            throw new RuntimeException('A new consent cannot be recorded for a completed or cancelled treatment item.');
        }
        if ($encounterId) {
            $stmt = $pdo->prepare('SELECT patient_id,dentist_user_id,status FROM `' . table('clinical_encounters') . '` WHERE id=? LIMIT 1');
            $stmt->execute([$encounterId]);
            $encounter = $stmt->fetch();
            if (!$encounter || (int)$encounter['patient_id'] !== $patientId) throw new RuntimeException('The selected encounter does not belong to this patient.');
            if ((string)$encounter['status'] === 'finalized') throw new RuntimeException('A finalized encounter cannot receive a new treatment consent.');
        }

        $status = (string) ($_POST['status'] ?? 'draft');
        $allowed = $canDecide ? ['draft','requested','signed','declined'] : ['draft','requested'];
        if (!in_array($status, $allowed, true)) throw new RuntimeException('Only the assigned Dentist can record a signed or declined treatment decision.');

        $dentistId = $isDentist ? (int)(current_user()['id'] ?? 0) : (int)($_POST['dentist_user_id'] ?? 0);
        if ($dentistId < 1) throw new RuntimeException('Select the responsible Dentist.');
        if ($isDentist) require_dentist_credentials_verified($dentistId);
        if (!empty($encounter) && !empty($encounter['dentist_user_id']) && (int)$encounter['dentist_user_id'] !== $dentistId) {
            throw new RuntimeException('The responsible Dentist must match the Dentist assigned to the active encounter.');
        }
        if ($item && !empty($item['plan_dentist_id']) && (int)$item['plan_dentist_id'] !== $dentistId) {
            throw new RuntimeException('This consent must be recorded by the Dentist responsible for the treatment plan.');
        }

        $consentType = trim((string) ($_POST['consent_type'] ?? 'Procedure-specific treatment consent'));
        $content = trim((string) ($_POST['content_snapshot'] ?? ''));
        $risks = trim((string) ($_POST['risks_snapshot'] ?? ''));
        $alternatives = trim((string) ($_POST['alternatives_snapshot'] ?? ''));
        $refusal = trim((string) ($_POST['refusal_consequences_snapshot'] ?? ''));
        if ($content === '') throw new RuntimeException('Record the procedure explanation provided to the patient.');

        $signerType = in_array((string)($_POST['signer_type'] ?? ''), ['patient','guardian','authorized_representative'], true)
            ? (string)$_POST['signer_type'] : 'patient';
        $guardianId = (int) ($_POST['guardian_id'] ?? 0);
        $signerName = trim((string) ($_POST['signer_name'] ?? ''));
        $signerRelationship = trim((string) ($_POST['signer_relationship'] ?? ''));
        $identityMethod = trim((string) ($_POST['identity_verification_method'] ?? ''));
        $identityOther = trim((string) ($_POST['identity_verification_other'] ?? ''));
        if ($identityMethod === 'other') $identityMethod = $identityOther;
        $signatureMethod = (string)($_POST['signature_method'] ?? '') === 'in_person_typed' ? 'in_person_typed' : null;
        $signerAcknowledged = isset($_POST['signer_acknowledged']);
        $signatureAttestation = null;
        $questionsAnswered = isset($_POST['questions_answered']) ? 1 : 0;
        $declineReason = trim((string) ($_POST['decline_reason'] ?? ''));
        $expiresAt = trim((string) ($_POST['expires_at'] ?? '')) ?: null;

        if (in_array($status, ['signed','declined'], true)) {
            if ($signerType === 'guardian') {
                if ($guardianId < 1) throw new RuntimeException('Select the verified guardian who is signing.');
                $stmt = $pdo->prepare('SELECT * FROM `' . table('patient_guardians') . '` WHERE id=? AND patient_id=? LIMIT 1');
                $stmt->execute([$guardianId,$patientId]);
                $guardian = $stmt->fetch();
                if (!$guardian || (string)($guardian['verification_status'] ?? 'pending') !== 'verified' || !(int)($guardian['authorized_to_consent'] ?? 0)) {
                    throw new RuntimeException('The selected guardian is not verified and authorized to consent for this patient.');
                }
                if ($signerName === '') $signerName = trim((string)$guardian['name']);
                if ($signerRelationship === '') $signerRelationship = trim((string)($guardian['relationship'] ?? 'Guardian')) ?: 'Guardian';
                if ($identityMethod === '') $identityMethod = 'Verified guardian record and in-person identity confirmation';
            } elseif ($signerType === 'patient') {
                if ($signerName === '') $signerName = consent_patient_name($pdo,$patientId);
                if ($signerRelationship === '') $signerRelationship = 'Self';
                if ($identityMethod === '' && $signatureMethod === 'in_person_typed' && $signerAcknowledged) {
                    $identityMethod = 'Clinic patient record and in-person identity confirmation';
                }
            }
            if ($signerName === '') throw new RuntimeException('Record or select the person who signed the consent.');
            if ($identityMethod === '') throw new RuntimeException('Select how the signer identity was verified.');
            if ($status === 'signed') {
                if (!$signatureMethod || !$signerAcknowledged) throw new RuntimeException('The signer must personally confirm the displayed typed acknowledgment.');
                $signatureAttestation = 'I, ' . $signerName . ', confirm that the proposed procedure, expected benefits, material risks, reasonable alternatives, and consequences of refusal or delay were explained to me; my questions were answered; and I voluntarily consent to the treatment identified in this record.';
                if ($risks === '' || $alternatives === '' || $refusal === '' || !$questionsAnswered) {
                    throw new RuntimeException('Signed consent requires material risks, alternatives, consequences of refusal, and confirmation that questions were answered.');
                }
            }
            if ($status === 'declined' && $declineReason === '') throw new RuntimeException('Record the reason or statement of treatment refusal.');
        }

        $planId = $item ? (int)$item['treatment_plan_id'] : ((int)($_POST['treatment_plan_id'] ?? 0) ?: null);
        $versionStmt = $pdo->prepare(
            'SELECT COALESCE(MAX(version_no),0)+1 FROM `' . table('consent_forms') . '` '
            . 'WHERE patient_id=? AND consent_type=? '
            . 'AND ((treatment_plan_item_id IS NULL AND ? IS NULL) OR treatment_plan_item_id=?) '
            . 'AND ((encounter_id IS NULL AND ? IS NULL) OR encounter_id=?)'
        );
        $versionStmt->execute([$patientId,$consentType,$itemId ?: null,$itemId ?: null,$encounterId ?: null,$encounterId ?: null]);
        $version = max(1,(int)$versionStmt->fetchColumn());
        $signedAt = $status === 'signed' ? date('Y-m-d H:i:s') : null;
        $declinedAt = $status === 'declined' ? date('Y-m-d H:i:s') : null;
        $payload = [
            'patient_id'=>$patientId,'encounter_id'=>$encounterId ?: null,'treatment_plan_id'=>$planId,
            'treatment_plan_item_id'=>$itemId ?: null,'consent_type'=>$consentType,'version_no'=>$version,
            'content_snapshot'=>$content,'risks_snapshot'=>$risks,'alternatives_snapshot'=>$alternatives,
            'refusal_consequences_snapshot'=>$refusal,'signer_name'=>$signerName,'signer_type'=>$signerType,
            'signer_relationship'=>$signerRelationship,'guardian_id'=>$guardianId ?: null,'identity_verification_method'=>$identityMethod,
            'signature_method'=>$signatureMethod,'signature_attestation_snapshot'=>$signatureAttestation,'questions_answered'=>$questionsAnswered,'dentist_user_id'=>$dentistId,
            'procedure_name'=>$item['procedure_name'] ?? null,'tooth_region'=>$item['tooth_region'] ?? null,
            'status'=>$status,'expires_at'=>$expiresAt,'decline_reason'=>$declineReason ?: null,
        ];
        $formHash = clinical_consent_form_hash($payload);
        $signatureHash = $status === 'signed'
            ? hash('sha256',$formHash . '|' . $signerName . '|' . $signedAt . '|' . $dentistId . '|' . (string)$signatureMethod)
            : null;

        $pdo->beginTransaction();
        try {
            if ($itemId) {
                $lock = $pdo->prepare('SELECT id,status FROM `' . table('treatment_plan_items') . '` WHERE id=? FOR UPDATE');
                $lock->execute([$itemId]);
                $locked = $lock->fetch();
                if (!$locked || in_array((string)$locked['status'], ['completed','cancelled'], true)) throw new RuntimeException('The treatment item changed before consent was saved.');
            }
            if(in_array($status,['signed','declined'],true)){
                if($itemId){
                    $pdo->prepare('UPDATE `' . table('consent_forms') . '` SET status=IF(?="signed","expired","withdrawn"),withdrawn_at=IF(?="declined",NOW(),withdrawn_at) WHERE patient_id=? AND treatment_plan_item_id=? AND dentist_user_id=? AND status="signed"')->execute([$status,$status,$patientId,$itemId,$dentistId]);
                }elseif($encounterId){
                    $pdo->prepare('UPDATE `' . table('consent_forms') . '` SET status=IF(?="signed","expired","withdrawn"),withdrawn_at=IF(?="declined",NOW(),withdrawn_at) WHERE patient_id=? AND encounter_id=? AND dentist_user_id=? AND status="signed"')->execute([$status,$status,$patientId,$encounterId,$dentistId]);
                }
            }
            $stmt = $pdo->prepare(
                'INSERT INTO `' . table('consent_forms') . '` '
                . '(patient_id,encounter_id,treatment_plan_id,treatment_plan_item_id,consent_type,version_no,content_snapshot,risks_snapshot,alternatives_snapshot,refusal_consequences_snapshot,signer_name,signer_relationship,signer_type,guardian_id,identity_verification_method,signature_method,signature_attestation_snapshot,questions_answered,status,signed_at,expires_at,declined_at,decline_reason,witness_user_id,dentist_user_id,created_by,signed_by_user_id,form_hash,signature_hash,created_at) '
                . 'VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())'
            );
            $stmt->execute([
                $patientId,$encounterId ?: null,$planId,$itemId ?: null,$consentType,$version,$content,$risks ?: null,
                $alternatives ?: null,$refusal ?: null,$signerName ?: null,$signerRelationship ?: null,$signerType,
                $guardianId ?: null,$identityMethod ?: null,$signatureMethod,$signatureAttestation,$questionsAnswered,$status,$signedAt,$expiresAt,
                $declinedAt,$declineReason ?: null,(int)($_POST['witness_user_id'] ?? 0) ?: null,$dentistId,
                (int)(current_user()['id'] ?? 0),in_array($status,['signed','declined'],true)?(int)(current_user()['id'] ?? 0):null,
                $formHash,$signatureHash,
            ]);
            $id = (int)$pdo->lastInsertId();
            consent_sync_item($pdo,$itemId ?: null,match($status){'signed'=>'accepted','declined'=>'declined','requested'=>'pending',default=>'not_requested'});
            $pdo->commit();
        } catch (Throwable $exception) {
            if ($pdo->inTransaction()) $pdo->rollBack();
            throw $exception;
        }
        audit('procedure_consent_recorded','consent',$id,['patient_id'=>$patientId,'item_id'=>$itemId ?: null,'encounter_id'=>$encounterId ?: null,'status'=>$status,'form_hash'=>$formHash]);
        module_return(consent_return_path($patientId,$itemId,$encounterId,$returnTo),'success',match($status){'signed'=>'Procedure-specific informed consent signed and linked to this treatment.','declined'=>'Treatment refusal recorded.','requested'=>'Consent discussion requested.','draft'=>'Consent draft saved.'});
    }

    if ($action === 'withdraw') {
        if (!$canDecide) throw new RuntimeException('Only the Dentist can withdraw a signed consent.');
        $id = (int) ($_POST['id'] ?? 0);
        $reason = trim((string) ($_POST['withdraw_reason'] ?? ''));
        if (mb_strlen($reason) < 10) throw new RuntimeException('Enter a specific withdrawal reason of at least 10 characters.');
        require_dentist_credentials_verified((int)(current_user()['id'] ?? 0));
        $pdo->beginTransaction();
        try {
            $stmt = $pdo->prepare('SELECT * FROM `' . table('consent_forms') . '` WHERE id=? FOR UPDATE');
            $stmt->execute([$id]);
            $row = $stmt->fetch();
            if (!$row) throw new RuntimeException('Consent record not found.');
            require_patient((int)$row['patient_id']);
            if ((int)$row['dentist_user_id'] !== (int)(current_user()['id'] ?? 0)) throw new RuntimeException('Only the signing Dentist can withdraw this consent.');
            if ((string)$row['status'] !== 'signed') throw new RuntimeException('Only an active signed consent can be withdrawn.');
            if(!empty($row['treatment_plan_item_id'])){
                $itemCheck=$pdo->prepare('SELECT status FROM `' . table('treatment_plan_items') . '` WHERE id=? FOR UPDATE');$itemCheck->execute([(int)$row['treatment_plan_item_id']]);
                if((string)$itemCheck->fetchColumn()==='completed')throw new RuntimeException('Consent cannot be withdrawn after the linked procedure was completed. Record a clinical addendum for later statements.');
            }
            $procedureCheck=$pdo->prepare('SELECT COUNT(*) FROM `' . table('procedures') . '` WHERE consent_form_id=? AND status="completed"');$procedureCheck->execute([$id]);
            if((int)$procedureCheck->fetchColumn()>0)throw new RuntimeException('Consent cannot be withdrawn after a completed procedure used it.');
            $pdo->prepare('UPDATE `' . table('consent_forms') . '` SET status="withdrawn",withdrawn_at=NOW(),decline_reason=? WHERE id=? AND status="signed"')
                ->execute([$reason,$id]);
            consent_sync_item($pdo,!empty($row['treatment_plan_item_id'])?(int)$row['treatment_plan_item_id']:null,'pending');
            $pdo->commit();
        } catch (Throwable $exception) {
            if ($pdo->inTransaction()) $pdo->rollBack();
            throw $exception;
        }
        audit('procedure_consent_withdrawn','consent',$id,['reason'=>$reason]);
        module_return('consents.php?patient_id='.(int)$row['patient_id'].(!empty($row['treatment_plan_item_id'])?'&item_id='.(int)$row['treatment_plan_item_id']:''),'success','Consent withdrawn. Treatment cannot be finalized until a new valid consent is signed.');
    }
}

$items = [];
$guardians = [];
if ($patientId && $schemaReady) {
    $stmt = $pdo->prepare(
        'SELECT i.id,i.procedure_name,i.tooth_region,i.status,i.consent_status,p.id treatment_plan_id,p.title plan_title,p.dentist_user_id '
        . 'FROM `' . table('treatment_plan_items') . '` i JOIN `' . table('treatment_plans') . '` p ON p.id=i.treatment_plan_id '
        . 'WHERE p.patient_id=? AND i.status NOT IN ("completed","cancelled") ORDER BY p.created_at DESC,i.sequence_no,i.id'
    );
    $stmt->execute([$patientId]);
    $items = $stmt->fetchAll();
    $stmt = $pdo->prepare('SELECT id,name,relationship FROM `' . table('patient_guardians') . '` WHERE patient_id=? AND verification_status="verified" AND authorized_to_consent=1 ORDER BY name');
    $stmt->execute([$patientId]);
    $guardians = $stmt->fetchAll();
}

$rows = [];
if ($schemaReady) {
    $sql = 'SELECT c.*,CONCAT(p.first_name," ",p.last_name) patient,d.name dentist,w.name witness,i.procedure_name,i.tooth_region '
        . 'FROM `' . table('consent_forms') . '` c JOIN `' . table('patients') . '` p ON p.id=c.patient_id '
        . 'LEFT JOIN `' . table('users') . '` d ON d.id=c.dentist_user_id LEFT JOIN `' . table('users') . '` w ON w.id=c.witness_user_id '
        . 'LEFT JOIN `' . table('treatment_plan_items') . '` i ON i.id=c.treatment_plan_item_id WHERE 1=1';
    $args = [];
    if ($patientId) { $sql .= ' AND c.patient_id=?'; $args[] = $patientId; }
    if ($itemId) { $sql .= ' AND c.treatment_plan_item_id=?'; $args[] = $itemId; }
    [$scopeSql,$scopeArgs] = task_patient_scope_condition('c.patient_id');
    $sql .= $scopeSql . ' ORDER BY c.created_at DESC LIMIT 100';
    $stmt = $pdo->prepare($sql);
    $stmt->execute(array_merge($args,$scopeArgs));
    $rows = $stmt->fetchAll();
}
$users = $pdo->query('SELECT id,name FROM `' . table('users') . '` WHERE status="active" ORDER BY name')->fetchAll();
$dentists = dentist_options();
$selectedPatientName = '';
foreach ($patients as $patientOption) {
    if ((int)($patientOption['id'] ?? 0) !== $patientId) continue;
    $selectedPatientName = trim(implode(' ', array_filter([
        trim((string)($patientOption['first_name'] ?? '')),
        trim((string)($patientOption['middle_name'] ?? '')),
        trim((string)($patientOption['last_name'] ?? '')),
    ], static fn(string $part): bool => $part !== '')));
    break;
}

render_header('Consent Forms');
render_module_intro('Procedure-specific informed consent','Record the exact procedure, material risks, alternatives, consequences of refusal, signer authority, and immutable signature evidence.',$canDraft&&$schemaReady?'New consent':null,$canDraft&&$schemaReady?'consent-form':null);
render_patient_filter($patients,'consents.php',$patientId);
if (!$schemaReady): ?>
<div class="alert warning"><strong>Version 0.5.9.8.6 consent repair is required.</strong> Open Administration → System Setup → Updates &amp; Database and apply all pending updates before using treatment consent.<?php $missingConsentColumns=clinical_consent_missing_schema_columns(); if($missingConsentColumns): ?><br><small>Missing database fields: <?=e(implode(", ",$missingConsentColumns))?></small><?php endif; ?></div>
<?php else: ?>
<div class="module-card-grid"><?php foreach($rows as $row): ?><article class="module-card">
<div class="card-head"><span class="badge"><?=e(module_status((string)$row['status']))?></span><small>Version <?=e((string)$row['version_no'])?></small></div>
<h3><?=e((string)($row['procedure_name'] ?: $row['consent_type']))?></h3>
<p><?=e((string)$row['patient'])?><?=!empty($row['tooth_region'])?' · '.e((string)$row['tooth_region']):''?></p>
<dl><dt>Signer</dt><dd><?=e((string)($row['signer_name'] ?: 'Pending'))?></dd><dt>Authority</dt><dd><?=e(module_status((string)($row['signer_type'] ?: 'patient')))?></dd><dt>Dentist</dt><dd><?=e((string)($row['dentist'] ?: '—'))?></dd><dt>Signed</dt><dd><?=e($row['signed_at']?date('M j, Y g:i A',strtotime((string)$row['signed_at'])):'—')?></dd><dt>Identity check</dt><dd><?=e((string)($row['identity_verification_method'] ?: '—'))?></dd><dt>Form hash</dt><dd><code><?=e($row['form_hash']?substr((string)$row['form_hash'],0,16).'…':'—')?></code></dd></dl>
<details><summary>Consent evidence</summary><p><strong>Explanation:</strong><br><?=nl2br(e((string)$row['content_snapshot']))?></p><p><strong>Material risks:</strong><br><?=nl2br(e((string)($row['risks_snapshot'] ?: 'Not yet recorded'))) ?></p><p><strong>Alternatives:</strong><br><?=nl2br(e((string)($row['alternatives_snapshot'] ?: 'Not yet recorded'))) ?></p><p><strong>Consequences of refusal:</strong><br><?=nl2br(e((string)($row['refusal_consequences_snapshot'] ?: 'Not yet recorded'))) ?></p><?php if(!empty($row['signature_attestation_snapshot'])): ?><p><strong>Signer acknowledgment:</strong><br><?=nl2br(e((string)$row['signature_attestation_snapshot']))?></p><?php endif; ?><?php if(!empty($row['decline_reason'])): ?><p><strong>Decision/withdrawal note:</strong><br><?=nl2br(e((string)$row['decline_reason']))?></p><?php endif; ?></details>
<?php if($canDecide&&$row['status']==='signed'&&(int)$row['dentist_user_id']===(int)(current_user()['id']??0)): ?><form method="post" class="form-grid"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="withdraw"><input type="hidden" name="id" value="<?=(int)$row['id']?>"><label class="wide">Withdrawal reason<input name="withdraw_reason" required minlength="10" placeholder="Patient withdrew consent before the procedure"></label><button class="btn ghost" data-confirm="Withdraw this consent and block treatment finalization?">Withdraw consent</button></form><?php endif; ?>
</article><?php endforeach; ?><?php if(!$rows): ?><div class="card queue-empty">No consent records found.</div><?php endif; ?></div>
<?php endif; ?>

<?php if($canDraft&&$schemaReady): ?>
<dialog id="consent-form" class="wide-dialog consent-dialog">
<form method="post" class="form-grid consent-transaction-form" data-keyboard-entry data-required-first-entry data-consent-transaction novalidate>
<button type="button" class="dialog-close" data-close aria-label="Close consent form">×</button>
<div class="wide consent-dialog-heading"><span class="eyebrow">Treatment authorization</span><h2>Procedure-specific consent</h2><p>Confirm the treatment context first, then record who made the decision and how the signer identity was verified.</p></div>
<input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="create"><input type="hidden" name="return" value="<?=e($returnTo)?>">
<section class="wide consent-form-section">
  <div class="consent-section-title"><span>1</span><div><strong>Patient and treatment</strong><small>The consent must be linked to this encounter or an exact treatment-plan item.</small></div></div>
  <div class="form-grid compact-form">
    <label>Patient<?php module_patient_select($patients,'patient_id',$patientId,true,'consent-patient-select'); ?></label>
    <label>Responsible Dentist<?php module_dentist_select($dentists,'dentist_user_id',$isDentist?(int)(current_user()['id']??0):0,true); ?></label>
    <label class="wide">Treatment item<select name="treatment_plan_item_id"><option value="">Use active encounter instead</option><?php foreach($items as $item): ?><option value="<?=(int)$item['id']?>" <?=$itemId===(int)$item['id']?'selected':''?>><?=e((string)$item['plan_title'].' — '.(string)$item['procedure_name'].(!empty($item['tooth_region'])?' · '.$item['tooth_region']:''))?></option><?php endforeach; ?></select></label>
    <label>Active encounter ID<input type="number" name="encounter_id" value="<?=$encounterId?:''?>" min="1" inputmode="numeric"></label>
    <label>Consent type<input name="consent_type" value="Procedure-specific treatment consent" required data-required-first></label>
  </div>
</section>
<section class="wide consent-form-section consent-decision-section">
  <div class="consent-section-title"><span>2</span><div><strong>Decision and signer verification</strong><small>Signed and declined decisions require a signer and an identity-verification method.</small></div></div>
  <div class="consent-required-notice" data-consent-required-notice><strong>Complete the signer details below before saving.</strong><span data-consent-required-copy>Choose the decision status to continue.</span></div>
  <div class="form-grid compact-form">
    <label>Status<select name="status" data-consent-status required data-required-first><option value="draft">Draft</option><option value="requested">Requested / discussion pending</option><?php if($canDecide): ?><option value="signed" <?=$returnTo==='clinical'?'selected':''?>>Signed and accepted</option><option value="declined">Declined / refused</option><?php endif; ?></select></label>
    <label>Expires on<input type="date" name="expires_at"></label>
    <label>Signer type<select name="signer_type" data-consent-signer-type><option value="patient">Patient</option><option value="guardian">Verified guardian</option><option value="authorized_representative">Other authorized representative</option></select></label>
    <label data-guardian-field>Verified guardian<select name="guardian_id" data-consent-guardian><option value="">Select verified guardian</option><?php foreach($guardians as $guardian): ?><option value="<?=(int)$guardian['id']?>" data-guardian-name="<?=e((string)$guardian['name'])?>" data-guardian-relationship="<?=e((string)($guardian['relationship']?:'Guardian'))?>"><?=e((string)$guardian['name'].' · '.(string)($guardian['relationship']?:'Guardian'))?></option><?php endforeach; ?></select></label>
    <label>Signer name<input name="signer_name" value="<?=e($selectedPatientName)?>" autocomplete="name" data-consent-signer-name data-required-first></label>
    <label>Signer relationship<input name="signer_relationship" value="<?=$selectedPatientName!==''?'Self':''?>" placeholder="Self, mother, legal guardian" data-consent-signer-relationship></label>
    <label class="wide">How was the signer identity verified?<select name="identity_verification_method" data-consent-identity data-required-first><option value="">Select verification method</option><option value="Clinic patient record and date of birth confirmed">Clinic record and date of birth confirmed</option><option value="Government-issued photo ID checked">Government-issued photo ID checked</option><option value="Portal-authenticated patient account">Portal-authenticated patient account</option><option value="Verified guardian record and in-person identity confirmation">Verified guardian record and in-person confirmation</option><option value="other">Other documented method</option></select></label>
    <label class="wide" data-identity-other-field hidden>Other verification method<input name="identity_verification_other" data-consent-identity-other placeholder="Describe exactly how identity was verified"></label>
    <label>Signature method<select name="signature_method" data-consent-signature-method><option value="">Pending signature</option><option value="in_person_typed" <?=$returnTo==='clinical'?'selected':''?>>In-person typed acknowledgment</option></select></label>
    <label>Witness<select name="witness_user_id"><option value="">No witness selected</option><?php foreach($users as $user): ?><option value="<?=(int)$user['id']?>"><?=e((string)$user['name'])?></option><?php endforeach; ?></select></label>
    <label class="wide check-label"><input type="checkbox" name="questions_answered" value="1" data-consent-questions><span>Questions were answered before the decision.</span></label>
    <label class="wide check-label"><input type="checkbox" name="signer_acknowledged" value="1" data-consent-acknowledged><span>I am the named signer. I personally confirm that the proposed procedure, benefits, material risks, alternatives, and consequences of refusal or delay were explained, my questions were answered, and I voluntarily make the decision recorded here.</span></label>
  </div>
</section>
<section class="wide consent-form-section">
  <div class="consent-section-title"><span>3</span><div><strong>Information explained</strong><small>Use procedure-specific wording. These statements become part of the signed record.</small></div></div>
  <div class="form-grid compact-form">
    <label class="wide">Procedure explanation<textarea name="content_snapshot" rows="3" required data-required-first>The Dentist explained the nature and purpose of the proposed procedure, expected benefits, relevant clinical findings, and what the patient may experience during and after treatment.</textarea></label>
    <label class="wide">Material risks<textarea name="risks_snapshot" rows="3" data-consent-signed-required placeholder="Record risks specific to this procedure and patient"></textarea></label>
    <label class="wide">Reasonable alternatives<textarea name="alternatives_snapshot" rows="3" data-consent-signed-required placeholder="Include no treatment where clinically applicable"></textarea></label>
    <label class="wide">Consequences of refusing or delaying treatment<textarea name="refusal_consequences_snapshot" rows="3" data-consent-signed-required></textarea></label>
    <label class="wide" data-decline-field hidden>Decline/refusal statement<textarea name="decline_reason" rows="2" placeholder="Record the patient or guardian statement and reason for refusal"></textarea></label>
  </div>
</section>
<div class="wide consent-submit-bar"><div><strong data-consent-submit-status>Review required fields</strong><small>The form will focus the first missing item instead of leaving this page.</small></div><button class="btn primary" type="submit">Save consent transaction</button></div>
</form>
</dialog><?php endif; ?>
<?php if(($itemId||$encounterId)&&$canDraft&&$schemaReady&&$returnTo==='clinical'): ?><script>document.addEventListener('DOMContentLoaded',()=>{const d=document.getElementById('consent-form');if(d&&typeof d.showModal==='function'&&!d.open){d.showModal();requestAnimationFrame(()=>window.dentalFocusFirstRequired?.(d));}});</script><?php elseif($itemId&&$canDraft&&$schemaReady): ?><script>document.addEventListener('DOMContentLoaded',()=>{const d=document.getElementById('consent-form');if(d&&typeof d.showModal==='function'&&!document.querySelector('.module-card')){d.showModal();requestAnimationFrame(()=>window.dentalFocusFirstRequired?.(d));}});</script><?php endif; ?>
<?php render_footer();
