<?php

declare(strict_types=1);

require DENTAL_ROOT . '/app/bootstrap.php';
require_login();
require_doctor_workflow_schema();
require DENTAL_ROOT . '/app/layout.php';
require_once DENTAL_ROOT . '/app/module_helpers.php';
require_once DENTAL_ROOT . '/app/doctor_photo.php';

$pdo = db();
$user = current_user() ?? [];
$actualRole = actual_role();
$isAdministrativeAccount=in_array($actualRole,['super_admin','clinic_admin'],true);
$readOnlyTaskPreview=task_preview_mode()&&active_role()==='dentist';
$isAdministrativeManager=$isAdministrativeAccount&&!$readOnlyTaskPreview;
$targetUserId = (int) ($_GET['user_id'] ?? $_POST['user_id'] ?? 0);
if ($targetUserId <= 0 && active_role_is('dentist')) {
    $targetUserId = (int) ($user['id'] ?? 0);
}
if ($targetUserId <= 0 && $isAdministrativeAccount) {
    $availableDentists = dentist_options();
    $targetUserId = (int)($availableDentists[0]['id'] ?? 0);
}
if ($targetUserId <= 0) {
    http_response_code(200);
    render_header('Dentist Professional Setup');
    ?>
    <section class="card setup-empty-state">
        <span class="eyebrow">Clinical setup required</span>
        <h2>No Dentist account is available yet</h2>
        <p>This is normal after a reset or a fresh install. Create an active Dentist staff account first, then complete the professional credentials and clinical setup before using the clinical day and treatment dashboard.</p>
        <div class="button-row">
            <?php if ($isAdministrativeAccount): ?>
                <?php if(task_link_allowed('staff.php')):?><a class="btn primary" href="staff.php">Create Dentist staff account</a><?php endif;?>
                <?php if(task_link_allowed('chairs.php')):?><a class="btn ghost" href="chairs.php">Set up chairs/resources</a><?php endif;?>
            <?php endif; ?>
            <a class="btn ghost" href="dashboard.php">Back to dashboard</a>
        </div>
    </section>
    <?php
    render_footer();
    return;
}
require_manage_dentist_profile($targetUserId);

function doctor_profile_upload(int $dentistUserId, string $field, array $extensions, int $maxBytes): ?array
{
    if (!isset($_FILES[$field]) || $_FILES[$field]['error'] === UPLOAD_ERR_NO_FILE) return null;
    $file = $_FILES[$field];
    if ($file['error'] !== UPLOAD_ERR_OK) throw new RuntimeException('The selected file could not be uploaded.');
    if ((int) $file['size'] <= 0 || (int) $file['size'] > $maxBytes) throw new RuntimeException('The uploaded file is empty or exceeds the allowed size.');
    $original = basename((string) $file['name']);
    $ext = strtolower(pathinfo($original, PATHINFO_EXTENSION));
    if (!in_array($ext, $extensions, true)) throw new RuntimeException('This file type is not allowed.');
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mime = (string) $finfo->file((string) $file['tmp_name']);
    $mimeByExtension = [
        'jpg' => ['image/jpeg'], 'jpeg' => ['image/jpeg'], 'png' => ['image/png'], 'webp' => ['image/webp'],
        'pdf' => ['application/pdf'],
        'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document','application/zip','application/octet-stream'],
    ];
    if (!isset($mimeByExtension[$ext]) || !in_array($mime, $mimeByExtension[$ext], true)) {
        throw new RuntimeException('The uploaded file content does not match its extension.');
    }
    if (in_array($field, ['photo_file','signature_file','prescription_signature_file'], true) && !str_starts_with($mime, 'image/')) {
        throw new RuntimeException('Doctor photographs and signatures must be valid image files.');
    }
    $safe = $field . '_' . date('Ymd_His') . '_' . bin2hex(random_bytes(5)) . '.' . $ext;
    $target = private_dentist_directory($dentistUserId) . '/' . $safe;
    if (!move_uploaded_file((string) $file['tmp_name'], $target)) throw new RuntimeException('Unable to store the protected file. Check storage/private permissions.');
    @chmod($target, 0640);
    return ['path' => 'dentists/' . $dentistUserId . '/' . $safe, 'name' => $original, 'mime' => $mime, 'size' => (int) $file['size']];
}

function doctor_profile_current_user_is_target(int $targetUserId): bool
{
    return (int) (current_user()['id'] ?? 0) === $targetUserId;
}

function doctor_profile_verified_license_exists(PDO $pdo, int $dentistUserId): bool
{
    if (!schema_table_exists(table('dentist_documents'))) return false;
    $stmt = $pdo->prepare('SELECT COUNT(*) FROM `' . table('dentist_documents') . '` WHERE dentist_user_id=? AND document_type="license" AND verification_status="verified" AND (expires_at IS NULL OR expires_at>=CURDATE())');
    $stmt->execute([$dentistUserId]);
    return (int) $stmt->fetchColumn() > 0;
}

