<?php

declare(strict_types=1);

require DENTAL_ROOT . '/app/bootstrap.php';
require DENTAL_ROOT . '/app/layout.php';

$clinic = public_clinic_profile();
$branchId = public_request_branch_id();
$serviceRows = public_services_catalog($branchId);
$dentists = active_dentists($branchId);
$errors = [];
$old = $_POST;
$startedAt = time();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $startedAt = (int) ($_POST['form_started'] ?? time());
    try {
        if (!public_intake_schema_ready()) {
            throw new RuntimeException('Online appointment registration is not ready. Please contact the clinic.');
        }
        verify_public_form('returning');

        foreach (['first_name', 'last_name', 'birth_date', 'mobile', 'service_id', 'preferred_date', 'preferred_time', 'reason'] as $field) {
            if (trim((string) ($_POST[$field] ?? '')) === '') {
                $errors[$field] = 'This field is required.';
            }
        }
        $email = trim((string) ($_POST['email'] ?? ''));
        if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $errors['email'] = 'Enter a valid email address.';
        }
        $birthDate = (string) ($_POST['birth_date'] ?? '');
        if (strtotime($birthDate) === false || strtotime($birthDate) > strtotime('today')) {
            $errors['birth_date'] = 'Enter a valid birth date.';
        }
        $preferredTime = (string) ($_POST['preferred_time'] ?? '');
        if (!preg_match('/^(?:[01]\d|2[0-3]):[0-5]\d$/', $preferredTime)) {
            $errors['preferred_time'] = 'Choose a valid preferred time.';
        }
        $alternateTime = trim((string) ($_POST['alternate_time'] ?? ''));
        if ($alternateTime !== '' && !preg_match('/^(?:[01]\d|2[0-3]):[0-5]\d$/', $alternateTime)) {
            $errors['alternate_time'] = 'Choose a valid alternate time.';
        }
        $preferredDate = (string) ($_POST['preferred_date'] ?? '');
        if (strtotime($preferredDate) === false || strtotime($preferredDate) < strtotime('today') || strtotime($preferredDate) > strtotime('+1 year')) {
            $errors['preferred_date'] = 'Choose a date from today up to one year ahead.';
        }
        $alternateDate = trim((string) ($_POST['alternate_date'] ?? ''));
        if ($alternateDate !== '' && (strtotime($alternateDate) === false || strtotime($alternateDate) < strtotime('today'))) {
            $errors['alternate_date'] = 'Choose a valid alternate date.';
        }
        $serviceId = (int) ($_POST['service_id'] ?? 0);
        $doctorId = (int) ($_POST['preferred_dentist_user_id'] ?? 0);
        $providerPreference = (string)($_POST['provider_preference_mode'] ?? 'specific');
        if (!in_array($providerPreference, ['specific','clinic_decides'], true)) $providerPreference = 'specific';
        $serviceRow = public_service_definition($serviceId, $branchId);
        $providerType = $serviceRow ? service_provider_type($serviceRow) : 'dentist';
        $doctorRow = null;
        $availableAtRequestedTime = [];
        if (!$serviceRow) {
            $errors['service_id'] = 'Choose an available service.';
        } elseif ($providerType === 'inhouse') {
            $providerPreference = 'clinic_decides';
            $doctorId = 0;
            if (!$errors && !validate_service_slot((int)$branchId,$serviceRow,$preferredDate,$preferredTime,0)) {
                $errors['preferred_time'] = 'This time is no longer available. Choose another listed time.';
            }
        } elseif ($providerPreference === 'specific') {
            foreach ($dentists as $candidate) {
                if ((int) $candidate['id'] === $doctorId) { $doctorRow = $candidate; break; }
            }
            if (!$doctorRow) {
                $errors['preferred_dentist_user_id'] = 'Choose an available dentist.';
            } elseif (!$errors && !validate_service_slot((int)$branchId,$serviceRow,$preferredDate,$preferredTime,$doctorId)) {
                $errors['preferred_time'] = 'This dentist is no longer available at that time. Choose another listed option.';
            }
        } else {
            $doctorId = 0;
            if (!$errors) {
                $availableAtRequestedTime = available_doctors_for_slot((int)$branchId,$serviceId,$preferredDate,$preferredTime,false);
                if (!$availableAtRequestedTime) {
                    $errors['preferred_time'] = 'No qualified dentist is available at that time. Choose another listed time.';
                }
            }
        }
        $service = (string) ($serviceRow['name'] ?? '');
        $dentistName = $providerType === 'inhouse'
            ? 'In-house clinic team'
            : ($providerPreference === 'clinic_decides' ? 'Let the dental clinic decide' : (string) ($doctorRow['name'] ?? ''));
        $urgency = in_array((string)($_POST['urgency'] ?? ''), ['routine','soon','urgent'], true) ? (string)$_POST['urgency'] : 'routine';
        if ($urgency === 'urgent' && mb_strlen(trim((string)($_POST['reason'] ?? ''))) < 20) {
            $errors['reason'] = 'Describe the urgent concern in enough detail for the clinic to prioritize it. For emergencies, contact the clinic directly.';
        }

        if (!isset($_POST['privacy_consent'])) {
            $errors['privacy_consent'] = 'Consent is required to submit the request.';
        }
        if ($errors) {
            throw new RuntimeException('Review the highlighted fields.');
        }

        $pdo = db();
        $patientNo = trim((string) ($_POST['patient_no'] ?? ''));
        $patient = false;
        if ($patientNo !== '') {
            $stmt = $pdo->prepare('SELECT id FROM `' . table('patients') . '` WHERE branch_id=? AND patient_no=? AND birth_date=? AND deleted_at IS NULL LIMIT 1');
            $stmt->execute([(int)$branchId,$patientNo, $birthDate]);
            $patient = $stmt->fetchColumn();
        }
        if ($patient === false) {
            $stmt = $pdo->prepare(
                "SELECT id FROM `" . table('patients') . "` WHERE branch_id=? AND LOWER(first_name)=LOWER(?) AND LOWER(last_name)=LOWER(?) AND birth_date=? AND deleted_at IS NULL "
                . "AND (mobile=? OR (? <> '' AND email=?)) LIMIT 1"
            );
            $stmt->execute([
                (int)$branchId,
                trim((string) $_POST['first_name']),
                trim((string) $_POST['last_name']),
                $birthDate,
                trim((string) $_POST['mobile']),
                $email,
                $email,
            ]);
            $patient = $stmt->fetchColumn();
        }

        if ($patient !== false && $providerType === 'dentist' && $providerPreference === 'specific') {
            $continuityDoctor = patient_primary_dentist((int)$patient);
            if ($continuityDoctor && (int)$continuityDoctor['id'] !== $doctorId) {
                $continuityRow = null;
                foreach ($dentists as $candidate) {
                    if ((int)$candidate['id'] === (int)$continuityDoctor['id']) { $continuityRow = $candidate; break; }
                }
                if (!$continuityRow || !$serviceRow || !validate_doctor_slot((int)$continuityDoctor['id'], (int)$branchId, $preferredDate, $preferredTime, (int)$serviceRow['duration_minutes'], (int)$serviceRow['preparation_minutes'], (int)$serviceRow['cleanup_minutes'])) {
                    $errors['preferred_time'] = 'For continuity of care, this appointment must remain with your established dentist. Choose another date or time when that dentist is available, or choose Let the dental clinic decide so staff can review an approved transfer.';
                    throw new RuntimeException('Review the highlighted fields.');
                }
                $doctorId = (int)$continuityDoctor['id'];
                $doctorRow = $continuityRow;
                $dentistName = (string)$continuityRow['name'];
            }
        } elseif ($patient !== false && $providerType === 'dentist' && $providerPreference === 'clinic_decides') {
            $continuityDoctor = patient_primary_dentist((int)$patient);
            if ($continuityDoctor) {
                $dentistName = 'Let the dental clinic decide — continuity review needed';
            }
        }

        $reference = public_reference();
        $request = [
            'public_reference' => $reference,
            'branch_id' => $branchId,
            'patient_type' => 'returning',
            'patient_id' => $patient !== false ? (int) $patient : null,
            'patient_no_entered' => $patientNo ?: null,
            'first_name' => trim((string) $_POST['first_name']),
            'middle_name' => trim((string) ($_POST['middle_name'] ?? '')) ?: null,
            'last_name' => trim((string) $_POST['last_name']),
            'birth_date' => $birthDate,
            'mobile' => trim((string) $_POST['mobile']),
            'email' => $email ?: null,
            'service_name' => $service,
            'service_id' => $serviceId,
            'preferred_dentist' => $dentistName,
            'preferred_dentist_user_id' => $doctorId > 0 ? $doctorId : null,
            'provider_preference_mode' => $providerPreference,
            'preferred_date' => $preferredDate,
            'preferred_time' => $preferredTime,
            'alternate_date' => $alternateDate ?: null,
            'alternate_time' => $alternateTime ?: null,
            'urgency' => $urgency,
            'reason' => trim((string) $_POST['reason']),
            'medical_changes' => trim((string) ($_POST['medical_changes'] ?? '')) ?: null,
            'status' => $patient !== false ? 'submitted' : 'needs_verification',
            'submitted_ip' => substr((string) ($_SERVER['REMOTE_ADDR'] ?? ''), 0, 45) ?: null,
        ];

        $providerPreferenceReady = schema_column_exists(table('appointment_requests'),'provider_preference_mode');
        $providerPreferenceColumn = $providerPreferenceReady ? ',provider_preference_mode' : '';
        $providerPreferenceValue = $providerPreferenceReady ? ',:provider_preference_mode' : '';
        if (!$providerPreferenceReady) unset($request['provider_preference_mode']);
        $stmt = $pdo->prepare(
            'INSERT INTO `' . table('appointment_requests') . '` '
            . '(public_reference,branch_id,patient_type,patient_id,patient_no_entered,first_name,middle_name,last_name,birth_date,mobile,email,service_name,service_id,preferred_dentist,preferred_dentist_user_id' . $providerPreferenceColumn . ',preferred_date,preferred_time,alternate_date,alternate_time,urgency,reason,medical_changes,status,consent_at,submitted_ip,created_at) '
            . 'VALUES (:public_reference,:branch_id,:patient_type,:patient_id,:patient_no_entered,:first_name,:middle_name,:last_name,:birth_date,:mobile,:email,:service_name,:service_id,:preferred_dentist,:preferred_dentist_user_id' . $providerPreferenceValue . ',:preferred_date,:preferred_time,:alternate_date,:alternate_time,:urgency,:reason,:medical_changes,:status,NOW(),:submitted_ip,NOW())'
        );
        $stmt->execute($request);
        $requestId=(int)$pdo->lastInsertId();
        $_SESSION['last_public_appointment_submission'] = time();
        $_SESSION['public_request_receipt'] = [
            'reference' => $reference,
            'name' => $request['first_name'],
            'service' => $request['service_name'],
            'preferred_date' => $request['preferred_date'],
            'preferred_time' => $request['preferred_time'],
        ];
        public_request_email((string) ($request['email'] ?? ''), (string) $request['first_name'], $reference, $request, $clinic,$requestId);
        clinic_request_notification($reference, $request, $clinic);
        header('Location: appointment-received.php');
        exit;
    } catch (Throwable $exception) {
        if (!$errors) {
            $errors['form'] = $exception->getMessage();
        }
    }
}

