<?php

declare(strict_types=1);

/**
 * Dentist treatment-path guidance and service rules.
 *
 * This file is intentionally schema-safe. It does not create new tables; it
 * classifies the clinic's service catalog so the Dentist sees what each visit
 * requires before trying to finalize the encounter.
 */

function treatment_path_builtin_services(): array
{
    return [
        ['name' => 'Dental Examination', 'provider_type' => 'dentist', 'duration_minutes' => 30, 'category' => 'Consultation / examination'],
        ['name' => 'Oral Prophylaxis', 'provider_type' => 'dentist', 'duration_minutes' => 45, 'category' => 'Preventive care'],
        ['name' => 'Tooth Restoration', 'provider_type' => 'dentist', 'duration_minutes' => 60, 'category' => 'Restorative'],
        ['name' => 'Tooth Extraction', 'provider_type' => 'dentist', 'duration_minutes' => 60, 'category' => 'Oral surgery'],
        ['name' => 'Root Canal Consultation', 'provider_type' => 'dentist', 'duration_minutes' => 60, 'category' => 'Endodontics'],
        ['name' => 'Orthodontic Consultation', 'provider_type' => 'dentist', 'duration_minutes' => 45, 'category' => 'Orthodontics'],
        ['name' => 'Denture Consultation', 'provider_type' => 'dentist', 'duration_minutes' => 45, 'category' => 'Prosthodontics'],
        ['name' => 'Emergency Dental Visit', 'provider_type' => 'dentist', 'duration_minutes' => 60, 'category' => 'Emergency'],
    ];
}

function treatment_path_default_rule(): array
{
    return [
        'type' => 'general_dental',
        'label' => 'General dental visit',
        'odontogram' => 'Review current chart. Use No changes when healthy/unchanged, otherwise update findings.',
        'tooth_required' => false,
        'consent_required' => 'When treatment is performed',
        'procedure_required' => 'Only when a procedure is actually performed today',
        'diagnosis_hint' => 'Record diagnosis, observation, referral, or healthy/no active disease decision.',
        'disposition_hint' => 'Choose what happened today: treatment, advice only, no treatment, deferred, referral, or emergency stabilization.',
        'prescription_hint' => 'Issue medication only when clinically indicated, otherwise mark No prescription required.',
        'followup_hint' => 'Choose follow-up recommended or no follow-up required.',
    ];
}