$pendingNewPhotoPaths = [];
$doctorPhotoCommitted = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    try {
        verify_csrf();if($readOnlyTaskPreview){http_response_code(403);exit('Dentist professional records are read-only in review mode. Switch Active role back to Administrator or Superuser to manage them.');}
        $action = (string) ($_POST['action'] ?? '');
        require_manage_dentist_profile($targetUserId);

        if ($action === 'save_profile') {
            $existing = dentist_profile($targetUserId) ?? [];
            $photoVariants = null;
            $signature = doctor_profile_upload($targetUserId, 'signature_file', ['jpg','jpeg','png','webp'], 2 * 1024 * 1024);
            $prescriptionSignature = doctor_profile_upload($targetUserId, 'prescription_signature_file', ['jpg','jpeg','png','webp'], 2 * 1024 * 1024);
            $languages = array_values(array_filter(array_map('trim', explode(',', (string) ($_POST['languages'] ?? '')))));
            $chairBranchId = (int) ($existing['account_branch_id'] ?? $existing['primary_branch_id'] ?? 0);
            // Physical chairs are managed centrally under Administration → Chairs & Resources.
            // Load the binding before saving so a dentist can upload a profile photo without
            // an undefined chair reference and without changing the centrally managed chair.
            $saveChairBinding = doctor_chair_binding($targetUserId, $chairBranchId);
            $chairName = normalize_chair_name((string) ($saveChairBinding['chair_name'] ?? $existing['default_chair_name'] ?? ''));
            $postedLicense=trim((string)($_POST['license_number']??''));
            $postedLicenseExpiry=trim((string)($_POST['license_expiry']??''));
            $oldLicense=trim((string)($existing['license_number']??''));$oldLicenseExpiry=trim((string)($existing['license_expiry']??''));
            $licenseChanged=$postedLicense!==$oldLicense||$postedLicenseExpiry!==$oldLicenseExpiry;
            $credentialCorrection=$licenseChanged&&($oldLicense!==''||$oldLicenseExpiry!=='');
            $credentialChangeReason=trim((string)($_POST['credential_change_reason']??''));
            if($credentialCorrection&&$credentialChangeReason==='')throw new RuntimeException('Enter the reason for changing the professional license details. The Dentist will require reverification.');
            $requestedProfileStatus=$isAdministrativeManager&&in_array((string)($_POST['profile_status']??''),['draft','active','suspended'],true)
                ? (string)$_POST['profile_status'] : (string)($existing['profile_status']??'draft');
            if($requestedProfileStatus==='active'&&dentist_credential_schema_ready()&&(string)($existing['credential_status']??'pending')!=='verified'){
                throw new RuntimeException('Verify the current professional license document before activating this Dentist professional record.');
            }
            if($licenseChanged&&dentist_credential_schema_ready())$requestedProfileStatus='draft';
            // v0.9.0.9: staff identity is maintained only in Profile Center.
            // This professional record adds title, credentials, privileges, and dental-practice settings.
            $profileDisplayName=trim((string)($existing['account_name']??$existing['display_name']??''));
            if($profileDisplayName==='')throw new RuntimeException('Complete the staff identity in Profile Center before saving professional credentials.');

            $photoVariants = doctor_photo_process_upload($targetUserId, 'photo_file');
            if ($photoVariants !== null) {
                $pendingNewPhotoPaths = [
                    $photoVariants['original_path'], $photoVariants['square_path'], $photoVariants['portrait_path'], $photoVariants['thumbnail_path'],
                ];
            }
            $pdo->beginTransaction();
            $sql = 'INSERT INTO `' . table('dentist_profiles') . '` '
                . '(user_id,professional_title,display_name,photo_path,specialty_id,subspecialty,license_number,license_expiry,accreditation_numbers,years_in_practice,education,qualifications,certifications,affiliations,languages_json,biography,public_biography,signature_path,prescription_signature_path,preferred_tooth_numbering,default_note_format,employment_type,primary_branch_id,default_chair_name,default_duration_minutes,maximum_daily_appointments,accepting_new_patients,public_profile_enabled,profile_status,created_at,updated_at) '
                . 'VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW()) '
                . 'ON DUPLICATE KEY UPDATE professional_title=VALUES(professional_title),display_name=VALUES(display_name),photo_path=VALUES(photo_path),specialty_id=VALUES(specialty_id),subspecialty=VALUES(subspecialty),license_number=VALUES(license_number),license_expiry=VALUES(license_expiry),accreditation_numbers=VALUES(accreditation_numbers),years_in_practice=VALUES(years_in_practice),education=VALUES(education),qualifications=VALUES(qualifications),certifications=VALUES(certifications),affiliations=VALUES(affiliations),languages_json=VALUES(languages_json),biography=VALUES(biography),public_biography=VALUES(public_biography),signature_path=VALUES(signature_path),prescription_signature_path=VALUES(prescription_signature_path),preferred_tooth_numbering=VALUES(preferred_tooth_numbering),default_note_format=VALUES(default_note_format),employment_type=VALUES(employment_type),primary_branch_id=VALUES(primary_branch_id),default_chair_name=VALUES(default_chair_name),default_duration_minutes=VALUES(default_duration_minutes),maximum_daily_appointments=VALUES(maximum_daily_appointments),accepting_new_patients=VALUES(accepting_new_patients),public_profile_enabled=VALUES(public_profile_enabled),profile_status=VALUES(profile_status),updated_at=NOW()';
            $pdo->prepare($sql)->execute([
                $targetUserId,
                trim((string) ($_POST['professional_title'] ?? 'Dr.')),
                $profileDisplayName,
                $photoVariants['square_path'] ?? ($existing['photo_square_path'] ?? $existing['photo_path'] ?? null),
                $isAdministrativeManager ? ((int) ($_POST['specialty_id'] ?? 0) ?: null) : ((int) ($existing['specialty_id'] ?? 0) ?: null),
                trim((string) ($_POST['subspecialty'] ?? '')) ?: null,
                trim((string) ($_POST['license_number'] ?? '')) ?: null,
                trim((string) ($_POST['license_expiry'] ?? '')) ?: null,
                trim((string) ($_POST['accreditation_numbers'] ?? '')) ?: null,
                (int) ($_POST['years_in_practice'] ?? 0) ?: null,
                trim((string) ($_POST['education'] ?? '')) ?: null,
                trim((string) ($_POST['qualifications'] ?? '')) ?: null,
                trim((string) ($_POST['certifications'] ?? '')) ?: null,
                trim((string) ($_POST['affiliations'] ?? '')) ?: null,
                json_encode($languages, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
                trim((string) ($_POST['biography'] ?? '')) ?: null,
                trim((string) ($_POST['public_biography'] ?? '')) ?: null,
                $signature['path'] ?? ($existing['signature_path'] ?? null),
                $prescriptionSignature['path'] ?? ($existing['prescription_signature_path'] ?? null),
                in_array((string) ($_POST['preferred_tooth_numbering'] ?? ''), ['FDI','Universal','Palmer'], true) ? $_POST['preferred_tooth_numbering'] : 'FDI',
                in_array((string) ($_POST['default_note_format'] ?? ''), ['SOAP','Narrative','Structured'], true) ? $_POST['default_note_format'] : 'SOAP',
                (string) ($existing['employment_type'] ?? 'full_time'),
                $chairBranchId ?: null,
                $chairName ?: null,
                max(5, min(480, (int) ($_POST['default_duration_minutes'] ?? 30))),
                $isAdministrativeManager ? ((int) ($_POST['maximum_daily_appointments'] ?? 0) ?: null) : ((int) ($existing['maximum_daily_appointments'] ?? 0) ?: null),
                isset($_POST['accepting_new_patients']) ? 1 : 0,
                isset($_POST['public_profile_enabled']) ? 1 : 0,
                $requestedProfileStatus,
            ]);
            if (doctor_photo_variant_schema_ready()) {
                $pdo->prepare('UPDATE `' . table('dentist_profiles') . '` SET photo_original_path=?,photo_square_path=?,photo_portrait_path=?,photo_thumbnail_path=?,photo_path=? WHERE user_id=?')->execute([
                    $photoVariants['original_path'] ?? ($existing['photo_original_path'] ?? null),
                    $photoVariants['square_path'] ?? ($existing['photo_square_path'] ?? $existing['photo_path'] ?? null),
                    $photoVariants['portrait_path'] ?? ($existing['photo_portrait_path'] ?? null),
                    $photoVariants['thumbnail_path'] ?? ($existing['photo_thumbnail_path'] ?? $existing['photo_square_path'] ?? $existing['photo_path'] ?? null),
                    $photoVariants['square_path'] ?? ($existing['photo_square_path'] ?? $existing['photo_path'] ?? null),
                    $targetUserId,
                ]);
            }
            if($licenseChanged&&dentist_credential_schema_ready()){
                $pdo->prepare('UPDATE `' . table('dentist_profiles') . '` SET credential_status="pending",credential_verified_by=NULL,credential_verified_at=NULL,credential_note=?,profile_status="draft" WHERE user_id=?')->execute(['License details changed; reverification required. '.$credentialChangeReason,$targetUserId]);
                $pdo->prepare('UPDATE `' . table('dentist_clinical_privileges') . '` SET status="pending" WHERE dentist_user_id=? AND status="granted"')->execute([$targetUserId]);
                if($credentialCorrection&&schema_table_exists(table('dentist_credential_history'))){
                    $pdo->prepare('INSERT INTO `' . table('dentist_credential_history') . '` (dentist_user_id,old_license_number,new_license_number,old_license_expiry,new_license_expiry,old_credential_status,new_credential_status,change_reason,changed_by,changed_at) VALUES (?,?,?,?,?,?,"pending",?,?,NOW())')->execute([$targetUserId,trim((string)($existing['license_number']??''))?:null,$postedLicense?:null,trim((string)($existing['license_expiry']??''))?:null,$postedLicenseExpiry?:null,(string)($existing['credential_status']??'pending'),$credentialChangeReason,(int)$user['id']]);
                }
            }
            $pdo->commit();
            $doctorPhotoCommitted = true;
            if ($photoVariants !== null) {
                doctor_photo_delete_replaced_files($targetUserId, doctor_photo_paths_from_profile($existing), [
                    $photoVariants['original_path'], $photoVariants['square_path'], $photoVariants['portrait_path'], $photoVariants['thumbnail_path'],
                ]);
            }
            audit('dentist_profile_updated', 'dentist_profile', $targetUserId, ['photo_updated' => $photoVariants !== null, 'signature_updated' => $signature !== null, 'chair_branch_id'=>$chairBranchId, 'chair_name'=>$chairName,'license_changed'=>$licenseChanged,'credential_change_reason'=>$credentialCorrection?$credentialChangeReason:null,'requested_status'=>$requestedProfileStatus,'profile_name'=>$profileDisplayName]);
            flash('success', $photoVariants !== null ? 'Professional settings saved. Professional 2×2, half-body portrait, and thumbnail images were generated.' : 'Professional settings saved. Permanent chair assignments remain controlled under Chairs & Resources.');
        }

        if ($action === 'save_privileges') {
            require_roles(['super_admin','clinic_admin']);
            require_independent_actor([$targetUserId], 'approve their own clinical privileges');
            require_dentist_credentials_verified($targetUserId);
            $selected = array_values(array_unique(array_filter(array_map('intval', (array) ($_POST['privileges'] ?? [])))));
            $privilegeNotes=trim((string)($_POST['privilege_notes']??''));
            if($selected&&$privilegeNotes==='')throw new RuntimeException('Enter the competency evidence or approval basis for the selected clinical privileges.');
            $pdo->beginTransaction();
            $pdo->prepare('DELETE FROM `' . table('dentist_clinical_privileges') . '` WHERE dentist_user_id=?')->execute([$targetUserId]);
            $insert = $pdo->prepare('INSERT INTO `' . table('dentist_clinical_privileges') . '` (dentist_user_id,privilege_id,status,effective_from,expires_at,approved_by,notes,created_at) VALUES (?,? ,"granted",CURDATE(),?,?,?,NOW())');
            foreach ($selected as $privilegeId) {
                if ($privilegeId > 0) $insert->execute([$targetUserId,$privilegeId,trim((string) ($_POST['privilege_expiry'] ?? '')) ?: null,(int) $user['id'],$privilegeNotes ?: null]);
            }
            $pdo->commit();
            audit('dentist_privileges_updated','dentist_profile',$targetUserId,['privilege_ids'=>$selected]);
            flash('success','Clinical privileges saved.');
        }

        if ($action === 'save_assignments') {
            require_roles(['super_admin','clinic_admin']);
            $branchIds = array_map('intval', (array) ($_POST['branch_ids'] ?? []));
            $serviceIds = array_map('intval', (array) ($_POST['service_ids'] ?? []));
            $favoriteIds = array_map('intval', (array) ($_POST['favorite_service_ids'] ?? []));
            $pdo->beginTransaction();
            $pdo->prepare('DELETE FROM `' . table('dentist_branch_assignments') . '` WHERE dentist_user_id=?')->execute([$targetUserId]);
            $insertBranch = $pdo->prepare('INSERT INTO `' . table('dentist_branch_assignments') . '` (dentist_user_id,branch_id,is_primary,status,created_at) VALUES (?,?,?,"active",NOW())');
            $primary = (int) ($_POST['primary_branch_id'] ?? 0);
            foreach ($branchIds as $branchId) if ($branchId > 0) $insertBranch->execute([$targetUserId,$branchId,$branchId === $primary ? 1 : 0]);
            $pdo->prepare('DELETE FROM `' . table('dentist_service_assignments') . '` WHERE dentist_user_id=?')->execute([$targetUserId]);
            $insertService = $pdo->prepare('INSERT INTO `' . table('dentist_service_assignments') . '` (dentist_user_id,service_id,is_active,created_at) VALUES (?,?,1,NOW())');
            foreach ($serviceIds as $serviceId) if ($serviceId > 0) $insertService->execute([$targetUserId,$serviceId]);
            $pdo->prepare('DELETE FROM `' . table('dentist_favorite_procedures') . '` WHERE dentist_user_id=?')->execute([$targetUserId]);
            $insertFavorite = $pdo->prepare('INSERT INTO `' . table('dentist_favorite_procedures') . '` (dentist_user_id,service_id,sort_order,created_at) VALUES (?,?,?,NOW())');
            foreach ($favoriteIds as $sort=>$serviceId) if ($serviceId > 0) $insertFavorite->execute([$targetUserId,$serviceId,$sort]);
            $pdo->commit();
            audit('dentist_assignments_updated','dentist_profile',$targetUserId,['branches'=>$branchIds,'services'=>$serviceIds,'favorites'=>$favoriteIds]);
            flash('success','Branch, service, and favorite-procedure assignments saved.');
        }

        if ($action === 'upload_document') {
            $upload = doctor_profile_upload($targetUserId, 'document_file', ['pdf','jpg','jpeg','png','webp','docx'], 15 * 1024 * 1024);
            if (!$upload) throw new RuntimeException('Choose a document to upload.');
            $type = (string) ($_POST['document_type'] ?? 'other');
            if (!in_array($type, ['license','certification','training','accreditation','employment','other'], true)) $type = 'other';
            $pdo->prepare('INSERT INTO `' . table('dentist_documents') . '` (dentist_user_id,document_type,title,file_path,original_name,mime_type,file_size,issued_at,expires_at,verification_status,notes,created_at) VALUES (?,?,?,?,?,?,?,?,?,"pending",?,NOW())')->execute([
                $targetUserId,$type,trim((string) ($_POST['document_title'] ?? '')) ?: $upload['name'],$upload['path'],$upload['name'],$upload['mime'],$upload['size'],trim((string) ($_POST['issued_at'] ?? '')) ?: null,trim((string) ($_POST['expires_at'] ?? '')) ?: null,trim((string) ($_POST['document_notes'] ?? '')) ?: null,
            ]);
            if ($type === 'license' && dentist_credential_schema_ready()) {
                $pdo->prepare('UPDATE `' . table('dentist_profiles') . '` SET credential_status="pending", credential_verified_by=NULL, credential_verified_at=NULL, credential_note="New professional license document uploaded; administrator verification is required.", profile_status="draft" WHERE user_id=?')->execute([$targetUserId]);
                $pdo->prepare('UPDATE `' . table('dentist_clinical_privileges') . '` SET status="pending" WHERE dentist_user_id=? AND status="granted"')->execute([$targetUserId]);
            }
            audit('dentist_document_uploaded','dentist_profile',$targetUserId,['type'=>$type,'name'=>$upload['name']]);
            flash('success',$type === 'license' ? 'Professional license uploaded securely. Status remains pending until an Administrator or Superuser verifies it.' : 'Professional document uploaded securely.');
        }

        if ($action === 'verify_document') {
            require_roles(['super_admin','clinic_admin']);
            if (doctor_profile_current_user_is_target($targetUserId)) throw new RuntimeException('A Dentist cannot verify their own professional license, even if they also have an Admin role. Ask another authorized Admin or Superuser to verify it.');
            if(!dentist_credential_schema_ready())throw new RuntimeException('Apply Version 0.5.9.6 before verifying professional credentials.');
            $documentId=(int)($_POST['document_id']??0);
            $status=in_array((string)($_POST['verification_status']??''),['verified','rejected','pending'],true)?(string)$_POST['verification_status']:'pending';
            $reviewNote=trim((string)($_POST['verification_note']??''));
            if (in_array($status, ['verified','rejected'], true) && $reviewNote === '') throw new RuntimeException('Enter the verification evidence or rejection reason.');
            $pdo->beginTransaction();
            $stmt=$pdo->prepare('SELECT * FROM `' . table('dentist_documents') . '` WHERE id=? AND dentist_user_id=? FOR UPDATE');
            $stmt->execute([$documentId,$targetUserId]);$document=$stmt->fetch();
            if(!$document)throw new RuntimeException('Credential document not found.');
            $profileLock=$pdo->prepare('SELECT * FROM `' . table('dentist_profiles') . '` WHERE user_id=? FOR UPDATE');
            $profileLock->execute([$targetUserId]);$profileRow=$profileLock->fetch();
            if(!$profileRow)throw new RuntimeException('Dentist professional record not found.');
            if($status==='verified'&&(string)$document['document_type']==='license'){
                if(trim((string)($profileRow['license_number']??''))==='')throw new RuntimeException('Enter the professional license number before verification.');
                $profileExpiry=trim((string)($profileRow['license_expiry']??''));
                if($profileExpiry===''||$profileExpiry<date('Y-m-d'))throw new RuntimeException('Enter a current professional license expiry before verification.');
                $documentExpiry=trim((string)($document['expires_at']??''));
                if($documentExpiry!==''&&$documentExpiry<date('Y-m-d'))throw new RuntimeException('An expired license document cannot be verified.');
            }
            $verifiedAtSql = schema_column_exists(table('dentist_documents'),'verified_at') ? ',verified_at=CASE WHEN ?="verified" THEN NOW() ELSE NULL END' : '';
            if ($verifiedAtSql !== '') {
                $pdo->prepare('UPDATE `' . table('dentist_documents') . '` SET verification_status=?,verified_by=?' . $verifiedAtSql . ' WHERE id=? AND dentist_user_id=?')->execute([$status,(int)$user['id'],$status,$documentId,$targetUserId]);
            } else {
                $pdo->prepare('UPDATE `' . table('dentist_documents') . '` SET verification_status=?,verified_by=? WHERE id=? AND dentist_user_id=?')->execute([$status,(int)$user['id'],$documentId,$targetUserId]);
            }
            if((string)$document['document_type']==='license'){
                if($status==='verified'){
                    $pdo->prepare('UPDATE `' . table('dentist_profiles') . '` SET credential_status="verified",credential_verified_by=?,credential_verified_at=NOW(),credential_note=?,profile_status="active" WHERE user_id=?')->execute([(int)$user['id'],$reviewNote?:'Professional license document verified.',$targetUserId]);
                }else{
                    $credentialStatus=$status==='rejected'?'rejected':'pending';
                    $pdo->prepare('UPDATE `' . table('dentist_profiles') . '` SET credential_status=?,credential_verified_by=?,credential_verified_at=NULL,credential_note=?,profile_status="draft" WHERE user_id=?')->execute([$credentialStatus,(int)$user['id'],$reviewNote?:'Professional license requires review.',$targetUserId]);
                    $pdo->prepare('UPDATE `' . table('dentist_clinical_privileges') . '` SET status="pending" WHERE dentist_user_id=? AND status="granted"')->execute([$targetUserId]);
                }
            }
            $pdo->commit();
            audit('dentist_document_reviewed','dentist_document',$documentId,['status'=>$status,'document_type'=>$document['document_type'],'credential_note'=>$reviewNote]);
            flash('success',$status==='verified'&&$document['document_type']==='license'?'Professional license verified. Clinical privileges may now be approved.':'Document verification updated.');
        }

        if ($action === 'save_template') {
            $type = (string) ($_POST['template_type'] ?? 'soap');
            if (!in_array($type, ['examination','procedure','soap','prescription','instruction'], true)) $type = 'soap';
            $pdo->prepare('INSERT INTO `' . table('dentist_templates') . '` (dentist_user_id,template_type,name,content,is_default,created_at,updated_at) VALUES (?,?,?,?,?,NOW(),NOW())')->execute([
                $targetUserId,$type,trim((string) ($_POST['template_name'] ?? '')) ?: 'Clinical template',trim((string) ($_POST['template_content'] ?? '')),isset($_POST['is_default'])?1:0,
            ]);
            audit('dentist_template_created','dentist_profile',$targetUserId,['type'=>$type]);
            flash('success','Clinical template saved.');
        }

        header('Location: doctor_profile.php?user_id=' . $targetUserId);
        exit;
    } catch (Throwable $exception) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        if (!$doctorPhotoCommitted && $pendingNewPhotoPaths) {
            foreach ($pendingNewPhotoPaths as $pendingPhotoPath) {
                $pendingFullPath = doctor_photo_absolute_path((string)$pendingPhotoPath);
                if (is_file($pendingFullPath)) @unlink($pendingFullPath);
            }
        }
        flash('error', $exception->getMessage());
        header('Location: doctor_profile.php?user_id=' . $targetUserId);
        exit;
    }
}