render_header('Returning Patient Appointment', true);
render_public_nav('appointment');
?>
<main class="public-form-page">
    <section class="public-form-intro">
        <span class="eyebrow">Returning patient</span>
        <h1>Request your next dental appointment</h1>
        <p>Enter enough information for the clinic to locate your existing record. For privacy, this page will not display whether a matching patient record was found. Returning appointments and follow-ups stay with your established dentist unless the clinic records an approved care transfer.</p>
        <div class="form-step-line"><span class="active">1. Verify identity</span><span>2. Report changes</span><span>3. Request schedule</span></div>
    </section>

    <?php if (!public_intake_schema_ready()): ?>
        <div class="public-notice warning"><strong>Online registration is temporarily unavailable.</strong> Please contact the clinic while the administrator completes the appointment-intake update.</div>
    <?php endif; ?>
    <?php if (isset($errors['form'])): ?><div class="public-notice error"><?= e($errors['form']) ?></div><?php endif; ?>

    <form method="post" class="public-intake-form" novalidate>
        <input type="hidden" name="csrf" value="<?= e(csrf_token()) ?>">
        <input type="hidden" name="form_started" value="<?= e((string) $startedAt) ?>">
        <input type="hidden" name="form_signature" value="<?= e(public_form_signature('returning', $startedAt)) ?>">
        <label class="honeypot" aria-hidden="true">Website<input name="website" tabindex="-1" autocomplete="off"></label>

        <section class="form-section-card">
            <div class="form-section-heading"><span>01</span><div><h2>Patient identity</h2><p>Use the same name and birth date recorded during your previous visit.</p></div></div>
            <div class="form-grid three-columns">
                <label>Patient number<input name="patient_no" data-returning-identity maxlength="30" placeholder="Optional, if known" value="<?= e((string) ($old['patient_no'] ?? '')) ?>"></label>
                <span class="form-helper span-2">Your patient number helps the clinic find the correct record but is not required.</span>
                <label>First name<input name="first_name" data-returning-identity maxlength="100" value="<?= e((string) ($old['first_name'] ?? '')) ?>" required><?php if (isset($errors['first_name'])): ?><small class="field-error"><?= e($errors['first_name']) ?></small><?php endif; ?></label>
                <label>Middle name<input name="middle_name" maxlength="100" value="<?= e((string) ($old['middle_name'] ?? '')) ?>"></label>
                <label>Last name<input name="last_name" data-returning-identity maxlength="100" value="<?= e((string) ($old['last_name'] ?? '')) ?>" required><?php if (isset($errors['last_name'])): ?><small class="field-error"><?= e($errors['last_name']) ?></small><?php endif; ?></label>
                <label>Birth date<input type="date" name="birth_date" data-returning-identity max="<?= e(date('Y-m-d')) ?>" value="<?= e((string) ($old['birth_date'] ?? '')) ?>" required><?php if (isset($errors['birth_date'])): ?><small class="field-error"><?= e($errors['birth_date']) ?></small><?php endif; ?></label>
                <label>Current mobile number<input name="mobile" data-returning-identity maxlength="40" value="<?= e((string) ($old['mobile'] ?? '')) ?>" required><?php if (isset($errors['mobile'])): ?><small class="field-error"><?= e($errors['mobile']) ?></small><?php endif; ?></label>
                <label>Current email address<input type="email" name="email" data-returning-identity maxlength="190" value="<?= e((string) ($old['email'] ?? '')) ?>"><?php if (isset($errors['email'])): ?><small class="field-error"><?= e($errors['email']) ?></small><?php endif; ?></label>
            </div>
        </section>

        <section class="form-section-card">
            <div class="form-section-heading"><span>02</span><div><h2>Changes since your last visit</h2><p>Tell the dentist about any new allergy, medicine, pregnancy, bleeding risk, hospitalization, anesthesia reaction, or health change that may affect dental care.</p></div></div>
            <label>Medical, medication, allergy, or contact changes<textarea name="medical_changes" maxlength="2500" placeholder="Write None if there are no changes."><?= e((string) ($old['medical_changes'] ?? '')) ?></textarea></label>
        </section>

        <section class="form-section-card">
            <div class="form-section-heading"><span>03</span><div><h2>Appointment preference</h2><p>Choose your preferred and alternate schedule.</p></div></div>
            <div class="form-grid three-columns">
                <div class="wide form-grid three-columns" data-slot-picker data-schedule-first data-provider-choice-enabled data-returning-booking data-patient-type="returning" data-branch-id="<?= e((string) $branchId) ?>" data-preferred-time="<?=e((string)($old['preferred_time']??''))?>" data-preferred-doctor="<?=e((string)($old['preferred_dentist_user_id']??''))?>">
                    <label>Service needed<select name="service_id" data-slot-service required><option value="">Choose a service</option><?php foreach ($serviceRows as $service): ?><option value="<?= e((string)$service['id']) ?>" data-provider-type="<?=e(service_provider_type($service))?>" data-requires-chair="<?=(int)($service['requires_chair']??1)?>" <?= ((int)($old['service_id'] ?? 0) === (int)$service['id']) ? 'selected' : '' ?>><?= e((string)$service['name']) ?> · <?= e((string)$service['duration_minutes']) ?> min</option><?php endforeach; ?></select><?php if (isset($errors['service_id'])): ?><small class="field-error"><?= e($errors['service_id']) ?></small><?php endif; ?></label>
                    <fieldset class="wide provider-choice" data-provider-choice><legend>Who should provide the dental care?</legend><label class="check-label"><input type="radio" name="provider_preference_mode" value="specific" <?= (($old['provider_preference_mode'] ?? 'specific') === 'specific') ? 'checked' : '' ?>><span><strong>Use my established or selected dentist</strong><small>The clinic will keep continuity of care when your established dentist is available.</small></span></label><label class="check-label"><input type="radio" name="provider_preference_mode" value="clinic_decides" <?= (($old['provider_preference_mode'] ?? '') === 'clinic_decides') ? 'checked' : '' ?>><span><strong>Let the dental clinic decide</strong><small>Use this when your usual dentist is unavailable or staff should assign the best available provider.</small></span></label></fieldset>
                    <label>Preferred date<input type="date" name="preferred_date" data-slot-date min="<?= e(date('Y-m-d')) ?>" max="<?= e(date('Y-m-d', strtotime('+1 year'))) ?>" value="<?= e((string) ($old['preferred_date'] ?? '')) ?>" required><?php if (isset($errors['preferred_date'])): ?><small class="field-error"><?= e($errors['preferred_date']) ?></small><?php endif; ?></label>
                    <div class="continuity-schedule-status span-2" data-continuity-status>Continuity-of-care will be verified by clinic staff before confirmation. The times shown below are preferred request times.</div><div class="available-dates-panel" data-available-dates>Choose a service to see the next available dates and times.</div>
                    <label>Preferred available time<select name="preferred_time" data-slot-time required><option value="">Select service and date</option></select><?php if (isset($errors['preferred_time'])): ?><small class="field-error"><?= e($errors['preferred_time']) ?></small><?php endif; ?></label>
                    <label data-slot-doctor-label>Available dentist<select name="preferred_dentist_user_id" data-slot-doctor><option value="">Choose a time first</option></select><?php if (isset($errors['preferred_dentist_user_id'])): ?><small class="field-error"><?= e($errors['preferred_dentist_user_id']) ?></small><?php endif; ?></label>
                    <div class="slot-status span-2" data-slot-status>Choose the preferred date and time first. DentalCare will then show only doctors who can accept that service at the selected schedule.</div>
                </div>
                <label>Urgency<select name="urgency" data-urgency-select><option value="routine" <?= (($old['urgency'] ?? 'routine') === 'routine') ? 'selected' : '' ?>>Routine</option><option value="soon" <?= (($old['urgency'] ?? '') === 'soon') ? 'selected' : '' ?>>Need an appointment soon</option><option value="urgent" <?= (($old['urgency'] ?? '') === 'urgent') ? 'selected' : '' ?>>Urgent dental concern</option></select></label>
                <div class="public-notice warning wide" data-urgent-notice hidden><strong>Urgent concern:</strong> This form does not provide emergency care. Contact the clinic directly for severe pain, uncontrolled bleeding, facial swelling, breathing difficulty, or trauma.</div>
                <span></span><span></span>
                <label>Alternate date<input type="date" name="alternate_date" min="<?= e(date('Y-m-d')) ?>" max="<?= e(date('Y-m-d', strtotime('+1 year'))) ?>" value="<?= e((string) ($old['alternate_date'] ?? '')) ?>"><?php if (isset($errors['alternate_date'])): ?><small class="field-error"><?= e($errors['alternate_date']) ?></small><?php endif; ?></label>
                <label>Alternate time<input type="time" name="alternate_time" value="<?= e((string) ($old['alternate_time'] ?? '')) ?>"></label>
                <span></span>
                <label class="wide">Reason for visit or current dental concern<textarea name="reason" maxlength="2000" required><?= e((string) ($old['reason'] ?? '')) ?></textarea><?php if (isset($errors['reason'])): ?><small class="field-error"><?= e($errors['reason']) ?></small><?php endif; ?></label>
                <p class="wide muted"><strong>Schedule notice:</strong> This is a preferred time only. It is not reserved until the clinic confirms the appointment.</p>
            </div>
        </section>

        <section class="form-consent-card">
            <label class="check-label"><input type="checkbox" name="privacy_consent" value="1" <?= isset($old['privacy_consent']) ? 'checked' : '' ?>><span>I authorize the clinic to use this information to locate my patient record, review this appointment request, and prepare for care. I understand that the preferred schedule is not final until confirmed.</span></label>
            <?php if (isset($errors['privacy_consent'])): ?><small class="field-error"><?= e($errors['privacy_consent']) ?></small><?php endif; ?>
            <div class="form-submit-row"><a class="btn ghost" href="index.php#appointment">Back</a><button class="btn primary" type="submit" <?= !public_intake_schema_ready() ? 'disabled' : '' ?>>Submit Appointment Request</button></div>
        </section>
    </form>
</main>
<?php
render_public_footer();
render_footer(true);