function treatment_path_rule_for_service_name(string $serviceName, string $providerType = 'dentist'): array
{
    $name = strtolower(trim($serviceName));
    $providerType = strtolower(trim($providerType ?: 'dentist'));
    if ($providerType === 'inhouse') {
        return [
            'type' => 'inhouse_screening',
            'label' => 'In-house screening / support service',
            'odontogram' => 'Not required unless the visit is handed to the Dentist for dental findings.',
            'tooth_required' => false,
            'consent_required' => 'Not treatment consent; use clinic policy for screening acknowledgement.',
            'procedure_required' => false,
            'diagnosis_hint' => 'Assistant/staff records screening findings. Dentist diagnosis is required only after dental referral.',
            'disposition_hint' => 'Complete screening, refer to Dentist when abnormal or requested.',
            'prescription_hint' => 'Not applicable for assistant/staff screening.',
            'followup_hint' => 'Refer or monitor based on clinic protocol.',
        ];
    }
    $rules = [
        '/\b(exam|consult|consultation|check\s*up|assessment)\b/' => [
            'type' => 'examination', 'label' => 'Examination / consultation', 'tooth_required' => false,
            'odontogram' => 'Must be reviewed. Healthy patients pass with Reviewed today — no changes / healthy dentition.',
            'consent_required' => 'Not required unless a procedure is performed today.',
            'procedure_required' => false,
            'diagnosis_hint' => 'Use Healthy dentition / no active dental disease, observation, or specific diagnosis.',
            'disposition_hint' => 'Usually examination only, no treatment required, observation, referral, or treatment advised.',
            'prescription_hint' => 'Usually not required unless medication is clinically indicated.',
            'followup_hint' => 'Set recall/follow-up or mark none.',
        ],
        '/\b(prophy|prophylaxis|clean|scal|polish)\b/' => [
            'type' => 'preventive', 'label' => 'Oral prophylaxis / cleaning', 'tooth_required' => false,
            'odontogram' => 'Review baseline; update only if calculus, caries, mobility, missing teeth, or restorations are found.',
            'consent_required' => 'Encounter/procedure consent required when clinic policy requires it.',
            'procedure_required' => true,
            'diagnosis_hint' => 'Healthy dentition, plaque/calculus, gingivitis, or other finding.',
            'disposition_hint' => 'Treatment performed today or examination/advice only.',
            'prescription_hint' => 'Normally not required unless medication is prescribed.',
            'followup_hint' => 'Recall interval or no follow-up.',
        ],
        '/\b(restor|filling|composite|amalgam|cavity|caries)\b/' => [
            'type' => 'restorative', 'label' => 'Restoration / filling', 'tooth_required' => true,
            'odontogram' => 'Select affected tooth/surface or continue a planned restoration. Completed restoration should update chart.',
            'consent_required' => 'Required before finalization unless documented emergency exception.',
            'procedure_required' => true,
            'diagnosis_hint' => 'Caries/defective restoration/fracture diagnosis with tooth and surface.',
            'disposition_hint' => 'Treatment performed, deferred, or treatment advised/declined.',
            'prescription_hint' => 'Usually not required unless clinically indicated.',
            'followup_hint' => 'Follow-up if sensitivity, multi-visit, or further treatment is needed.',
        ],
        '/\b(extract|surgery|surgical|impacted)\b/' => [
            'type' => 'oral_surgery', 'label' => 'Extraction / oral surgery', 'tooth_required' => true,
            'odontogram' => 'Select the tooth. Completed extraction should mark tooth as extracted/missing in chart history.',
            'consent_required' => 'Required before finalization unless documented emergency exception.',
            'procedure_required' => true,
            'diagnosis_hint' => 'Indication for extraction linked to tooth/region.',
            'disposition_hint' => 'Treatment performed, emergency stabilization, deferred, or referred.',
            'prescription_hint' => 'Often considered; issue prescription or mark No prescription required.',
            'followup_hint' => 'Follow-up decision required; post-op monitoring/recall as needed.',
        ],
        '/\b(root\s*canal|endo|pulp|rct)\b/' => [
            'type' => 'endodontic', 'label' => 'Root canal / endodontic care', 'tooth_required' => true,
            'odontogram' => 'Select tooth and prior finding/planned RCT. Multi-visit progress should carry forward.',
            'consent_required' => 'Required before finalization unless documented emergency exception.',
            'procedure_required' => true,
            'diagnosis_hint' => 'Pulpal/periapical diagnosis linked to tooth.',
            'disposition_hint' => 'Consultation, treatment performed, deferred, or referred.',
            'prescription_hint' => 'Issue medication only when indicated, otherwise mark not required.',
            'followup_hint' => 'Usually follow-up or next appointment when multi-visit.',
        ],
        '/\b(ortho|braces|aligner)\b/' => [
            'type' => 'orthodontic', 'label' => 'Orthodontic consultation/treatment', 'tooth_required' => false,
            'odontogram' => 'Review baseline dentition; record occlusion/crowding findings rather than forcing every tooth.',
            'consent_required' => 'Required for treatment start; consult may not need procedure consent.',
            'procedure_required' => 'Only if appliance/treatment is started today.',
            'diagnosis_hint' => 'Malocclusion/crowding/spacing or orthodontic assessment.',
            'disposition_hint' => 'Consultation, treatment plan, treatment performed, deferred, or referred.',
            'prescription_hint' => 'Usually not required.',
            'followup_hint' => 'Treatment planning or adjustment schedule.',
        ],
        '/\b(denture|prostho|crown|bridge)\b/' => [
            'type' => 'prosthodontic', 'label' => 'Denture / prosthodontic care', 'tooth_required' => false,
            'odontogram' => 'Review missing teeth/restorations; update abutment/missing/restored teeth only when changed.',
            'consent_required' => 'Required for procedure/work start; consult may not need procedure consent.',
            'procedure_required' => 'Only when clinical procedure/lab step is performed today.',
            'diagnosis_hint' => 'Edentulism, missing teeth, prosthesis concern, or consult finding.',
            'disposition_hint' => 'Consultation, impression/procedure performed, deferred, or referred.',
            'prescription_hint' => 'Usually not required.',
            'followup_hint' => 'Try-in, adjustment, or delivery schedule when needed.',
        ],
        '/\b(emergency|pain|urgent|trauma)\b/' => [
            'type' => 'emergency', 'label' => 'Emergency dental visit', 'tooth_required' => 'If localized',
            'odontogram' => 'Select pain tooth/area if known, or mark area not localized with reason.',
            'consent_required' => 'Required for treatment unless emergency exception is documented.',
            'procedure_required' => 'Required only if treatment/stabilization is performed.',
            'diagnosis_hint' => 'Emergency diagnosis, pain source, trauma, infection, or undetermined source.',
            'disposition_hint' => 'Emergency stabilization, medication, referral, deferred treatment, or treatment performed.',
            'prescription_hint' => 'Issue or mark not required after allergy/medicine review.',
            'followup_hint' => 'Usually follow-up required unless clearly resolved.',
        ],
    ];
    foreach ($rules as $pattern => $rule) {
        if (preg_match($pattern, $name)) return array_merge(treatment_path_default_rule(), $rule);
    }
    return treatment_path_default_rule();
}