$profile = dentist_profile($targetUserId);
if (!$profile) {
    http_response_code(200);
    render_header('Dentist Professional Setup');
    ?>
    <section class="card setup-empty-state">
        <span class="eyebrow">Clinical setup required</span>
        <h2>Dentist account or professional record was not found</h2>
        <p>The selected Dentist may have been removed, disabled, or not created correctly. Use Staff management to create or reactivate the Dentist account, then return here to complete professional details and privileges.</p>
        <div class="button-row">
            <?php if ($isAdministrativeAccount): ?>
                <?php if(task_link_allowed('staff.php')):?><a class="btn primary" href="staff.php">Open Staff management</a><?php endif;?>
                <a class="btn ghost" href="doctor_profile.php">Open available Dentist record</a>
            <?php endif; ?>
            <a class="btn ghost" href="dashboard.php">Back to dashboard</a>
        </div>
    </section>
    <?php
    render_footer();
    return;
}
$specialties = $pdo->query('SELECT * FROM `' . table('dentist_specialties') . '` WHERE is_active=1 ORDER BY name')->fetchAll();
$privileges = $pdo->query('SELECT * FROM `' . table('clinical_privileges') . '` WHERE is_active=1 ORDER BY category,name')->fetchAll();
$stmt = $pdo->prepare('SELECT privilege_id FROM `' . table('dentist_clinical_privileges') . '` WHERE dentist_user_id=? AND status="granted"');
$stmt->execute([$targetUserId]);
$assignedPrivileges = array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN));
$branches = branch_options();
$services = $pdo->query('SELECT id,name,duration_minutes FROM `' . table('service_catalog') . '` WHERE is_active=1 ORDER BY name')->fetchAll();
$stmt = $pdo->prepare('SELECT branch_id FROM `' . table('dentist_branch_assignments') . '` WHERE dentist_user_id=? AND status="active"');$stmt->execute([$targetUserId]);$assignedBranches=array_map('intval',$stmt->fetchAll(PDO::FETCH_COLUMN));
$stmt = $pdo->prepare('SELECT service_id FROM `' . table('dentist_service_assignments') . '` WHERE dentist_user_id=? AND is_active=1');$stmt->execute([$targetUserId]);$assignedServices=array_map('intval',$stmt->fetchAll(PDO::FETCH_COLUMN));
$stmt = $pdo->prepare('SELECT service_id FROM `' . table('dentist_favorite_procedures') . '` WHERE dentist_user_id=? ORDER BY sort_order');$stmt->execute([$targetUserId]);$favoriteServices=array_map('intval',$stmt->fetchAll(PDO::FETCH_COLUMN));
$stmt = $pdo->prepare('SELECT d.*,u.name verifier FROM `' . table('dentist_documents') . '` d LEFT JOIN `' . table('users') . '` u ON u.id=d.verified_by WHERE dentist_user_id=? ORDER BY d.created_at DESC');$stmt->execute([$targetUserId]);$documents=$stmt->fetchAll();
$stmt = $pdo->prepare('SELECT * FROM `' . table('dentist_templates') . '` WHERE dentist_user_id=? ORDER BY template_type,name');$stmt->execute([$targetUserId]);$templates=$stmt->fetchAll();
$credentialHistory=[];if(schema_table_exists(table('dentist_credential_history'))){$stmt=$pdo->prepare('SELECT h.*,u.name changed_by_name FROM `' . table('dentist_credential_history') . '` h LEFT JOIN `' . table('users') . '` u ON u.id=h.changed_by WHERE h.dentist_user_id=? ORDER BY h.changed_at DESC,h.id DESC LIMIT 10');$stmt->execute([$targetUserId]);$credentialHistory=$stmt->fetchAll();}
$privilegeGroups=[];foreach($privileges as $privilege){$privilegeGroups[(string)($privilege['category']?:'Other')][]=$privilege;}
$languages = json_decode((string) ($profile['languages_json'] ?? '[]'), true); if (!is_array($languages)) $languages=[];
$profileBranchId=(int)($profile['primary_branch_id']??$profile['account_branch_id']??0);$chairBinding=doctor_chair_binding($targetUserId,$profileBranchId);
$licenseReady = trim((string)($profile['license_number'] ?? '')) !== '' && trim((string)($profile['license_expiry'] ?? '')) !== '' && (string)$profile['license_expiry'] >= date('Y-m-d');
$verifiedLicenseExists = doctor_profile_verified_license_exists($pdo, $targetUserId);
$allDentists = $isAdministrativeAccount ? dentist_options() : [];

