<?php
// ─────────────────────────────────────────────────────────────
//  customer/dashboard.php — Member portal
// ─────────────────────────────────────────────────────────────
require_once dirname(__DIR__) . '/lib.php';
session_start_safe();

// Remember-me auto-login
if (empty($_SESSION['bk_user_id']) && !empty($_COOKIE['bk_remember'])) {
    $u = db()->prepare('SELECT id, email FROM bk_users WHERE remember_token = ?');
    $u->execute([$_COOKIE['bk_remember']]);
    $rem = $u->fetch();
    if ($rem) {
        $_SESSION['bk_user_id']    = (int)$rem['id'];
        $_SESSION['bk_user_email'] = $rem['email'];
        $_SESSION['bk_user_time']  = time();
    }
}

if (!customer_logged_in()) {
    header('Location: ../login.php?redirect=customer/dashboard.php'); exit;
}

$userId = (int)$_SESSION['bk_user_id'];
$pdo    = db();

// User + customer profile
$user = $pdo->prepare('
    SELECT u.id, u.email, u.email_verified_at, u.created_at AS member_since,
           c.id AS customer_id, c.name, c.phone, c.dob, c.gender, c.address_line1,
           c.city, c.country, c.emergency_contact_name, c.emergency_contact_phone
    FROM bk_users u
    LEFT JOIN bk_customers c ON c.user_id = u.id
    WHERE u.id = ?
');
$user->execute([$userId]);
$user = $user->fetch();
if (!$user) { session_destroy(); header('Location: ../login.php'); exit; }

$customerId  = (int)($user['customer_id'] ?? 0);
$displayName = $user['name'] ?: explode('@', $user['email'])[0];
$initials    = strtoupper(mb_substr($displayName, 0, 1));
$verified    = !empty($user['email_verified_at']);

// Active membership
$membership = null;
if ($customerId) {
    $ms = $pdo->prepare('
        SELECT m.*, p.name AS plan_name, p.color AS plan_color, p.description AS plan_desc,
               p.session_limit
        FROM bk_memberships m
        JOIN bk_plans p ON p.id = m.plan_id
        WHERE m.customer_id = ? AND m.status = "active"
          AND (m.expires_at IS NULL OR m.expires_at > NOW())
        ORDER BY m.created_at DESC LIMIT 1
    ');
    $ms->execute([$customerId]);
    $membership = $ms->fetch();
}

// Signed QR token for check-in (short-lived)
$qrToken = null;
if ($membership && defined('QR_SIGNING_SECRET') && QR_SIGNING_SECRET) {
    $payload = [
        'membership_id' => (int)$membership['id'],
        'customer_id'   => (int)$customerId,
        'exp'           => time() + 15 * 60,
        'nonce'         => bin2hex(random_bytes(8)),
    ];
    $payloadJson = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    if ($payloadJson !== false) {
        $sig = hash_hmac('sha256', $payloadJson, QR_SIGNING_SECRET, true);
        $p64 = rtrim(strtr(base64_encode($payloadJson), '+/', '-_'), '=');
        $s64 = rtrim(strtr(base64_encode($sig), '+/', '-_'), '=');
        $qrToken = $p64 . '.' . $s64;
    }
}

$profileRequired = (bool)$membership;
$profileComplete = !empty($user['name'])
    && !empty($user['phone'])
    && !empty($user['dob'])
    && !empty($user['gender'])
    && !empty($user['address_line1'])
    && !empty($user['city'])
    && !empty($user['country'])
    && !empty($user['emergency_contact_name'])
    && !empty($user['emergency_contact_phone']);

// Upcoming appointments
$upcoming = [];
if ($customerId) {
    $us = $pdo->prepare('
        SELECT a.id, a.ref, a.start_datetime, a.end_datetime, a.status, a.notes,
               a.provider_id, a.service_id,
               s.name AS service_name, s.color AS service_color,
               pr.name AS provider_name
        FROM bk_appointments a
        JOIN bk_services s ON s.id = a.service_id
        LEFT JOIN bk_providers pr ON pr.id = a.provider_id
        WHERE a.customer_id = ?
          AND a.start_datetime >= NOW()
          AND a.status NOT IN ("cancelled","no_show")
        ORDER BY a.start_datetime ASC LIMIT 6
    ');
    $us->execute([$customerId]);
    $upcoming = $us->fetchAll();
}

// Membership/payment history
$membershipHistory = [];
if ($customerId) {
    $mh = $pdo->prepare('
        SELECT m.id, m.starts_at, m.expires_at, m.status, m.activated_by,
               m.stripe_payment_id, m.stripe_session_id, m.created_at,
               m.sessions_total, m.sessions_remaining,
               p.name AS plan_name, p.session_limit
        FROM bk_memberships m
        JOIN bk_plans p ON p.id = m.plan_id
        WHERE m.customer_id = ?
        ORDER BY m.created_at DESC
        LIMIT 12
    ');
    $mh->execute([$customerId]);
    $membershipHistory = $mh->fetchAll();
}

// Past appointments
$past = [];
if ($customerId) {
    $ps = $pdo->prepare('
        SELECT a.id, a.ref, a.start_datetime, a.status,
               s.name AS service_name, s.color AS service_color,
               pr.name AS provider_name
        FROM bk_appointments a
        JOIN bk_services s ON s.id = a.service_id
        LEFT JOIN bk_providers pr ON pr.id = a.provider_id
        WHERE a.customer_id = ?
          AND (a.start_datetime < NOW() OR a.status IN ("cancelled","no_show"))
        ORDER BY a.start_datetime DESC LIMIT 8
    ');
    $ps->execute([$customerId]);
    $past = $ps->fetchAll();
}


// Loyalty badge data
$loyaltyPoints = 0;
$totalBookings = 0;
if ($customerId) {
    $lq = $pdo->prepare('SELECT loyalty_points, total_bookings FROM bk_customers WHERE id=?');
    $lq->execute([$customerId]);
    $lr = $lq->fetch();
    $loyaltyPoints = (int)($lr['loyalty_points'] ?? 0);
    $totalBookings = (int)($lr['total_bookings'] ?? 0);
}

// Completed appointments eligible for rating
$ratable = [];
if ($customerId) {
    $rq = $pdo->prepare('
        SELECT a.id, a.ref, a.start_datetime, s.name AS service_name, pr.name AS provider_name
        FROM bk_appointments a
        JOIN bk_services s ON s.id = a.service_id
        LEFT JOIN bk_providers pr ON pr.id = a.provider_id
        LEFT JOIN bk_ratings r ON r.appointment_id = a.id
        WHERE a.customer_id = ?
          AND a.status IN ("completed","confirmed")
          AND a.start_datetime < NOW()
          AND r.id IS NULL
        ORDER BY a.start_datetime DESC LIMIT 3
    ');
    $rq->execute([$customerId]);
    $ratable = $rq->fetchAll();
}

function fmt_dt(string $d): string { return date('D, M j · g:i A', strtotime($d)); }
function days_left(?string $exp): string {
    if (!$exp) return '∞';
    $diff = (strtotime($exp) - time()) / 86400;
    if ($diff < 0) return 'Expired';
    if ($diff < 1) return 'Today';
    return floor($diff) . 'd left';
}
function status_class(string $s): string {
    return match($s) {
        'confirmed' => 'badge-green',
        'pending'   => 'badge-amber',
        'completed' => 'badge-blue',
        default     => 'badge-red',
    };
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>My Account — <?= esc(APP_NAME) ?></title>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<link href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Syne:wght@700;800&family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600&display=swap" rel="stylesheet"/>
<style>
*{box-sizing:border-box;margin:0;padding:0}
:root{
  --bg:#f4f5f7;--surface:#fff;--card-alt:#f8f9fb;
  --border:#e8eaed;--border-hi:#d1d5db;
  --accent:#e09500;--accent-hi:#f5a623;--accent-d:#b87800;
  --accent-pale:#fff8eb;--accent-glow:rgba(224,149,0,.18);--accent-border:rgba(224,149,0,.3);
  --green:#16a34a;--green-pale:#f0fdf4;--green-border:#bbf7d0;
  --red:#dc2626;--red-pale:#fef2f2;--red-border:#fecaca;
  --amber:#d97706;--amber-pale:#fffbeb;--amber-border:#fde68a;
  --blue:#4f46e5;--blue-pale:#eef2ff;--blue-border:#c7d2fe;
  --text:#111827;--text-2:#4b5563;--text-3:#9ca3af;
  --font-d:'Syne',sans-serif;--font-b:'DM Sans',sans-serif;--font-m:'DM Mono',monospace;
}
html,body{min-height:100vh;background:var(--bg);color:var(--text);font-family:var(--font-b);-webkit-font-smoothing:antialiased;font-size:14px;line-height:1.6}
a{text-decoration:none;color:inherit}button{font-family:inherit}

/* ── Topbar ── */
.topbar{background:linear-gradient(135deg,var(--accent-hi),var(--accent-d));height:56px;padding:0 20px;display:flex;align-items:center;gap:12px;box-shadow:0 2px 8px rgba(0,0,0,.12);position:sticky;top:0;z-index:100}
.topbar-logo{width:30px;height:30px;background:rgba(255,255,255,.2);border-radius:8px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.topbar-logo svg{width:14px;height:14px;stroke:#fff;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.topbar-name{font-family:var(--font-d);font-size:15px;font-weight:800;color:#fff}
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:10px}
.topbar-btn{background:rgba(255,255,255,.18);color:#fff;font-size:12px;font-weight:600;padding:7px 14px;border-radius:8px;border:1px solid rgba(255,255,255,.28);cursor:pointer;text-decoration:none;transition:background .15s;white-space:nowrap}
.topbar-btn:hover{background:rgba(255,255,255,.3)}
.topbar-ava{width:32px;height:32px;border-radius:50%;background:rgba(255,255,255,.25);color:#fff;font-family:var(--font-d);font-size:13px;font-weight:800;display:flex;align-items:center;justify-content:center;cursor:pointer;border:2px solid rgba(255,255,255,.5);flex-shrink:0}

/* ── Banner ── */
.banner{background:var(--amber-pale);border-bottom:1px solid var(--amber-border);padding:11px 20px;display:flex;align-items:center;gap:10px;font-size:13px;color:var(--amber)}
.banner svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
.banner-btn{margin-left:auto;font-size:12px;font-weight:700;color:var(--amber);background:none;border:1px solid var(--amber-border);border-radius:7px;padding:5px 12px;cursor:pointer;white-space:nowrap;transition:background .15s}
.banner-btn:hover{background:rgba(217,119,6,.1)}
.banner-btn:disabled{opacity:.6;cursor:not-allowed}

/* ── Layout ── */
.page{max-width:780px;margin:0 auto;padding:24px 16px 60px}

/* ── Profile strip ── */
.profile{background:var(--surface);border-radius:16px;border:1px solid var(--border);padding:18px 22px;display:flex;align-items:center;gap:16px;margin-bottom:18px;box-shadow:0 1px 4px rgba(0,0,0,.04)}
.profile-ava{width:50px;height:50px;border-radius:50%;background:linear-gradient(135deg,var(--accent-hi),var(--accent-d));color:#fff;font-family:var(--font-d);font-size:20px;font-weight:800;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 2px 8px var(--accent-glow)}
.profile-name{font-family:var(--font-d);font-size:17px;font-weight:800}
.profile-email{font-size:12px;color:var(--text-3);margin-top:1px}
.profile-right{margin-left:auto;display:flex;gap:8px;flex-shrink:0}
.pbtn{font-size:12px;font-weight:600;padding:7px 13px;border-radius:8px;border:1.5px solid var(--border-hi);color:var(--text-2);background:transparent;cursor:pointer;transition:border-color .15s,color .15s,background .15s;white-space:nowrap}
.pbtn:hover{border-color:var(--accent);color:var(--accent)}
.pbtn-danger:hover{border-color:var(--red-border);color:var(--red)}
.badge{display:inline-flex;align-items:center;gap:3px;font-family:var(--font-m);font-size:9px;font-weight:500;padding:2px 7px;border-radius:5px;vertical-align:middle;margin-left:6px}
.badge-verified{background:var(--green-pale);color:var(--green);border:1px solid var(--green-border)}
.badge-unverified{background:var(--amber-pale);color:var(--amber);border:1px solid var(--amber-border)}

/* ── Section header ── */
.sec{display:flex;align-items:center;gap:10px;margin:0 0 12px}
.sec-title{font-family:var(--font-d);font-size:13px;font-weight:800;white-space:nowrap}
.sec-line{flex:1;height:1px;background:var(--border)}

/* ── Membership card ── */
.mem{background:var(--surface);border-radius:16px;border:1px solid var(--border);overflow:hidden;margin-bottom:18px;box-shadow:0 1px 4px rgba(0,0,0,.04)}
.mem-hdr{padding:16px 20px;color:#fff;display:flex;align-items:center;gap:10px}
.mem-dot{width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.45);flex-shrink:0}
.mem-plan{font-family:var(--font-d);font-size:16px;font-weight:800}
.mem-status{margin-left:auto;font-family:var(--font-m);font-size:10px;font-weight:500;padding:3px 10px;border-radius:20px;background:rgba(255,255,255,.2);letter-spacing:.06em}
.mem-body{padding:14px 20px;display:grid;grid-template-columns:1fr 1fr;gap:8px}
.mem-stat{background:var(--card-alt);border-radius:10px;padding:11px 14px}
.mem-stat-lbl{font-family:var(--font-m);font-size:9px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);margin-bottom:2px}
.mem-stat-val{font-size:15px;font-weight:700}
.mem-stat-full{grid-column:1/-1}
.mem-none{padding:24px;text-align:center}
.mem-none-title{font-family:var(--font-d);font-weight:800;font-size:15px;color:var(--amber);margin-bottom:4px}
.mem-none-sub{font-size:13px;color:var(--text-3);margin-bottom:14px}

/* ── Buttons ── */
.btn-accent{display:inline-block;padding:9px 20px;background:var(--accent);color:#fff;font-size:13px;font-weight:700;border-radius:9px;border:none;cursor:pointer;transition:background .15s,box-shadow .15s}
.btn-accent:hover{background:var(--accent-hi);box-shadow:0 3px 10px var(--accent-glow)}

/* ── Appointments ── */
.appt-list{display:flex;flex-direction:column;gap:8px;margin-bottom:18px}
.appt{background:var(--surface);border-radius:13px;border:1px solid var(--border);padding:13px 16px;display:flex;align-items:center;gap:12px;box-shadow:0 1px 3px rgba(0,0,0,.03);transition:box-shadow .15s}
.appt:hover{box-shadow:0 2px 10px rgba(0,0,0,.07)}
.appt-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0}
.appt-info{flex:1;min-width:0}
.appt-svc{font-weight:600;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.appt-meta{font-size:12px;color:var(--text-3);margin-top:1px}
.appt-right{display:flex;align-items:center;gap:8px;flex-shrink:0}
.badge-green{background:var(--green-pale);color:var(--green);border:1px solid var(--green-border)}
.badge-amber{background:var(--amber-pale);color:var(--amber);border:1px solid var(--amber-border)}
.badge-red{background:var(--red-pale);color:var(--red);border:1px solid var(--red-border)}
.badge-blue{background:var(--blue-pale);color:var(--blue);border:1px solid var(--blue-border)}
.appt-badge{font-family:var(--font-m);font-size:9px;font-weight:500;padding:3px 8px;border-radius:6px}
.cancel-btn{font-size:11px;font-weight:600;padding:4px 10px;border-radius:6px;border:1px solid var(--red-border);color:var(--red);background:transparent;cursor:pointer;transition:background .15s;white-space:nowrap}
.cancel-btn:hover{background:var(--red-pale)}
.reschedule-btn{font-size:11px;font-weight:600;padding:4px 10px;border-radius:6px;border:1px solid var(--border-hi);color:var(--text-2);background:transparent;cursor:pointer;transition:background .15s;white-space:nowrap;margin-right:4px}
.reschedule-btn:hover{background:var(--surface-hi)}
.rs-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;max-height:240px;overflow-y:auto;margin-top:8px}
.rs-slot{padding:8px 4px;border-radius:8px;border:1.5px solid var(--border);text-align:center;font-size:13px;font-weight:600;cursor:pointer;transition:all .15s;color:var(--text)}
.rs-slot:hover{border-color:var(--accent);color:var(--accent)}
.rs-slot.selected{border-color:var(--accent);background:var(--accent);color:#fff}
.rs-slot.full{opacity:.4;cursor:not-allowed;pointer-events:none}

.empty{background:var(--surface);border-radius:13px;border:1px dashed var(--border-hi);padding:26px;text-align:center;color:var(--text-3);font-size:13px;margin-bottom:18px}
.empty a{color:var(--accent);font-weight:600}

.past-appt{opacity:.65}

/* ── Loyalty badges ── */
.loyalty-strip{display:flex;gap:10px;margin-bottom:18px;flex-wrap:wrap}
.loyalty-badge{background:var(--surface);border:1px solid var(--border);border-radius:13px;padding:12px 16px;display:flex;align-items:center;gap:10px;flex:1;min-width:120px;box-shadow:0 1px 3px rgba(0,0,0,.03)}
.loyalty-icon{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0}
.loyalty-label{font-family:var(--font-m);font-size:9px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3)}
.loyalty-val{font-family:var(--font-d);font-size:16px;font-weight:800}
/* ── Rate prompt ── */
.rate-card{background:var(--accent-pale);border:1px solid var(--accent-border);border-radius:13px;padding:14px 16px;margin-bottom:18px}
.rate-card-title{font-family:var(--font-d);font-size:13px;font-weight:800;color:var(--accent-d);margin-bottom:10px}
.rate-item{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--accent-border)}
.rate-item:last-child{border-bottom:none;padding-bottom:0}
.rate-item-info{flex:1;min-width:0}
.rate-item-svc{font-weight:600;font-size:13px}
.rate-item-meta{font-size:11px;color:var(--text-3)}
.star-row{display:flex;gap:2px;cursor:pointer}
.star{font-size:20px;color:var(--border-hi);transition:color .1s;cursor:pointer}
.star.lit{color:#f5a623}
.rate-submit{margin-top:6px;font-size:12px;font-weight:700;padding:5px 13px;background:var(--accent);color:#fff;border:none;border-radius:7px;cursor:pointer;white-space:nowrap}
.rate-submit:disabled{opacity:.6;cursor:not-allowed}


/* ── Modal ── */
.modal-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:200;align-items:center;justify-content:center;padding:16px}
.modal-overlay.open{display:flex}
.modal{background:var(--surface);border-radius:20px;width:100%;max-width:440px;overflow:hidden;box-shadow:0 8px 40px rgba(0,0,0,.18)}
.modal-hdr{background:linear-gradient(135deg,var(--accent-hi),var(--accent-d));padding:20px 24px;display:flex;align-items:center;justify-content:space-between}
.modal-title{font-family:var(--font-d);font-size:17px;font-weight:800;color:#fff}
.modal-close{background:none;border:none;color:rgba(255,255,255,.7);font-size:22px;cursor:pointer;line-height:1;padding:0 2px}
.modal-close:hover{color:#fff}
.modal-body{padding:24px}
.modal-row{margin-bottom:16px}
.modal-row label{display:block;font-size:12px;font-weight:600;color:var(--text-2);letter-spacing:.03em;margin-bottom:5px}
.modal-row input{width:100%;padding:10px 13px;border:1.5px solid var(--border-hi);border-radius:9px;font-family:var(--font-b);font-size:14px;color:var(--text);background:var(--surface);transition:border-color .15s,box-shadow .15s;outline:none;-webkit-appearance:none}
.modal-row input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}
.modal-divider{border:none;border-top:1px solid var(--border);margin:18px 0;padding-top:18px}
.modal-divider-lbl{font-family:var(--font-m);font-size:10px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);margin-bottom:14px}
.modal-footer{display:flex;gap:8px;margin-top:4px}
.modal-save{flex:1;padding:11px;background:var(--accent);color:#fff;font-family:var(--font-b);font-size:14px;font-weight:700;border:none;border-radius:9px;cursor:pointer;transition:background .15s}
.modal-save:hover{background:var(--accent-hi)}
.modal-save:disabled{opacity:.6;cursor:not-allowed}
.modal-cancel-btn{padding:11px 16px;background:transparent;border:1.5px solid var(--border-hi);border-radius:9px;font-family:var(--font-b);font-size:14px;color:var(--text-2);cursor:pointer}
.modal-alert{padding:10px 12px;border-radius:8px;font-size:13px;margin-bottom:14px;display:none}
.modal-err{background:var(--red-pale);color:var(--red);border:1px solid var(--red-border)}
.modal-ok{background:var(--green-pale);color:var(--green);border:1px solid var(--green-border)}
.modal-alert.show{display:block}

@media(max-width:560px){
  .profile{flex-wrap:wrap}.profile-right{width:100%}
  .mem-body{grid-template-columns:1fr}
  .topbar-name{display:none}
  .appt-right{flex-direction:column;align-items:flex-end;gap:4px}
}
</style>
</head>
<body>

<!-- Topbar -->
<div class="topbar">
  <div class="topbar-logo">
    <svg viewBox="0 0 24 24"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
  </div>
  <span class="topbar-name"><?= esc(APP_NAME) ?></span>
  <div class="topbar-right">
    <a href="../book.php" class="topbar-btn">+ Book Now</a>
    <div class="topbar-ava" title="<?= esc($user['email']) ?>"><?= $initials ?></div>
  </div>
</div>

<!-- Unverified email banner -->
<?php if (!$verified): ?>
<div class="banner">
  <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
  <span>Please verify your email address to enable all features.</span>
  <button class="banner-btn" id="resendBtn" onclick="resendVerify()">Resend Email</button>
</div>
<?php endif; ?>

<div class="page">

  <!-- Profile strip -->
  <div class="profile">
    <div class="profile-ava"><?= $initials ?></div>
    <div style="min-width:0">
      <div class="profile-name">
        <?= esc($displayName) ?>
        <?php if ($verified): ?>
          <span class="badge badge-verified">✓ Verified</span>
        <?php else: ?>
          <span class="badge badge-unverified">Unverified</span>
        <?php endif; ?>
      </div>
      <div class="profile-email"><?= esc($user['email']) ?></div>
    </div>
    <div class="profile-right">
      <button class="pbtn" onclick="openEditModal()">Edit Profile</button>
      <button class="pbtn pbtn-danger" onclick="doLogout()">Sign Out</button>
    </div>
  </div>

  <!-- Loyalty badges -->
  <?php
  $badge = '';
  if ($totalBookings >= 50)      $badge = '🏆 Champion';
  elseif ($totalBookings >= 20)  $badge = '🥇 Pro Member';
  elseif ($totalBookings >= 10)  $badge = '🥈 Regular';
  elseif ($totalBookings >= 1)   $badge = '🌱 Member';
  ?>
  <div class="loyalty-strip">
    <div class="loyalty-badge">
      <div class="loyalty-icon" style="background:var(--accent-pale)">⭐</div>
      <div>
        <div class="loyalty-label">Loyalty Points</div>
        <div class="loyalty-val"><?= number_format($loyaltyPoints) ?></div>
      </div>
    </div>
    <div class="loyalty-badge">
      <div class="loyalty-icon" style="background:var(--green-pale)">📅</div>
      <div>
        <div class="loyalty-label">Total Sessions</div>
        <div class="loyalty-val"><?= $totalBookings ?></div>
      </div>
    </div>
    <?php if ($badge): ?>
    <div class="loyalty-badge">
      <div class="loyalty-icon" style="background:var(--blue-pale)">🎖️</div>
      <div>
        <div class="loyalty-label">Status</div>
        <div class="loyalty-val" style="font-size:13px"><?= $badge ?></div>
      </div>
    </div>
    <?php endif; ?>
  </div>

  <!-- Rate recent appointments -->
  <?php if ($ratable): ?>
  <div class="rate-card" id="rate-section">
    <div class="rate-card-title">⭐ Rate your recent sessions</div>
    <?php foreach ($ratable as $ra): ?>
    <div class="rate-item" id="rate-item-<?= $ra['id'] ?>">
      <div class="rate-item-info">
        <div class="rate-item-svc"><?= esc($ra['service_name']) ?></div>
        <div class="rate-item-meta"><?= fmt_dt($ra['start_datetime']) ?><?= $ra['provider_name'] ? ' · ' . esc($ra['provider_name']) : '' ?></div>
      </div>
      <div style="display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex-shrink:0">
        <div class="star-row" data-ref="<?= esc($ra['ref']) ?>" data-apptid="<?= $ra['id'] ?>" onmouseleave="hoverStar(this,0)">
          <?php for ($s=1;$s<=5;$s++): ?>
          <span class="star" data-val="<?= $s ?>"
            onmouseover="hoverStar(this.parentNode,<?= $s ?>)"
            onclick="selectStar(this.parentNode,<?= $s ?>)">★</span>
          <?php endfor; ?>
        </div>
        <button class="rate-submit" id="rate-btn-<?= $ra['id'] ?>"
          onclick="submitRating(<?= $ra['id'] ?>, '<?= esc($ra['ref']) ?>')"
          disabled>Submit</button>
      </div>
    </div>
    <?php endforeach; ?>
  </div>
  <?php endif; ?>

  <!-- Membership -->
  <div class="sec"><span class="sec-title">Membership</span><span class="sec-line"></span></div>
  <?php if ($membership): ?>
  <div class="mem">
    <div class="mem-hdr" style="background:<?= esc($membership['plan_color'] ?: '#e09500') ?>">
      <div class="mem-dot"></div>
      <span class="mem-plan"><?= esc($membership['plan_name']) ?></span>
      <span class="mem-status"><?= strtoupper(esc($membership['status'])) ?></span>
    </div>
    <div class="mem-body">
      <div class="mem-stat">
        <div class="mem-stat-lbl">Expires</div>
        <div class="mem-stat-val"><?= $membership['expires_at'] ? date('M j, Y', strtotime($membership['expires_at'])) : 'Never' ?></div>
      </div>
      <div class="mem-stat">
        <div class="mem-stat-lbl">Remaining</div>
        <div class="mem-stat-val"><?= days_left($membership['expires_at']) ?></div>
      </div>
      <?php if ($membership['session_limit'] !== null): ?>
      <div class="mem-stat">
        <div class="mem-stat-lbl">Sessions left</div>
        <div class="mem-stat-val">
          <?= (int)($membership['sessions_remaining'] ?? $membership['session_limit']) ?>
          <span style="font-size:12px;color:var(--text-3);font-weight:400">/ <?= (int)$membership['session_limit'] ?></span>
        </div>
      </div>
      <div class="mem-stat">
        <div class="mem-stat-lbl">QR Pass</div>
        <div class="mem-stat-val" style="font-size:12px;font-weight:600;color:var(--text-2)">
          <?= $qrToken ? 'Ready' : 'Not configured' ?>
        </div>
      </div>
      <?php endif; ?>
      <?php if ($membership['plan_desc']): ?>
      <div class="mem-stat mem-stat-full">
        <div class="mem-stat-lbl">Plan details</div>
        <div class="mem-stat-val" style="font-size:13px;font-weight:400;color:var(--text-2)"><?= esc($membership['plan_desc']) ?></div>
      </div>
      <?php endif; ?>
      <?php if ($membership['session_limit'] !== null && $qrToken): ?>
      <div class="mem-stat mem-stat-full">
        <div class="mem-stat-lbl">Show this at check-in</div>
        <div class="mem-stat-val" style="display:flex;align-items:center;gap:14px;flex-wrap:wrap">
          <div id="qrBox" style="width:150px;height:150px;background:#fff;border-radius:12px;border:1px solid var(--border);display:flex;align-items:center;justify-content:center;color:var(--text-3);font-size:12px">
            Loading…
          </div>
          <div style="flex:1;min-width:180px">
            <div style="font-size:12px;color:var(--text-2);margin-bottom:6px">
              Present this QR at reception for attendance logging.
            </div>
            <button class="btn-accent" type="button" onclick="copyQr()">Copy token</button>
            <div style="margin-top:8px;font-family:var(--font-m);font-size:10px;color:var(--text-3);word-break:break-all">
              <?= esc(substr($qrToken, 0, 18)) ?>…<?= esc(substr($qrToken, -10)) ?>
            </div>
          </div>
        </div>
      </div>
      <?php endif; ?>
    </div>
  </div>
  <?php else: ?>
  <div class="mem">
    <div class="mem-none">
      <div class="mem-none-title">No active membership</div>
      <div class="mem-none-sub">Choose a plan to unlock bookings and member services.</div>
      <a href="../plans.php" class="btn-accent">View Plans</a>
    </div>
  </div>
  <?php endif; ?>

  <!-- Payment + membership history -->
  <?php if ($membershipHistory): ?>
  <div class="sec"><span class="sec-title">Payments &amp; Membership History</span><span class="sec-line"></span></div>
  <div class="appt-list">
    <?php foreach ($membershipHistory as $h): ?>
    <div class="appt">
      <div class="appt-dot" style="background:<?= $h['activated_by'] === 'stripe' ? '#16a34a' : '#4f46e5' ?>"></div>
      <div class="appt-info">
        <div class="appt-svc">
          <?= esc($h['plan_name']) ?>
          <span class="badge <?= $h['status'] === 'active' ? 'badge-green' : 'badge-red' ?>" style="margin-left:8px">
            <?= strtoupper(esc($h['status'])) ?>
          </span>
        </div>
        <div class="appt-meta">
          <?= $h['starts_at'] ? date('M j, Y', strtotime($h['starts_at'])) : '—' ?>
          → <?= $h['expires_at'] ? date('M j, Y', strtotime($h['expires_at'])) : '—' ?>
          · Source: <?= strtoupper(esc($h['activated_by'] ?: 'manual')) ?>
          <?php if ($h['session_limit'] !== null): ?>
            · Sessions: <?= (int)($h['sessions_remaining'] ?? 0) ?> / <?= (int)($h['sessions_total'] ?? $h['session_limit']) ?>
          <?php endif; ?>
        </div>
        <?php if (!empty($h['stripe_payment_id']) || !empty($h['stripe_session_id'])): ?>
        <div class="appt-meta" style="font-family:var(--font-m);font-size:10px">
          <?= $h['stripe_payment_id'] ? 'Payment: ' . esc($h['stripe_payment_id']) : '' ?>
          <?= $h['stripe_session_id'] ? ' · Session: ' . esc($h['stripe_session_id']) : '' ?>
        </div>
        <?php endif; ?>
      </div>
    </div>
    <?php endforeach; ?>
  </div>
  <?php endif; ?>

  <!-- Upcoming appointments -->
  <div class="sec"><span class="sec-title">Upcoming Appointments</span><span class="sec-line"></span></div>
  <?php if ($upcoming): ?>
  <div class="appt-list">
    <?php foreach ($upcoming as $a): ?>
    <div class="appt" id="appt-<?= $a['id'] ?>">
      <div class="appt-dot" style="background:<?= esc($a['service_color'] ?: '#e09500') ?>"></div>
      <div class="appt-info">
        <div class="appt-svc"><?= esc($a['service_name']) ?></div>
        <div class="appt-meta">
          <?= fmt_dt($a['start_datetime']) ?>
          <?= $a['provider_name'] ? ' · ' . esc($a['provider_name']) : '' ?>
          · Ref: <?= esc($a['ref']) ?>
        </div>
      </div>
      <div class="appt-right">
        <span class="appt-badge <?= status_class($a['status']) ?>"><?= ucfirst(str_replace('_',' ',$a['status'])) ?></span>
        <button class="reschedule-btn" onclick="openRescheduleModal(<?= $a['id'] ?>, '<?= esc($a['service_name']) ?>', '<?= esc($a['provider_name']) ?>', <?= $a['provider_id'] ?>, <?= $a['service_id'] ?>)">Reschedule</button>
        <button class="cancel-btn" onclick="cancelAppt(<?= $a['id'] ?>, this)">Cancel</button>
      </div>
    </div>
    <?php endforeach; ?>
  </div>
  <?php else: ?>
  <div class="empty">No upcoming appointments · <a href="../book.php">Book one now</a></div>
  <?php endif; ?>

  <!-- Past appointments -->
  <?php if ($past): ?>
  <div class="sec"><span class="sec-title">History</span><span class="sec-line"></span></div>
  <div class="appt-list">
    <?php foreach ($past as $a): ?>
    <div class="appt past-appt">
      <div class="appt-dot" style="background:<?= esc($a['service_color'] ?: '#9ca3af') ?>"></div>
      <div class="appt-info">
        <div class="appt-svc"><?= esc($a['service_name']) ?></div>
        <div class="appt-meta">
          <?= fmt_dt($a['start_datetime']) ?>
          <?= $a['provider_name'] ? ' · ' . esc($a['provider_name']) : '' ?>
        </div>
      </div>
      <div class="appt-right">
        <span class="appt-badge <?= status_class($a['status']) ?>"><?= ucfirst(str_replace('_',' ',$a['status'])) ?></span>
      </div>
    </div>
    <?php endforeach; ?>
  </div>
  <?php endif; ?>

</div><!-- /page -->

<!-- Edit Profile Modal -->
<div class="modal-overlay" id="editModal">
  <div class="modal">
    <div class="modal-hdr">
      <span class="modal-title">Edit Profile</span>
      <button class="modal-close" onclick="closeEditModal()">×</button>
    </div>
    <div class="modal-body">
      <div class="modal-alert modal-err" id="editErr"></div>
      <div class="modal-alert modal-ok"  id="editOk"></div>
      <div class="modal-row">
        <label>Full name</label>
        <input type="text" id="editName" value="<?= esc($user['name'] ?? '') ?>" placeholder="Your name"/>
      </div>
      <div class="modal-row">
        <label>Phone</label>
        <input type="tel" id="editPhone" value="<?= esc($user['phone'] ?? '') ?>" placeholder="+1 555 000 0000"/>
      </div>
      <div class="modal-row">
        <label>Date of birth</label>
        <input type="date" id="editDob" value="<?= esc($user['dob'] ?? '') ?>"/>
      </div>
      <div class="modal-row">
        <label>Gender</label>
        <input type="text" id="editGender" value="<?= esc($user['gender'] ?? '') ?>" placeholder="male / female / other"/>
      </div>
      <div class="modal-row">
        <label>Address line</label>
        <input type="text" id="editAddressLine1" value="<?= esc($user['address_line1'] ?? '') ?>" placeholder="Street and house number"/>
      </div>
      <div class="modal-row">
        <label>City</label>
        <input type="text" id="editCity" value="<?= esc($user['city'] ?? '') ?>" placeholder="City"/>
      </div>
      <div class="modal-row">
        <label>Country</label>
        <input type="text" id="editCountry" value="<?= esc($user['country'] ?? '') ?>" placeholder="Country"/>
      </div>
      <div class="modal-row">
        <label>Emergency contact name</label>
        <input type="text" id="editEmergencyName" value="<?= esc($user['emergency_contact_name'] ?? '') ?>" placeholder="Full name"/>
      </div>
      <div class="modal-row">
        <label>Emergency contact phone</label>
        <input type="tel" id="editEmergencyPhone" value="<?= esc($user['emergency_contact_phone'] ?? '') ?>" placeholder="+1 555 000 0001"/>
      </div>
      <div class="modal-divider">
        <div class="modal-divider-lbl">Change Password <span style="font-weight:400;text-transform:none;letter-spacing:0">(leave blank to keep current)</span></div>
        <div class="modal-row">
          <label>Current password</label>
          <input type="password" id="editCurPw" placeholder="••••••••" autocomplete="current-password"/>
        </div>
        <div class="modal-row" style="margin-bottom:0">
          <label>New password</label>
          <input type="password" id="editNewPw" placeholder="Min 8 characters" autocomplete="new-password"/>
        </div>
      </div>
      <div class="modal-footer">
        <button class="modal-cancel-btn" onclick="closeEditModal()">Cancel</button>
        <button class="modal-save" id="editSaveBtn" onclick="saveProfile()">Save Changes</button>
      </div>
    </div>
  </div>
</div>

<script src="../assets/qrcode.min.js"></script>
<script>
const API = '../api/auth.php';
const QR_TOKEN = <?= json_encode($qrToken) ?>;

function copyQr(){
  if(!QR_TOKEN){ alert('QR not available'); return; }
  navigator.clipboard.writeText(QR_TOKEN).then(()=>alert('Copied'));
}

function renderQr(){
  const box = document.getElementById('qrBox');
  if(!box) return;
  if(!QR_TOKEN){ box.textContent='QR unavailable'; return; }
  if(typeof QRCode === 'undefined'){ box.textContent='QR library missing'; return; }
  box.innerHTML = '';
  new QRCode(box, { text: QR_TOKEN, width: 150, height: 150, correctLevel: QRCode.CorrectLevel.M });
}
renderQr();

// ── Logout ──────────────────────────────────────────────────
async function doLogout() {
  await fetch(API, {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'logout'})});
  window.location.href = '../login.php';
}

// ── Cancel appointment ───────────────────────────────────────
async function cancelAppt(id, btn) {
  if (!confirm('Cancel this appointment?')) return;
  btn.disabled = true; btn.textContent = 'Cancelling…';
  try {
    const r = await fetch(API, {method:'POST',headers:{'Content-Type':'application/json'},
      body: JSON.stringify({action:'cancel-appointment', id})});
    const d = await r.json();
    if (d.ok) {
      const row = document.getElementById('appt-' + id);
      if (row) {
        const badge = row.querySelector('.appt-badge');
        if (badge) { badge.textContent = 'Cancelled'; badge.className = 'appt-badge badge-red'; }
        btn.remove();
        row.style.opacity = '0.5';
      }
    } else {
      alert(d.error || 'Could not cancel appointment.');
      btn.disabled = false; btn.textContent = 'Cancel';
    }
  } catch(err) {
    alert('Network error — please try again.');
    btn.disabled = false; btn.textContent = 'Cancel';
  }
}

// ── Resend verification ──────────────────────────────────────
async function resendVerify() {
  const btn = document.getElementById('resendBtn');
  btn.disabled = true; btn.textContent = 'Sending…';
  try {
    const r = await fetch(API, {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'resend-verify'})});
    const d = await r.json();
    btn.textContent = d.ok ? '✓ Sent' : 'Try again';
    if (!d.ok) btn.disabled = false;
  } catch(err) { btn.textContent = 'Try again'; btn.disabled = false; }
}

// ── Edit profile modal ───────────────────────────────────────
function openEditModal()  { document.getElementById('editModal').classList.add('open'); }
function closeEditModal() {
  document.getElementById('editModal').classList.remove('open');
  document.getElementById('editErr').className = 'modal-alert modal-err';
  document.getElementById('editOk').className  = 'modal-alert modal-ok';
  document.getElementById('editCurPw').value = '';
  document.getElementById('editNewPw').value = '';
}

async function saveProfile() {
  const btn = document.getElementById('editSaveBtn');
  const e   = document.getElementById('editErr');
  const o   = document.getElementById('editOk');
  e.className = 'modal-alert modal-err';
  o.className = 'modal-alert modal-ok';

  const name    = document.getElementById('editName').value.trim();
  const phone   = document.getElementById('editPhone').value.trim();
  const dob     = document.getElementById('editDob').value.trim();
  const gender  = document.getElementById('editGender').value.trim();
  const addressLine1 = document.getElementById('editAddressLine1').value.trim();
  const city    = document.getElementById('editCity').value.trim();
  const country = document.getElementById('editCountry').value.trim();
  const emergencyName = document.getElementById('editEmergencyName').value.trim();
  const emergencyPhone = document.getElementById('editEmergencyPhone').value.trim();
  const curPw   = document.getElementById('editCurPw').value;
  const newPw   = document.getElementById('editNewPw').value;
  const requireComplete = <?= $profileRequired ? 'true' : 'false' ?>;

  if (!name) { e.textContent = 'Name is required.'; e.classList.add('show'); return; }
  if (requireComplete && (!phone || !dob || !gender || !addressLine1 || !city || !country || !emergencyName || !emergencyPhone)) {
    e.textContent = 'Please complete all required member profile fields.';
    e.classList.add('show');
    return;
  }

  const payload = {
    action: 'update-profile',
    name, phone, dob, gender,
    address_line1: addressLine1, city, country,
    emergency_contact_name: emergencyName,
    emergency_contact_phone: emergencyPhone,
    require_complete: requireComplete,
    current_password: curPw,
    new_password: newPw
  };
  btn.disabled = true; btn.textContent = 'Saving…';

  try {
    const r = await fetch(API, {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
    const d = await r.json();
    if (d.ok) {
      o.textContent = d.message; o.classList.add('show');
      btn.textContent = '✓ Saved';
      setTimeout(closeEditModal, 1400);
    } else {
      e.textContent = d.error || 'Update failed.'; e.classList.add('show');
      btn.disabled = false; btn.textContent = 'Save Changes';
    }
  } catch(err) {
    e.textContent = 'Network error — please try again.'; e.classList.add('show');
    btn.disabled = false; btn.textContent = 'Save Changes';
  }
}

// Close modal on overlay click
document.getElementById('editModal').addEventListener('click', function(e) {
  if (e.target === this) closeEditModal();
});

// ── Star ratings ─────────────────────────────────────────────
const starSelections = {}; // apptId → selected rating

function hoverStar(row, val) {
  const apptId = row.dataset.apptid;
  const selected = starSelections[apptId] || 0;
  row.querySelectorAll('.star').forEach(s => {
    const sv = parseInt(s.dataset.val);
    s.classList.toggle('lit', sv <= (val || selected));
  });
}

function selectStar(row, val) {
  const apptId = row.dataset.apptid;
  starSelections[apptId] = val;
  hoverStar(row, val);
  const btn = document.getElementById('rate-btn-' + apptId);
  if (btn) btn.disabled = false;
}

async function submitRating(apptId, ref) {
  const btn = document.getElementById('rate-btn-' + apptId);
  const rating = starSelections[apptId];
  if (!rating) return;
  btn.disabled = true; btn.textContent = 'Sending…';

  const r = await fetch('../api/booking.php?_route=rate', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({ref, rating, email: <?= json_encode($user['email']) ?>}),
  }).then(r=>r.json()).catch(()=>({ok:false}));

  const item = document.getElementById('rate-item-' + apptId);
  if (item) {
    item.innerHTML = '<div style="color:var(--green);font-size:13px;font-weight:600;padding:8px 0">✓ Thanks for your feedback!</div>';
  }
}

</script>
<!-- ── Reschedule Modal ── -->
<div class="modal-overlay" id="rsModal">
  <div class="modal">
    <div class="modal-header">
      <div>
        <div class="modal-title">Reschedule Appointment</div>
        <div id="rs-subtitle" style="font-size:12px;color:var(--text-3);margin-top:2px"></div>
      </div>
      <button class="modal-close" onclick="closeRsModal()">×</button>
    </div>
    <div style="padding:0 20px 20px">
      <label style="font-size:12px;font-weight:600;color:var(--text-2);display:block;margin-bottom:6px">Pick a new date</label>
      <input type="date" id="rs-date" style="width:100%;padding:10px 12px;border-radius:9px;border:1.5px solid var(--border-hi);background:var(--surface-hi);color:var(--text);font-size:14px;box-sizing:border-box"/>
      <button onclick="loadRsSlots()" style="margin-top:8px;width:100%;padding:10px;border-radius:9px;border:none;background:var(--accent);color:#fff;font-weight:700;font-size:13px;cursor:pointer">Check Availability</button>

      <div id="rs-slots-wrap" style="margin-top:12px;display:none">
        <label style="font-size:12px;font-weight:600;color:var(--text-2);display:block;margin-bottom:6px">Available times</label>
        <div class="rs-slot-grid" id="rs-slots"></div>
      </div>

      <div id="rs-err" style="display:none;margin-top:10px;font-size:13px;color:var(--red)"></div>

      <div style="display:flex;gap:8px;margin-top:16px">
        <button class="modal-cancel-btn" style="flex:1" onclick="closeRsModal()">Cancel</button>
        <button id="rs-confirm-btn" style="flex:1;padding:11px 16px;background:var(--accent);border:none;border-radius:9px;color:#fff;font-family:var(--font-b);font-size:14px;font-weight:700;cursor:pointer;display:none" onclick="confirmReschedule()">Confirm Reschedule</button>
      </div>
    </div>
  </div>
</div>

<script>
// ── Reschedule state ──────────────────────────────────────────
const rsState = { apptId:null, providerId:null, serviceId:null, selectedSlot:null };
const BK_API  = '../api/booking.php';

function openRescheduleModal(apptId, serviceName, providerName, providerId, serviceId) {
  rsState.apptId     = apptId;
  rsState.providerId = providerId;
  rsState.serviceId  = serviceId;
  rsState.selectedSlot = null;

  document.getElementById('rs-subtitle').textContent = serviceName + ' · ' + providerName;
  // Default date = tomorrow
  const tmr = new Date(); tmr.setDate(tmr.getDate() + 1);
  document.getElementById('rs-date').value = tmr.toISOString().slice(0,10);
  document.getElementById('rs-date').min   = new Date().toISOString().slice(0,10);
  document.getElementById('rs-slots-wrap').style.display = 'none';
  document.getElementById('rs-err').style.display = 'none';
  document.getElementById('rs-confirm-btn').style.display = 'none';
  document.getElementById('rsModal').classList.add('open');
}

function closeRsModal() {
  document.getElementById('rsModal').classList.remove('open');
}

async function loadRsSlots() {
  const date = document.getElementById('rs-date').value;
  if (!date) { showRsErr('Please pick a date.'); return; }
  document.getElementById('rs-err').style.display = 'none';

  const slotsWrap = document.getElementById('rs-slots-wrap');
  const slotsEl   = document.getElementById('rs-slots');
  slotsEl.innerHTML = '<div style="grid-column:1/-1;text-align:center;padding:16px;color:var(--text-3);font-size:13px">Loading…</div>';
  slotsWrap.style.display = 'block';
  document.getElementById('rs-confirm-btn').style.display = 'none';
  rsState.selectedSlot = null;

  try {
    const r = await fetch(`${BK_API}?_route=slots&service_id=${rsState.serviceId}&provider_id=${rsState.providerId}&date=${date}`);
    const d = await r.json();
    if (!d.ok || !d.slots?.length) {
      slotsEl.innerHTML = '<div style="grid-column:1/-1;text-align:center;padding:16px;color:var(--text-3);font-size:13px">No available slots on this date.</div>';
      return;
    }
    const available = d.slots.filter(s => s.available);
    if (!available.length) {
      slotsEl.innerHTML = '<div style="grid-column:1/-1;text-align:center;padding:16px;color:var(--text-3);font-size:13px">All slots are fully booked on this date.</div>';
      return;
    }
    slotsEl.innerHTML = available.map(s => `
      <div class="rs-slot" data-dt="${s.datetime}" onclick="selectRsSlot(this, '${s.datetime}')">
        ${s.time}
      </div>`).join('');
  } catch(e) {
    showRsErr('Could not load slots. Please try again.');
  }
}

function selectRsSlot(el, datetime) {
  document.querySelectorAll('.rs-slot').forEach(s => s.classList.remove('selected'));
  el.classList.add('selected');
  rsState.selectedSlot = datetime;
  document.getElementById('rs-confirm-btn').style.display = 'block';
}

async function confirmReschedule() {
  if (!rsState.selectedSlot) { showRsErr('Please select a time slot.'); return; }
  const btn = document.getElementById('rs-confirm-btn');
  btn.disabled = true;
  btn.textContent = 'Rescheduling…';

  try {
    const r = await fetch(API, {
      method: 'POST',
      headers: {'Content-Type':'application/json'},
      body: JSON.stringify({ action:'reschedule-appointment', id: rsState.apptId, datetime: rsState.selectedSlot })
    });
    const d = await r.json();
    if (d.ok) {
      closeRsModal();
      toast('Appointment rescheduled! Reloading…', 'ok');
      setTimeout(() => location.reload(), 1600);
    } else {
      showRsErr(d.error || 'Could not reschedule. Please try again.');
      btn.disabled = false;
      btn.textContent = 'Confirm Reschedule';
    }
  } catch(e) {
    showRsErr('Network error. Please try again.');
    btn.disabled = false;
    btn.textContent = 'Confirm Reschedule';
  }
}

function showRsErr(msg) {
  const el = document.getElementById('rs-err');
  el.textContent = msg;
  el.style.display = 'block';
}

function toast(msg, type) {
  const t = document.createElement('div');
  t.textContent = msg;
  t.style.cssText = `position:fixed;bottom:24px;left:50%;transform:translateX(-50%);padding:10px 20px;border-radius:10px;font-size:13px;font-weight:600;z-index:9999;background:${type==='ok'?'#22c55e':'#ef4444'};color:#fff;box-shadow:0 4px 16px rgba(0,0,0,.18)`;
  document.body.appendChild(t);
  setTimeout(() => t.remove(), 3000);
}

document.getElementById('rsModal').addEventListener('click', function(e) {
  if (e.target === this) closeRsModal();
});

<?php if ($profileRequired && !$profileComplete): ?>
setTimeout(function(){
  openEditModal();
  const err = document.getElementById('editErr');
  err.textContent = 'Please complete your profile before using membership features.';
  err.classList.add('show');
}, 300);
<?php endif; ?>
</script>

</body>
</html>