function treatment_path_fetch_active_services(PDO $pdo, ?int $branchId = null): array
{
    $rows = [];
    if (function_exists('schema_table_exists') && schema_table_exists(table('service_catalog'))) {
        try {
            $columns = 'id,name,duration_minutes,provider_type,is_public,is_active';
            if (function_exists('schema_column_exists') && schema_column_exists(table('service_catalog'), 'booking_scope')) $columns .= ',booking_scope';
            if (function_exists('schema_column_exists') && schema_column_exists(table('service_catalog'), 'fee_status')) $columns .= ',fee_status';
            $sql = 'SELECT '.$columns.' FROM `' . table('service_catalog') . '` WHERE is_active=1';
            $args = [];
            if ($branchId && function_exists('schema_column_exists') && schema_column_exists(table('service_catalog'), 'branch_id')) {
                $sql .= ' AND (branch_id=? OR branch_id IS NULL)';
                $args[] = $branchId;
            }
            $sql .= ' ORDER BY provider_type,name';
            $stmt = $pdo->prepare($sql);
            $stmt->execute($args);
            $rows = $stmt->fetchAll() ?: [];
        } catch (Throwable $exception) {
            error_log('DentalCare treatment-path service audit failed: ' . $exception->getMessage());
            $rows = [];
        }
    }
    if (!$rows) $rows = treatment_path_builtin_services();
    return array_values($rows);
}

function treatment_path_encounter_services(PDO $pdo, array $encounter, array $serviceCatalog = []): array
{
    $serviceCatalog = $serviceCatalog ?: treatment_path_fetch_active_services($pdo, (int)($encounter['branch_id'] ?? 0) ?: null);
    $rows = [];
    $seen = [];
    $add = static function(array $row, string $source) use (&$rows, &$seen): void {
        $name = trim((string)($row['name'] ?? $row['service_name'] ?? ''));
        if ($name === '') return;
        $key = strtolower($name) . '|' . strtolower((string)($row['provider_type'] ?? 'dentist'));
        if (isset($seen[$key])) return;
        $seen[$key] = true;
        $rule = treatment_path_rule_for_service_name($name, (string)($row['provider_type'] ?? 'dentist'));
        $rows[] = array_merge($row, ['name' => $name, 'source' => $source, 'path_rule' => $rule]);
    };
    if (!empty($encounter['appointment_id']) && function_exists('schema_table_exists') && schema_table_exists(table('appointment_services'))) {
        try {
            $stmt = $pdo->prepare('SELECT service_name name,provider_type,duration_minutes,status FROM `' . table('appointment_services') . '` WHERE appointment_id=? AND COALESCE(status,"") NOT IN ("cancelled","no_show") ORDER BY sequence_no,id');
            $stmt->execute([(int)$encounter['appointment_id']]);
            foreach ($stmt->fetchAll() ?: [] as $row) $add($row, 'appointment segment');
        } catch (Throwable $exception) {
            error_log('DentalCare treatment-path appointment service audit failed: ' . $exception->getMessage());
        }
    }
    if (!empty($encounter['queue_service'])) {
        $add(['name' => (string)$encounter['queue_service'], 'provider_type' => (string)($encounter['provider_type'] ?? 'dentist'), 'duration_minutes' => null], 'queue service');
    }
    if (!$rows) {
        foreach ($serviceCatalog as $service) {
            if ((string)($service['provider_type'] ?? 'dentist') === 'dentist') {
                $add($service, 'catalog');
                break;
            }
        }
    }
    return $rows;
}