render_header('Dentist Credentials & Clinical Setup');
?>
<?php if ($allDentists): ?><form class="card compact-filter" method="get"><label>Doctor<select name="user_id" onchange="this.form.submit()"><?php foreach($allDentists as $doctor):?><option value="<?=(int)$doctor['id']?>" <?=$targetUserId===(int)$doctor['id']?'selected':''?>><?=e($doctor['display_name'] ?: $doctor['name'])?></option><?php endforeach;?></select></label><noscript><button class="btn ghost">Open</button></noscript></form><?php endif; ?>
<section class="doctor-profile-hero card">
    <div class="doctor-avatar"><?php if(!empty($profile['photo_path'])):?><img src="doctor_asset.php?type=photo&variant=square&user_id=<?=$targetUserId?>" alt=""><?php else:?><span><?=e(strtoupper(substr((string)($profile['display_name']?:$profile['account_name']),0,1)))?></span><?php endif;?></div>
    <div><span class="eyebrow">Dentist professional record</span><h2><?=e(dentist_display_name($profile))?></h2><p><?=e($profile['specialty_name'] ?: 'Dentist')?><?=!empty($profile['branch_name'])?' · '.e($profile['branch_name']):''?></p><div class="status-actions"><a class="btn primary" href="doctor_treatment.php<?=$isAdministrativeAccount?'?dentist_id='.$targetUserId:''?>">Open Treatment Dashboard</a><a class="btn ghost" href="doctor_schedule.php?tab=appointments<?=$isAdministrativeAccount?'&doctor_id='.$targetUserId:''?>">Weekly Schedule</a><a class="btn ghost" href="doctor_schedule.php?tab=future<?=$isAdministrativeAccount?'&doctor_id='.$targetUserId:''?>">Future Appointments</a><a class="btn ghost" href="doctor_schedule.php?tab=builder<?=$isAdministrativeAccount?'&doctor_id='.$targetUserId:''?>">Build Availability</a></div></div>
    <div class="doctor-profile-status"><span class="badge">Credentials: <?=e(module_status((string)($profile['credential_status']??'pending')))?></span><span class="badge"><?=e(ucwords(str_replace('_',' ',(string)($profile['employment_type']??'full_time'))))?></span><span class="badge"><?=!empty($profile['accepting_new_patients'])?'Accepting new patients':'Not accepting new patients'?></span><?php if(!empty($profile['license_expiry'])):?><small>License expiry <?=e(date('M j, Y',strtotime($profile['license_expiry'])))?></small><?php endif;?></div>
</section>
<?php if(($profile['credential_status']??'pending')!=='verified'): ?><div class="alert warning"><strong>Clinical access is blocked.</strong> The Dentist may complete this professional record and upload documents, but clinical access stays pending until all three are true: license number is present, expiry is current/future, and a Professional license document is verified by another authorized Admin or Superuser.<?php if(!$licenseReady):?> <strong>Missing/current license details still need correction.</strong><?php endif;?><?php if(!$verifiedLicenseExists):?> <strong>No current verified license document is attached yet.</strong><?php endif;?><?=!empty($profile['credential_note'])?' '.e((string)$profile['credential_note']):''?></div><?php else: ?><div class="alert success"><strong>Professional credentials verified.</strong> Verified <?=!empty($profile['credential_verified_at'])?e(date('M j, Y g:i A',strtotime((string)$profile['credential_verified_at']))):'by clinic administration'?>.</div><?php endif; ?>
<section class="chair-binding-note <?= $chairBinding['valid'] ? '' : 'warning' ?>"><div><strong><?= $chairBinding['valid'] ? 'Bound treatment chair: ' . e((string)$chairBinding['chair_name']) : 'Chair assignment required' ?></strong><small><?= $chairBinding['valid'] ? 'New and future appointments for this branch use this chair automatically.' : e((string)$chairBinding['issue']) ?></small></div><?php if($isAdministrativeManager):?><a class="btn ghost" href="chairs.php?branch_id=<?= (int)($profile['primary_branch_id']??$profile['account_branch_id']??0) ?>"><?= $chairBinding['valid']?'Manage chair':'Assign chair' ?></a><?php endif;?></section>