function treatment_path_render_card(PDO $pdo, array $encounter, array $encounterServices, bool $compact = false): void
{
    $services = $encounterServices ?: treatment_path_encounter_services($pdo, $encounter);
    echo '<section class="card treatment-path-card">';
    echo '<div class="card-head"><div><span class="eyebrow">Dentist treatment path</span><h2>What this visit requires</h2><p>The system now classifies the current service so the Dentist knows why the next gate is blocking and what can be skipped with a valid decision.</p></div><span class="badge">'.count($services).' service'.(count($services)===1?'':'s').'</span></div>';
    echo '<div class="treatment-path-grid">';
    foreach ($services as $service) {
        $rule = (array)($service['path_rule'] ?? treatment_path_rule_for_service_name((string)$service['name'], (string)($service['provider_type'] ?? 'dentist')));
        echo '<article class="treatment-path-service">';
        echo '<div><strong>' . e((string)$service['name']) . '</strong><small>' . e((string)($rule['label'] ?? 'General visit')) . ' · ' . e((string)($service['source'] ?? 'catalog')) . '</small></div>';
        echo '<dl>';
        echo '<dt>Odontogram</dt><dd>' . e((string)($rule['odontogram'] ?? 'Review current chart.')) . '</dd>';
        echo '<dt>Tooth required</dt><dd>' . e(is_bool($rule['tooth_required'] ?? false) ? (($rule['tooth_required'] ?? false) ? 'Yes' : 'No') : (string)($rule['tooth_required'] ?? 'When applicable')) . '</dd>';
        echo '<dt>Procedure</dt><dd>' . e(is_bool($rule['procedure_required'] ?? false) ? (($rule['procedure_required'] ?? false) ? 'Required when performed' : 'Not required for consult/no treatment') : (string)($rule['procedure_required'] ?? 'When treatment is performed')) . '</dd>';
        echo '<dt>Consent</dt><dd>' . e((string)($rule['consent_required'] ?? 'When treatment is performed')) . '</dd>';
        echo '</dl>';
        echo '<p><strong>Diagnosis:</strong> ' . e((string)($rule['diagnosis_hint'] ?? 'Record diagnosis or no-pathology decision.')) . '</p>';
        echo '</article>';
    }
    echo '</div>';
    echo '<div class="treatment-path-strip"><strong>Finalize order:</strong> Intake/vitals → safety/consent → exam/odontogram → diagnosis → outcome/procedure → prescription decision → SOAP/follow-up → billing/no-payment release.</div>';
    echo '</section>';
}

function treatment_path_catalog_summary_markdown(array $services): string
{
    $lines = ["| Treatment / service | Provider | Flow requirement | Tooth? | Procedure? |", "|---|---|---|---|---|"];
    foreach ($services as $service) {
        $name = (string)($service['name'] ?? 'Service');
        $provider = (string)($service['provider_type'] ?? 'dentist');
        $rule = treatment_path_rule_for_service_name($name, $provider);
        $tooth = is_bool($rule['tooth_required']) ? ($rule['tooth_required'] ? 'Yes' : 'No') : (string)$rule['tooth_required'];
        $procedure = is_bool($rule['procedure_required']) ? ($rule['procedure_required'] ? 'Yes when performed' : 'No for consult/no treatment') : (string)$rule['procedure_required'];
        $lines[] = '| ' . str_replace('|', '\\|', $name) . ' | ' . str_replace('|', '\\|', $provider) . ' | ' . str_replace('|', '\\|', (string)$rule['label']) . ' | ' . str_replace('|', '\\|', $tooth) . ' | ' . str_replace('|', '\\|', $procedure) . ' |';
    }
    return implode("\n", $lines) . "\n";
}