<div class="doctor-profile-layout doctor-profile-layout-compact">
<main class="doctor-profile-main">
<form method="post" enctype="multipart/form-data" class="card doctor-profile-form-compact">
<input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="save_profile"><input type="hidden" name="user_id" value="<?=$targetUserId?>">
<div class="card-head doctor-profile-form-head"><div><span class="eyebrow">Professional and clinical setup</span><h2>Dentist credentials and preferences</h2><p>Personal identity is maintained once in Profile Center. This page contains license, specialty, documents, signatures, privileges, and dental-practice settings.</p></div><button class="btn primary" type="submit">Save professional settings</button></div>
<details class="doctor-compact-section" open>
<summary><span><strong>Professional identity and license</strong><small>Staff identity, specialty, license number, expiry, and languages</small></span><em><?= $licenseReady ? 'License fields complete' : 'License fields needed' ?></em></summary>
<div class="form-grid doctor-compact-grid">
<label>Professional title<input name="professional_title" value="<?=e($profile['professional_title']??'Dr.')?>"></label>
<label class="wide">Staff identity<input value="<?=e((string)($profile['account_name']??$profile['display_name']??''))?>" readonly><small>Name and personal contact details are maintained once in Profile Center. Saving this page cannot create a second identity.</small></label>
<div class="wide inline-actions"><?php if(doctor_profile_current_user_is_target($targetUserId)):?><a class="btn ghost" href="my_profile.php">Edit personal details in Profile Center</a><?php elseif($isAdministrativeAccount):?><a class="btn ghost" href="staff.php?manage_id=<?=$targetUserId?>">Open staff account &amp; work assignment</a><?php endif;?></div>
<label>Specialty<select name="specialty_id" <?=$isAdministrativeManager?'':'disabled'?>><option value="">General / not specified</option><?php foreach($specialties as $specialty):?><option value="<?=(int)$specialty['id']?>" <?=(int)($profile['specialty_id']??0)===(int)$specialty['id']?'selected':''?>><?=e($specialty['name'])?></option><?php endforeach;?></select><?php if(!$isAdministrativeManager):?><small>Specialty assignment is reviewed by Admin/Superuser.</small><?php endif;?></label>
<label>Subspecialty<input name="subspecialty" value="<?=e($profile['subspecialty']??'')?>"></label>
<label>Professional license number<input name="license_number" value="<?=e($profile['license_number']??'')?>"></label>
<label>License expiration<input type="date" name="license_expiry" value="<?=e($profile['license_expiry']??'')?>"></label>
<label>Years in practice<input type="number" min="0" max="80" name="years_in_practice" value="<?=e($profile['years_in_practice']??'')?>"></label>
<label>Languages <small>Comma separated</small><input name="languages" value="<?=e(implode(', ',$languages))?>"></label>
<label class="wide">Reason for credential correction <small>Required only when the license number or expiry changes after a previous entry</small><textarea name="credential_change_reason" rows="2" placeholder="Explain the correction and evidence reviewed."></textarea></label>
</div>
</details>
<details class="doctor-compact-section">
<summary><span><strong>Professional background</strong><small>Accreditations, education, qualifications, certificates, affiliations, and biographies</small></span><em>Optional profile details</em></summary>
<div class="form-grid doctor-compact-grid">
<label class="wide">Accreditation numbers<textarea name="accreditation_numbers" rows="2"><?=e($profile['accreditation_numbers']??'')?></textarea></label>
<label class="wide">Education<textarea name="education" rows="3"><?=e($profile['education']??'')?></textarea></label>
<label class="wide">Qualifications<textarea name="qualifications" rows="3"><?=e($profile['qualifications']??'')?></textarea></label>
<label class="wide">Certifications<textarea name="certifications" rows="3"><?=e($profile['certifications']??'')?></textarea></label>
<label class="wide">Professional affiliations<textarea name="affiliations" rows="3"><?=e($profile['affiliations']??'')?></textarea></label>
<label class="wide">Internal biography<textarea name="biography" rows="4"><?=e($profile['biography']??'')?></textarea></label>
<label class="wide">Public biography<textarea name="public_biography" rows="4"><?=e($profile['public_biography']??'')?></textarea></label>
</div>
</details>
<details class="doctor-compact-section">
<summary><span><strong>Clinic preferences</strong><small>Visit timing, note style, patient acceptance, and public profile</small></span><em>Operational defaults</em></summary>
<div class="form-grid doctor-compact-grid">
<label>Employment type<input value="<?=e(ucwords(str_replace('_',' ',(string)($profile['employment_type']??'full_time'))))?>" readonly><small>Managed in Staff Accounts &amp; Roles.</small></label>
<label>Primary branch<input value="<?=e((string)($profile['branch_name']??'All branches'))?>" readonly><small>Managed in Staff Accounts &amp; Roles.</small></label>
<label>Default visit duration<input type="number" min="5" max="480" name="default_duration_minutes" value="<?=e($profile['default_duration_minutes']??30)?>"></label>
<label>Maximum appointments/day<input type="number" min="1" max="100" name="maximum_daily_appointments" <?=$isAdministrativeManager?'':'disabled'?> value="<?=e($profile['maximum_daily_appointments']??'')?>"><?php if(!$isAdministrativeManager):?><small>Daily cap is administrator-controlled.</small><?php endif;?></label>
<label>Tooth numbering<select name="preferred_tooth_numbering"><?php foreach(['FDI','Universal','Palmer'] as $value):?><option value="<?=$value?>" <?=$profile['preferred_tooth_numbering']===$value?'selected':''?>><?=$value?></option><?php endforeach;?></select></label>
<label>Default note format<select name="default_note_format"><?php foreach(['SOAP','Narrative','Structured'] as $value):?><option value="<?=$value?>" <?=$profile['default_note_format']===$value?'selected':''?>><?=$value?></option><?php endforeach;?></select></label>
<?php if($isAdministrativeManager):?><label>Profile status<select name="profile_status"><?php foreach(['draft'=>'Draft','active'=>'Active','suspended'=>'Suspended'] as $value=>$label):?><option value="<?=$value?>" <?=$profile['profile_status']===$value?'selected':''?>><?=e($label)?></option><?php endforeach;?></select><small>Activation still requires verified credentials.</small></label><?php endif;?>
<label class="choice wide"><input type="checkbox" name="accepting_new_patients" value="1" <?=!empty($profile['accepting_new_patients'])?'checked':''?>><span><strong>Accepting new patients</strong></span></label>
<label class="choice wide"><input type="checkbox" name="public_profile_enabled" value="1" <?=!empty($profile['public_profile_enabled'])?'checked':''?>><span><strong>Publish approved public profile</strong></span></label>
</div>
</details>
<details class="doctor-compact-section" data-doctor-photo-crop>
<summary><span><strong>Protected identity files</strong><small>Professional 2×2 photo, public half-body portrait, and clinical signatures</small></span><em>Private uploads</em></summary>
<div class="doctor-photo-manager">
<div class="doctor-photo-format-grid" aria-label="Current doctor photo formats">
<figure class="doctor-photo-format doctor-photo-format-square"><div><img data-photo-preview="square" src="<?=!empty($profile['photo_path'])?'doctor_asset.php?type=photo&amp;variant=square&amp;user_id='.$targetUserId:'public/favicon.svg'?>" alt="2×2 doctor photo preview"></div><figcaption><strong>2×2 professional photo</strong><small>Used in the sidebar, treatment workspace, schedules, and clinical records.</small></figcaption></figure>
<figure class="doctor-photo-format doctor-photo-format-portrait"><div><img data-photo-preview="portrait" src="<?=!empty($profile['photo_path'])?'doctor_asset.php?type=photo&amp;variant=portrait&amp;user_id='.$targetUserId:'public/favicon.svg'?>" alt="Half-body doctor portrait preview"></div><figcaption><strong>Half-body portrait</strong><small>Used on the public clinic page and full professional profile.</small></figcaption></figure>
</div>
<div class="form-grid doctor-compact-grid doctor-photo-upload-fields">
<label class="wide">Professional doctor photograph<input type="file" name="photo_file" accept="image/jpeg,image/png,image/webp" data-photo-file><small>Select one clear photograph at least 800 × 800 pixels and no larger than 5 MB. The crop editor creates both required formats without stretching the face.</small></label>
<input type="hidden" name="photo_square_data"><input type="hidden" name="photo_portrait_data"><input type="hidden" name="photo_thumbnail_data">
<p class="wide doctor-photo-crop-state" data-photo-crop-state><?=!empty($profile['photo_path'])?'Current photo formats are available. Selecting a new image opens the professional crop editor.':'Select a photograph to prepare the 2×2 and half-body formats.'?></p>
<label>Clinical signature<input type="file" name="signature_file" accept="image/jpeg,image/png,image/webp"></label>
<label>Prescription signature<input type="file" name="prescription_signature_file" accept="image/jpeg,image/png,image/webp"></label>
</div>
</div>
<dialog id="doctor-photo-crop-dialog" class="doctor-photo-crop-dialog">
<div class="doctor-photo-crop-shell">
<div class="doctor-photo-crop-head"><div><span class="eyebrow">Professional photo editor</span><h2>Prepare both doctor-photo formats</h2><p>Review the square 2×2 crop and the public half-body portrait before applying.</p></div><button type="button" class="dialog-close" data-photo-cancel aria-label="Cancel photo editor">×</button></div>
<div class="doctor-photo-preset-tabs" role="group" aria-label="Photo crop format"><button type="button" class="btn ghost active" data-photo-preset="square" aria-pressed="true">2×2 Photo</button><button type="button" class="btn ghost" data-photo-preset="portrait" aria-pressed="false">Half-Body Portrait</button></div>
<div class="doctor-photo-editor-layout">
<div class="doctor-photo-editor-frame is-square" data-photo-editor-frame><canvas data-photo-editor-canvas></canvas><span class="doctor-photo-face-guide" aria-hidden="true"></span></div>
<div class="doctor-photo-editor-controls">
<label>Zoom<input type="range" min="1" max="3" step="0.01" value="1" data-photo-zoom></label>
<label>Move left / right<input type="range" min="-100" max="100" step="1" value="0" data-photo-horizontal></label>
<label>Move up / down<input type="range" min="-100" max="100" step="1" value="0" data-photo-vertical></label>
<div class="doctor-photo-guidance"><strong>Professional framing</strong><span>Keep the face centered, shoulders visible in the 2×2 crop, and chest or waist visible in the portrait. Leave a small space above the head.</span></div>
</div>
</div>
<p class="doctor-photo-editor-status" data-photo-status role="status"></p>
<div class="dialog-actions"><button type="button" class="btn ghost" data-photo-cancel>Cancel</button><button type="button" class="btn primary" data-photo-apply>Use both professional crops</button></div>
</div>
</dialog>
</details>
<div class="doctor-profile-sticky-actions"><span>Professional settings do not change staff identity, roles, permissions, credential verification, or approved clinical privileges.</span><button class="btn primary" type="submit">Save professional settings</button></div>
</form>

<?php if($credentialHistory):?>
<details class="card doctor-side-section doctor-wide-section">
<summary><span><strong>Credential correction history</strong><small>License changes remain visible and always trigger reverification.</small></span><em><?=count($credentialHistory)?> change<?=count($credentialHistory)===1?'':'s'?></em></summary>
<div class="table-wrap compact-table"><table><thead><tr><th>Changed</th><th>Previous</th><th>Updated</th><th>Reason</th><th>Changed by</th></tr></thead><tbody><?php foreach($credentialHistory as $change):?><tr><td><?=e(date('M j, Y g:i A',strtotime((string)$change['changed_at'])))?></td><td><strong><?=e((string)($change['old_license_number']?:'—'))?></strong><small><?=e((string)($change['old_license_expiry']?:'No expiry'))?> · <?=e(module_status((string)$change['old_credential_status']))?></small></td><td><strong><?=e((string)($change['new_license_number']?:'—'))?></strong><small><?=e((string)($change['new_license_expiry']?:'No expiry'))?> · Pending reverification</small></td><td><?=e((string)$change['change_reason'])?></td><td><?=e((string)($change['changed_by_name']?:'System'))?></td></tr><?php endforeach;?></tbody></table></div>
</details>
<?php endif;?>

<details class="card doctor-side-section doctor-wide-section" open>
<summary><span><strong>Credential documents</strong><small>Uploaded professional documents and verification status</small></span><em><?=count($documents)?> file<?=count($documents)===1?'':'s'?></em></summary>
<div class="table-wrap compact-table"><table><thead><tr><th>Document</th><th>Type</th><th>Expiry</th><th>Verification</th><th>Action</th></tr></thead><tbody><?php foreach($documents as $document):?><tr><td><strong><?=e($document['title'])?></strong><br><small><?=e($document['original_name'])?></small></td><td><?=e(ucfirst($document['document_type']))?></td><td><?=e($document['expires_at']?:'—')?></td><td><span class="badge"><?=e(ucfirst($document['verification_status']))?></span><?php if($document['verifier']):?><small><?=e($document['verifier'])?></small><?php endif;?></td><td><a href="doctor_asset.php?type=document&id=<?=(int)$document['id']?>">Open</a><?php if($isAdministrativeManager):?><form method="post" class="inline-form compact-verify-form"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="verify_document"><input type="hidden" name="user_id" value="<?=$targetUserId?>"><input type="hidden" name="document_id" value="<?=(int)$document['id']?>"><select name="verification_status"><option value="pending" <?=$document['verification_status']==='pending'?'selected':''?>>Pending</option><option value="verified" <?=$document['verification_status']==='verified'?'selected':''?>>Verified</option><option value="rejected" <?=$document['verification_status']==='rejected'?'selected':''?>>Rejected</option></select><input name="verification_note" placeholder="Verification evidence or rejection reason" required><button class="btn link">Update</button></form><?php endif;?></td></tr><?php endforeach;if(!$documents):?><tr><td colspan="5" class="muted">No professional documents uploaded.</td></tr><?php endif;?></tbody></table></div>
</details>
</main>

<aside class="doctor-profile-side doctor-profile-side-compact">
<section class="card doctor-profile-progress-card">
<h2>Completion checklist</h2>
<ul class="profile-checklist">
<li class="<?=trim((string)($profile['account_name']??$profile['display_name']??''))!==''?'complete':'missing'?>"><span><?=trim((string)($profile['account_name']??$profile['display_name']??''))!==''?'✓':'!'?></span> Staff identity</li>
<li class="<?=$licenseReady?'complete':'missing'?>"><span><?=$licenseReady?'✓':'!'?></span> Current license details</li>
<li class="<?=$verifiedLicenseExists?'complete':'missing'?>"><span><?=$verifiedLicenseExists?'✓':'!'?></span> Verified license document</li>
<li class="<?=($profile['credential_status']??'pending')==='verified'?'complete':'missing'?>"><span><?=($profile['credential_status']??'pending')==='verified'?'✓':'!'?></span> Credential status</li>
<li class="<?=$chairBinding['valid']?'complete':'missing'?>"><span><?=$chairBinding['valid']?'✓':'!'?></span> Treatment chair binding</li>
</ul>
<p class="muted">Dentists can complete professional information and upload files. Verification, role assignment, and clinical activation require another authorized Admin/Superuser.</p>
</section>

<details class="card doctor-side-section" open>
<summary><span><strong>Upload professional document</strong><small>License, PRC, certifications, training, or accreditation</small></span><em>Doctor upload</em></summary>
<form method="post" enctype="multipart/form-data" class="form-grid doctor-side-form"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="upload_document"><input type="hidden" name="user_id" value="<?=$targetUserId?>"><p class="notice info wide">Doctors can upload their own documents. Verification and clinical activation are only available to another authorized Admin or Superuser.</p><label>Document type<select name="document_type"><?php foreach(['license'=>'Professional license','certification'=>'Certification','training'=>'Training','accreditation'=>'Accreditation','employment'=>'Employment','other'=>'Other'] as $value=>$label):?><option value="<?=$value?>" <?=$value==='license'?'selected':''?>><?=$label?></option><?php endforeach;?></select></label><label>Title<input name="document_title" placeholder="Professional license / PRC ID"></label><label class="wide">File<input type="file" name="document_file" accept=".pdf,.jpg,.jpeg,.png,.webp,.docx" required></label><label>Issued<input type="date" name="issued_at"></label><label>Expires<input type="date" name="expires_at"><small>For license documents, match this with the professional license expiry.</small></label><label class="wide">Notes<textarea name="document_notes" rows="3"></textarea></label><div class="wide"><button class="btn ghost">Upload securely</button></div></form>
</details>

<details class="card doctor-side-section">
<summary><span><strong>Clinical templates</strong><small>Reusable examination, SOAP, prescription, and instruction text</small></span><em><?=count($templates)?> saved</em></summary>
<form method="post" class="form-grid doctor-side-form"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="save_template"><input type="hidden" name="user_id" value="<?=$targetUserId?>"><label>Type<select name="template_type"><option value="examination">Examination</option><option value="procedure">Procedure</option><option value="soap">SOAP note</option><option value="prescription">Prescription</option><option value="instruction">Instructions</option></select></label><label>Name<input name="template_name" required></label><label class="wide">Template<textarea name="template_content" rows="5" required></textarea></label><label class="choice wide"><input type="checkbox" name="is_default" value="1"><span>Default for this type</span></label><div class="wide"><button class="btn ghost">Save template</button></div><?php if($templates):?><div class="timeline wide"><?php foreach($templates as $template):?><article class="timeline-item"><h4><?=e($template['name'])?></h4><small><?=e(ucfirst($template['template_type']))?><?=$template['is_default']?' · Default':''?></small></article><?php endforeach;?></div><?php endif;?></form>
</details>

<?php if($isAdministrativeManager):?>
<details class="card doctor-side-section doctor-admin-section">
<summary><span><strong>Clinical privileges</strong><small>Admin/Superuser only; locked until credentials are verified</small></span><em><b data-privilege-total><?=count($assignedPrivileges)?></b> selected</em></summary>
<form method="post" class="clinical-privilege-card" data-privilege-manager><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="save_privileges"><input type="hidden" name="user_id" value="<?=$targetUserId?>"><p class="muted">Each checkbox belongs to the titled category directly above it. Grant only procedures supported by verified competence and clinic policy.</p><?php if(($profile['credential_status']??'pending')!=='verified'): ?><p class="notice warning"><strong>Locked:</strong> privileges cannot be granted until the current professional license document is verified.</p><?php endif; ?><div class="clinical-privilege-groups compact-privilege-groups"><?php foreach($privilegeGroups as $groupName=>$groupPrivileges):?><details class="privilege-group" data-privilege-group><summary class="privilege-group-header"><div><span class="eyebrow">Privilege category</span><h3><?=e($groupName)?></h3><p><?=count($groupPrivileges)?> controlled function<?=count($groupPrivileges)===1?'':'s'?> · <b data-group-count>0</b> selected</p></div></summary><div class="privilege-group-actions compact-group-actions"><button type="button" class="btn link" data-group-select="all" <?=($profile['credential_status']??'pending')==='verified'?'':'disabled'?>>Select group</button><button type="button" class="btn link" data-group-select="none" <?=($profile['credential_status']??'pending')==='verified'?'':'disabled'?>>Clear</button></div><div class="clinical-privilege-grid"><?php foreach($groupPrivileges as $privilege):?><label class="clinical-privilege-option"><span class="privilege-check"><input type="checkbox" name="privileges[]" value="<?=(int)$privilege['id']?>" <?=in_array((int)$privilege['id'],$assignedPrivileges,true)?'checked':''?> <?=($profile['credential_status']??'pending')==='verified'?'':'disabled'?>><i aria-hidden="true"></i></span><span class="privilege-copy"><strong><?=e($privilege['name'])?></strong><?php if(!empty($privilege['description'])):?><small><?=e($privilege['description'])?></small><?php endif;?><span class="privilege-meta"><em class="risk-<?=e((string)$privilege['risk_level'])?>"><?=e(ucfirst((string)$privilege['risk_level']))?> risk</em><code><?=e($privilege['code'])?></code></span></span></label><?php endforeach;?></div></details><?php endforeach;?></div><div class="form-grid privilege-approval"><label>Privilege expiration <small>Optional; applies to this saved approval set</small><input type="date" name="privilege_expiry"></label><label>Approval note<textarea name="privilege_notes" rows="3" required placeholder="Competency evidence or approval basis"></textarea></label></div><button class="btn primary" <?=($profile['credential_status']??'pending')==='verified'?'':'disabled'?>>Save clinical privileges</button></form>
</details>

<details class="card doctor-side-section doctor-admin-section">
<summary><span><strong>Branches, services, and favorites</strong><small>Admin/Superuser assignment controls</small></span><em><?=count($assignedBranches)?> / <?=count($assignedServices)?> / <?=count($favoriteServices)?></em></summary>
<form method="post" class="doctor-assignment-card" data-assignment-manager>
<input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><input type="hidden" name="action" value="save_assignments"><input type="hidden" name="user_id" value="<?=$targetUserId?>"><input type="hidden" name="primary_branch_id" value="<?=e($profile['primary_branch_id']??$profile['account_branch_id']??'')?>">
<p class="muted">Use the compact sections below instead of scrolling through every option at once.</p>
<details class="assignment-section" data-assignment-section open>
<summary><span><strong>Branch access</strong><small>Where this Dentist may practice</small></span><em><b data-assignment-count><?=count($assignedBranches)?></b> selected</em></summary>
<div class="assignment-tools"><input type="search" placeholder="Search branches…" data-assignment-filter><div><button type="button" class="btn link" data-assignment-toggle="all">Select all</button><button type="button" class="btn link" data-assignment-toggle="none">Clear</button></div></div>
<div class="assignment-option-list branch-assignment-list" data-assignment-list><?php foreach($branches as $branch):?><label class="permission-row" data-assignment-option data-search-text="<?=e(strtolower($branch['name'].' '.$branch['code']))?>"><input type="checkbox" name="branch_ids[]" value="<?=(int)$branch['id']?>" <?=in_array((int)$branch['id'],$assignedBranches,true)?'checked':''?>><span><strong><?=e($branch['name'])?></strong><small><?=e($branch['code'])?></small></span></label><?php endforeach;?></div>
</details>
<details class="assignment-section" data-assignment-section>
<summary><span><strong>Services performed</strong><small>Services available for booking and treatment</small></span><em><b data-assignment-count><?=count($assignedServices)?></b> selected</em></summary>
<div class="assignment-tools"><input type="search" placeholder="Search services…" data-assignment-filter><div><button type="button" class="btn link" data-assignment-toggle="all">Select all</button><button type="button" class="btn link" data-assignment-toggle="none">Clear</button></div></div>
<div class="assignment-option-list" data-assignment-list><?php foreach($services as $service):?><label class="permission-row" data-assignment-option data-search-text="<?=e(strtolower($service['name'].' '.$service['duration_minutes'].' minutes'))?>"><input type="checkbox" name="service_ids[]" value="<?=(int)$service['id']?>" <?=in_array((int)$service['id'],$assignedServices,true)?'checked':''?>><span><strong><?=e($service['name'])?></strong><small><?=e($service['duration_minutes'])?> minutes</small></span></label><?php endforeach;?></div>
</details>
<details class="assignment-section" data-assignment-section>
<summary><span><strong>Favorite procedures</strong><small>Quick-entry shortcuts for this Dentist</small></span><em><b data-assignment-count><?=count($favoriteServices)?></b> selected</em></summary>
<div class="assignment-tools"><input type="search" placeholder="Search favorites…" data-assignment-filter><div><button type="button" class="btn link" data-assignment-toggle="all">Select all</button><button type="button" class="btn link" data-assignment-toggle="none">Clear</button></div></div>
<div class="assignment-option-list" data-assignment-list><?php foreach($services as $service):?><label class="permission-row" data-assignment-option data-search-text="<?=e(strtolower($service['name']))?>"><input type="checkbox" name="favorite_service_ids[]" value="<?=(int)$service['id']?>" <?=in_array((int)$service['id'],$favoriteServices,true)?'checked':''?>><span><strong><?=e($service['name'])?></strong></span></label><?php endforeach;?></div>
</details>
<div class="assignment-save-bar"><span data-assignment-summary><?=count($assignedBranches)?> branches · <?=count($assignedServices)?> services · <?=count($favoriteServices)?> favorites</span><button class="btn primary">Save assignments</button></div>
</form>
</details>
<?php endif;?>
</aside>
</div>
<script src="public/assets/js/doctor-photo-crop.js?v=<?=e(dental_asset_version('public/assets/js/doctor-photo-crop.js'))?>"></script>
<script>
document.querySelectorAll('.doctor-profile-form-compact .doctor-compact-section').forEach(section=>{section.addEventListener('toggle',()=>{if(!section.open)return;section.parentElement?.querySelectorAll('.doctor-compact-section[open]').forEach(other=>{if(other!==section)other.open=false;});});});
</script>

<?php render_footer();
