{% extends "dashboard_base.html" %}

{% block title %}{% if editing %}Edit{% else %}New{% endif %} event type — calrs{% endblock %}

{% block dashboard_content %}

{% if error %}
  <div class="error" style="margin-bottom: 1rem;">{{ error }}</div>
{% endif %}

<form method="POST">

{% if preset is defined and preset %}
<div style="padding: 0.75rem 1rem; border-radius: var(--radius); background: var(--accent-subtle); border: 1px solid var(--accent-border); font-size: 0.875rem; margin-bottom: 1rem; display: flex; align-items: center; gap: 0.5rem;">
  {% if preset == "public" %}
    <span>&#127760;</span> Creating a <strong>public</strong> event type &mdash; anyone with the link can book.
  {% elif preset == "private" %}
    <span>&#128274;</span> Creating a <strong>private</strong> event type &mdash; only people you invite can book.
  {% elif preset == "internal" %}
    <span>&#127970;</span> Creating an <strong>internal</strong> event type &mdash; any colleague can share the booking link.
  {% elif preset == "team" %}
    <span>&#128101;</span> Creating a <strong>team</strong> event type &mdash; bookings are distributed across team members.
  {% endif %}
</div>
{% endif %}

<!-- Card 1: Basics -->
<div class="card">
  <h1 style="margin-bottom: 1rem;">{% if editing %}Edit event type{% else %}New event type{% endif %}</h1>

  {% if not editing and teams is defined and teams %}
  <div class="form-group">
    <label for="team_id">Team <span class="hint">(optional — leave empty for personal event type)</span></label>
    <select id="team_id" name="team_id" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text); width: 100%;">
      <option value="">Personal</option>
      {% for t in teams %}
      <option value="{{ t.id }}" {% if form_team_id is defined and form_team_id == t.id %}selected{% endif %}>{{ t.name }}</option>
      {% endfor %}
    </select>
  </div>
  {% endif %}

  <div class="form-group" id="scheduling-mode-group" style="{% if not (is_group is defined and is_group) %}display:none;{% endif %}">
    <label for="scheduling_mode">Scheduling mode</label>
    <select id="scheduling_mode" name="scheduling_mode" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text); width: 100%;">
      <option value="round_robin" {% if form_scheduling_mode is defined and form_scheduling_mode == "round_robin" %}selected{% endif %}>Round Robin — assign to one available member</option>
      <option value="collective" {% if form_scheduling_mode is defined and form_scheduling_mode == "collective" %}selected{% endif %}>Collective — all members must be available</option>
    </select>
    <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">Round Robin assigns to one available member (least busy first). Collective requires all members to be free at the same time.</span>
  </div>

  <div class="form-group">
    <label for="title">Title</label>
    <input type="text" id="title" name="title" required value="{{ form_title }}" placeholder="30min intro call">
  </div>

  <div class="form-group">
    <label for="slug">Slug <span class="hint">(URL-friendly identifier)</span></label>
    <input type="text" id="slug" name="slug" value="{{ form_slug }}" placeholder="auto-generated from title" pattern="[a-z0-9\-]*" title="Lowercase letters, numbers, and dashes only">
  </div>

  <div class="form-group">
    <label for="description">Description <span class="hint">(optional)</span></label>
    <div style="border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden;">
      <div class="md-toolbar" data-target="description" style="display: flex; gap: 0.25rem; padding: 0.375rem 0.5rem; background: var(--surface-hover); border-bottom: 1px solid var(--border);">
        <button type="button" data-action="bold" title="Bold" style="padding: 0.25rem 0.5rem; background: none; border: 1px solid transparent; border-radius: 3px; cursor: pointer; font-weight: 700; font-size: 0.85rem; color: var(--text); font-family: inherit; line-height: 1;">B</button>
        <button type="button" data-action="italic" title="Italic" style="padding: 0.25rem 0.5rem; background: none; border: 1px solid transparent; border-radius: 3px; cursor: pointer; font-style: italic; font-size: 0.85rem; color: var(--text); font-family: inherit; line-height: 1;">I</button>
        <button type="button" data-action="link" title="Insert link" style="padding: 0.25rem 0.5rem; background: none; border: 1px solid transparent; border-radius: 3px; cursor: pointer; font-size: 0.85rem; color: var(--text); font-family: inherit; line-height: 1;">&#128279;</button>
        <div style="flex: 1;"></div>
        <button type="button" class="md-preview-toggle" title="Toggle preview" style="padding: 0.25rem 0.5rem; background: none; border: 1px solid transparent; border-radius: 3px; cursor: pointer; font-size: 0.75rem; color: var(--text-muted); font-family: inherit; line-height: 1;">Preview</button>
      </div>
      <textarea id="description" name="description" placeholder="A quick introductory call to discuss..." style="border: none; border-radius: 0; width: 100%; resize: vertical; padding: 0.5rem 0.75rem; font-family: inherit; font-size: 0.9rem; background: var(--surface); color: var(--text); box-sizing: border-box;">{{ form_description }}</textarea>
      <div id="description-preview" style="display: none; padding: 0.5rem 0.75rem; min-height: 4rem; font-size: 0.9rem; color: var(--text); background: var(--surface);"></div>
    </div>
    <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">Shown on the booking page. Supports **bold**, *italic*, and [links](url).</span>
  </div>

  <div style="display: grid; grid-template-columns: auto 1fr; gap: 0.75rem; align-items: start;" class="form-grid-2">
    <div class="form-group" style="min-width: 140px;">
      <label for="location_type">Location</label>
      <select id="location_type" name="location_type" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text); width: 100%;">
        <option value="link" {% if form_location_type == "link" %}selected{% endif %}>Video call</option>
        <option value="phone" {% if form_location_type == "phone" %}selected{% endif %}>Phone</option>
        <option value="in_person" {% if form_location_type == "in_person" %}selected{% endif %}>In person</option>
        <option value="custom" {% if form_location_type == "custom" %}selected{% endif %}>Custom</option>
      </select>
    </div>
    <div class="form-group">
      <label for="location_value">Details</label>
      <input type="text" id="location_value" name="location_value" required value="{{ form_location_value }}" placeholder="https://meet.example.com/my-room">
    </div>
  </div>

  <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;" class="form-grid-2">
    <div class="form-group">
      <label for="duration_min">Duration (minutes)</label>
      <input type="number" id="duration_min" name="duration_min" required value="{{ form_duration }}" min="5" max="480" step="5">
    </div>
    <div class="form-group">
      <label for="slot_interval_min">Slot interval (minutes)</label>
      <input type="number" id="slot_interval_min" name="slot_interval_min" value="{% if form_slot_interval and form_slot_interval != 0 %}{{ form_slot_interval }}{% endif %}" min="5" max="480" step="5" placeholder="Same as duration">
      <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">How often slots start. Leave blank to match duration.</span>
    </div>
  </div>
</div>

<style>
  /* Collapsible sections */
  .collapsible-section { overflow: visible; }
  .collapsible-section > .collapsible-header {
    display: flex;
    align-items: center;
    cursor: pointer;
    list-style: none;
    padding: 0;
    gap: 0.75rem;
    user-select: none;
  }
  .collapsible-section > .collapsible-header::-webkit-details-marker { display: none; }
  .collapsible-section > .collapsible-header h2 { margin: 0; flex-shrink: 0; }
  .collapsible-section > .collapsible-header .collapsible-hint {
    flex: 1;
    text-align: right;
    font-size: 0.825rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }
  .collapsible-section > .collapsible-header .collapsible-chevron {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.2s ease;
  }
  .collapsible-section > .collapsible-header .collapsible-chevron::after {
    content: '';
    display: block;
    width: 7px;
    height: 7px;
    border-right: 2px solid var(--text-muted);
    border-bottom: 2px solid var(--text-muted);
    transform: rotate(-45deg);
    transition: transform 0.2s ease;
  }
  .collapsible-section[open] > .collapsible-header .collapsible-chevron::after {
    transform: rotate(45deg);
  }
  .collapsible-section > .collapsible-body {
    padding-top: 0.75rem;
    margin-top: 0.75rem;
    border-top: 1px solid var(--border);
  }
  /* Animation styles — only applied via JS class during transitions */
  .collapsible-section.animating > .collapsible-body {
    overflow: hidden;
    transition: max-height 0.25s ease, opacity 0.2s ease;
  }
  .collapsible-section > .collapsible-header .collapsible-hint {
    transition: opacity 0.2s ease;
  }
  .collapsible-section[open] > .collapsible-header .collapsible-hint {
    opacity: 0.4;
  }

  .priority-btn {
    padding: 0.3rem 0.75rem;
    font-size: 0.8rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: none;
    cursor: pointer;
    color: var(--text-secondary);
    transition: all 0.15s ease;
  }
  .priority-btn:hover { background: var(--surface-hover); }
  .priority-btn.active-high { background: var(--accent); color: #fff; border-color: var(--accent); }
  .priority-btn.active-medium { background: var(--text-muted); color: #fff; border-color: var(--text-muted); }
  .priority-btn.active-low { background: var(--surface-hover); color: var(--text-secondary); border-color: var(--border); font-style: italic; }
</style>

<!-- Card 2: Members (round-robin priority OR collective inclusion) -->
{% if priority_members is defined and priority_members %}
{% set is_collective_card = is_collective_team is defined and is_collective_team %}
<div class="card" id="priority-card" style="margin-top: 1rem;">
  {% if is_collective_card %}
  <h2 style="margin-bottom: 0.25rem;">Required members</h2>
  <p style="color: var(--text-muted); font-size: 0.85rem; margin-bottom: 1rem;">All checked members must be free for a slot to be offered. Uncheck members you want to exclude (their availability will be ignored).</p>
  {% else %}
  <h2 style="margin-bottom: 0.25rem;">Member Priority</h2>
  <p style="color: var(--text-muted); font-size: 0.85rem; margin-bottom: 1rem;">Higher priority members are assigned bookings first when available. Same priority = balanced by recent booking count.</p>
  {% endif %}

  {% for m in priority_members %}
  <div data-row-uid="{{ m.user_id }}" style="display: flex; align-items: center; padding: 0.5rem 0; gap: 0.75rem; {% if not loop.last %}border-bottom: 1px solid var(--border);{% endif %}">
    <input type="checkbox" data-include="{{ m.user_id }}" {% if m.weight > 0 %}checked{% endif %}
      style="accent-color: var(--accent); width: 1rem; height: 1rem; flex-shrink: 0; cursor: pointer;"
      onchange="toggleMember('{{ m.user_id }}', this.checked)">
    <div style="display: flex; align-items: center; gap: 0.5rem; flex: 1; min-width: 0; transition: opacity 0.15s;" data-member-info="{{ m.user_id }}">
      <div class="avatar-circle" style="width: 28px; height: 28px; font-size: 0.65rem;">
        {% if m.has_avatar %}
          <img src="/avatar/{{ m.user_id }}" alt="">
        {% else %}
          {{ m.initials }}
        {% endif %}
      </div>
      <div style="min-width: 0;">
        <div style="font-weight: 500; font-size: 0.875rem;">{{ m.name }}</div>
        {% if m.timezone %}
        <div style="font-size: 0.75rem; color: var(--text-muted);" title="Member's timezone. Their personal working hours are interpreted in this TZ.">{{ m.timezone }}</div>
        {% endif %}
      </div>
    </div>
    {% if not is_collective_card %}
    <div data-priority-btns="{{ m.user_id }}" style="display: flex; gap: 0.25rem; flex-shrink: 0;">
      <button type="button" data-priority="high" class="priority-btn {% if m.weight >= 3 %}active-high{% endif %}" onclick="setPriority(this, '{{ m.user_id }}', 'high')">High</button>
      <button type="button" data-priority="medium" class="priority-btn {% if m.weight == 2 %}active-medium{% endif %}" onclick="setPriority(this, '{{ m.user_id }}', 'medium')">Medium</button>
      <button type="button" data-priority="low" class="priority-btn {% if m.weight >= 1 and m.weight <= 1 %}active-low{% endif %}" onclick="setPriority(this, '{{ m.user_id }}', 'low')">Low</button>
    </div>
    {% endif %}
  </div>
  {% endfor %}
</div>
{% endif %}

{% if not editing %}
<!-- Dynamic priority card (creation flow — populated by JS when team + round-robin selected) -->
<div id="dynamic-priority-card" class="card" style="margin-top: 1rem; display: none;">
  <h2 style="margin-bottom: 0.25rem;">Member Priority</h2>
  <p style="color: var(--text-muted); font-size: 0.85rem; margin-bottom: 1rem;">Higher priority members are assigned bookings first when available. Same priority = balanced by recent booking count.</p>
  <div id="dynamic-priority-list"></div>
</div>
{% endif %}

<!-- Collapsible: Availability -->
<details class="card collapsible-section" style="margin-top: 1rem;" id="scheduling-section"{% if editing %} open{% endif %}>
  <summary class="collapsible-header"><h2>Availability</h2><span class="collapsible-hint" id="scheduling-hint"></span><span class="collapsible-chevron"></span></summary>
  <div class="collapsible-body">
    <div class="form-group" style="margin-bottom: 1rem;">
      <label for="event_type_timezone">Timezone</label>
      <select id="event_type_timezone" name="timezone" style="width: 100%; padding: 0.5rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); font-size: 0.9rem;">
        {% for tz in tz_options %}
          <option value="{{ tz.value }}" {% if tz.value == form_timezone %}selected{% endif %}>{{ tz.label }}</option>
        {% endfor %}
      </select>
      <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">The hours below are interpreted in this timezone. For team event types, pick the team's working timezone (not necessarily the creator's).</span>
    </div>
    <div id="schedule-container" style="display: flex; flex-direction: column; gap: 0.25rem;"></div>
    <div style="display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 0.5rem;">
      <button type="button" id="reset-to-default-btn" style="padding: 0.25rem 0.625rem; border: 1px solid var(--border); border-radius: var(--radius); background: transparent; color: var(--text-muted); cursor: pointer; font-size: 0.75rem; transition: all 0.15s ease;" title="Replace these hours with your profile-default availability">Reset to my default</button>
      <button type="button" id="copy-to-all-btn" style="padding: 0.25rem 0.625rem; border: 1px solid var(--border); border-radius: var(--radius); background: transparent; color: var(--text-muted); cursor: pointer; font-size: 0.75rem; transition: all 0.15s ease;" title="Copy the first enabled day's windows to all other enabled days">Copy to all days</button>
    </div>
    <input type="hidden" name="avail_schedule" id="avail_schedule" value="{{ form_avail_schedule | default(value='') }}">
    <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.5rem;">Pre-filled from your <a href="/dashboard/settings#availability" style="color: var(--accent);">default availability</a>. You can override it here for this event type.</span>
  </div>
</details>

<!-- Collapsible: Buffers & notice -->
<details class="card collapsible-section" style="margin-top: 1rem;"{% if editing and ((form_buffer_before is defined and form_buffer_before and form_buffer_before != "0") or (form_buffer_after is defined and form_buffer_after and form_buffer_after != "0") or (form_min_notice is defined and form_min_notice and form_min_notice != "0") or (form_cancel_notice_value is defined and form_cancel_notice_value and form_cancel_notice_value > 0) or (form_reschedule_notice_value is defined and form_reschedule_notice_value and form_reschedule_notice_value > 0)) %} open{% endif %}>
  <summary class="collapsible-header">
    <h2>Buffers &amp; notice</h2>
    <span class="collapsible-hint" id="buffers-hint"></span>
    <span class="collapsible-chevron"></span>
  </summary>
  <div class="collapsible-body">
    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;" class="form-grid-2">
      <div class="form-group">
        <label for="buffer_before">Buffer before (min)</label>
        <input type="number" id="buffer_before" name="buffer_before" value="{{ form_buffer_before }}" min="0" max="120" step="5">
      </div>
      <div class="form-group">
        <label for="buffer_after">Buffer after (min)</label>
        <input type="number" id="buffer_after" name="buffer_after" value="{{ form_buffer_after }}" min="0" max="120" step="5">
      </div>
    </div>
    <div class="form-group">
      <label for="min_notice_value">Minimum notice</label>
      <div style="display: flex; gap: 0.5rem; align-items: center;">
        <input type="number" id="min_notice_value" value="" min="0" step="1" style="flex: 1; max-width: 120px;">
        <select id="min_notice_unit" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text);">
          <option value="1">minutes</option>
          <option value="60">hours</option>
          <option value="1440">days</option>
        </select>
      </div>
      <input type="hidden" id="min_notice_min" name="min_notice_min" value="{{ form_min_notice }}">
      <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">How far in advance someone must book.</span>
    </div>

    <div class="form-group">
      <label for="cancel_notice_value">{{ t("event-type-form-cancel-notice-label") }}</label>
      <div style="display: flex; gap: 0.5rem; align-items: center;">
        <input type="number" min="0" step="1" id="cancel_notice_value" name="cancel_notice_value"
               value="{% if form_cancel_notice_value is defined and form_cancel_notice_value > 0 %}{{ form_cancel_notice_value }}{% endif %}"
               placeholder="0" style="flex: 1; max-width: 120px;">
        <select name="cancel_notice_unit" id="cancel_notice_unit" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text);">
          <option value="minutes" {% if form_cancel_notice_unit is defined and form_cancel_notice_unit == "minutes" %}selected{% endif %}>{{ t("event-type-form-notice-unit-minutes") }}</option>
          <option value="hours" {% if form_cancel_notice_unit is defined and form_cancel_notice_unit == "hours" %}selected{% endif %}>{{ t("event-type-form-notice-unit-hours") }}</option>
          <option value="days" {% if form_cancel_notice_unit is defined and form_cancel_notice_unit == "days" %}selected{% endif %}>{{ t("event-type-form-notice-unit-days") }}</option>
        </select>
      </div>
      <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">{{ t("event-type-form-notice-help") }}</span>
    </div>

    <div class="form-group">
      <label for="reschedule_notice_value">{{ t("event-type-form-reschedule-notice-label") }}</label>
      <div style="display: flex; gap: 0.5rem; align-items: center;">
        <input type="number" min="0" step="1" id="reschedule_notice_value" name="reschedule_notice_value"
               value="{% if form_reschedule_notice_value is defined and form_reschedule_notice_value > 0 %}{{ form_reschedule_notice_value }}{% endif %}"
               placeholder="0" style="flex: 1; max-width: 120px;">
        <select name="reschedule_notice_unit" id="reschedule_notice_unit" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text);">
          <option value="minutes" {% if form_reschedule_notice_unit is defined and form_reschedule_notice_unit == "minutes" %}selected{% endif %}>{{ t("event-type-form-notice-unit-minutes") }}</option>
          <option value="hours" {% if form_reschedule_notice_unit is defined and form_reschedule_notice_unit == "hours" %}selected{% endif %}>{{ t("event-type-form-notice-unit-hours") }}</option>
          <option value="days" {% if form_reschedule_notice_unit is defined and form_reschedule_notice_unit == "days" %}selected{% endif %}>{{ t("event-type-form-notice-unit-days") }}</option>
        </select>
      </div>
      <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">{{ t("event-type-form-notice-help") }}</span>
    </div>
  </div>
</details>

<!-- Collapsible: Booking limits -->
<details class="card collapsible-section" style="margin-top: 1rem;"{% if editing and (form_first_slot_only or (form_frequency_limits is defined and form_frequency_limits)) %} open{% endif %}>
  <summary class="collapsible-header">
    <h2>Booking limits</h2>
    <span class="collapsible-hint" id="limits-hint"></span>
    <span class="collapsible-chevron"></span>
  </summary>
  <div class="collapsible-body">
    <!-- One slot per day toggle -->
    <div style="display: flex; justify-content: space-between; align-items: center; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius);">
      <div>
        <strong style="font-size: 0.925rem;">One slot per day</strong>
        <div style="color: var(--text-muted); font-size: 0.825rem;">Only show the earliest available time each day.</div>
      </div>
      <label style="position: relative; display: inline-block; width: 44px; height: 24px; flex-shrink: 0;">
        <input type="checkbox" name="first_slot_only" {% if form_first_slot_only %}checked{% endif %} autocomplete="off" style="opacity: 0; width: 0; height: 0;" id="first-slot-toggle">
        <span style="position: absolute; cursor: pointer; inset: 0; background: #71717a; border-radius: 24px; transition: 0.2s;" id="first-slot-track">
          <span style="position: absolute; height: 18px; width: 18px; left: 3px; bottom: 3px; background: white; border-radius: 50%; transition: 0.2s;" id="first-slot-knob"></span>
        </span>
      </label>
    </div>

    <!-- Frequency limits toggle -->
    <div style="display: flex; justify-content: space-between; align-items: center; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); margin-top: 0.5rem;">
      <div>
        <strong style="font-size: 0.925rem;">Limit booking frequency</strong>
        <div style="color: var(--text-muted); font-size: 0.825rem;">Limit how many times this event can be booked per period.</div>
      </div>
      <label style="position: relative; display: inline-block; width: 44px; height: 24px; flex-shrink: 0;">
        <input type="checkbox" id="freq-limit-toggle" autocomplete="off" style="opacity: 0; width: 0; height: 0;">
        <span style="position: absolute; cursor: pointer; inset: 0; background: #71717a; border-radius: 24px; transition: 0.2s;" id="freq-toggle-track">
          <span style="position: absolute; height: 18px; width: 18px; left: 3px; bottom: 3px; background: white; border-radius: 50%; transition: 0.2s;" id="freq-toggle-knob"></span>
        </span>
      </label>
    </div>
    <div id="freq-limits-container" style="display: none; margin-top: 0.5rem; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius);">
      <div id="freq-limits-list" style="display: flex; flex-direction: column; gap: 0.5rem;"></div>
      <button type="button" id="add-freq-limit" style="margin-top: 0.75rem; padding: 0.375rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); background: transparent; color: var(--text-muted); cursor: pointer; font-size: 0.85rem; transition: all 0.15s ease;">+ Add limit</button>
    </div>
    <input type="hidden" name="frequency_limits" id="frequency_limits" value="{{ form_frequency_limits | default(value='') }}">
  </div>
</details>

<!-- Collapsible: Booking options -->
<details class="card collapsible-section" style="margin-top: 1rem;"{% if editing and (form_requires_confirmation or (form_max_additional_guests is defined and form_max_additional_guests and form_max_additional_guests != 0) or (form_default_calendar_view is defined and form_default_calendar_view and form_default_calendar_view != "month")) %} open{% endif %}>
  <summary class="collapsible-header">
    <h2>Booking options</h2>
    <span class="collapsible-hint" id="options-hint"></span>
    <span class="collapsible-chevron"></span>
  </summary>
  <div class="collapsible-body">
    <label style="display: flex; align-items: center; gap: 0.625rem; cursor: pointer; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); transition: all 0.15s ease;">
      <input type="checkbox" name="requires_confirmation" {% if form_requires_confirmation %}checked{% endif %} style="accent-color: var(--accent); width: 1.125rem; height: 1.125rem;">
      <div>
        <strong style="font-size: 0.925rem;">Requires confirmation</strong>
        <div style="color: var(--text-muted); font-size: 0.825rem;">Bookings will be pending until you approve them from the dashboard.</div>
      </div>
    </label>

    <div class="form-group" style="margin-top: 0.75rem;">
      <label for="max_additional_guests">Additional guests</label>
      <select id="max_additional_guests" name="max_additional_guests" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text); width: 100%;">
        <option value="0" {% if form_max_additional_guests == 0 %}selected{% endif %}>Guests cannot add others</option>
        <option value="1" {% if form_max_additional_guests == 1 %}selected{% endif %}>Up to 1 additional guest</option>
        <option value="3" {% if form_max_additional_guests == 3 %}selected{% endif %}>Up to 3 additional guests</option>
        <option value="5" {% if form_max_additional_guests == 5 %}selected{% endif %}>Up to 5 additional guests</option>
        <option value="10" {% if form_max_additional_guests == 10 %}selected{% endif %}>Up to 10 additional guests</option>
      </select>
      <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">Allow the person booking to invite additional attendees who will receive the calendar invite.</span>
    </div>

    <div class="form-group" style="margin-top: 0.75rem;">
      <label for="default_calendar_view">Default calendar view</label>
      <select id="default_calendar_view" name="default_calendar_view" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text); width: 100%;">
        <option value="month" {% if form_default_calendar_view is not defined or form_default_calendar_view == "month" %}selected{% endif %}>Month — calendar grid with slot list</option>
        <option value="week" {% if form_default_calendar_view == "week" %}selected{% endif %}>Week — 7-day columns with time slots</option>
        <option value="column" {% if form_default_calendar_view == "column" %}selected{% endif %}>Column — days listed with inline slots</option>
      </select>
      <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">The view guests see by default. They can switch views anytime.</span>
    </div>

    {% if calendars is defined and calendars %}
    <div style="border-top: 1px solid var(--border); padding-top: 1rem; margin-top: 0.75rem;">
      <label style="font-weight: 600; font-size: 0.925rem; display: block; margin-bottom: 0.5rem;">Conflict calendars</label>
      <span class="hint" style="font-size: 0.825rem; color: var(--text-muted); display: block; margin-bottom: 0.75rem;">Select which calendars to check for conflicts. If none selected, all calendars are used.</span>
      <div style="display: flex; flex-direction: column; gap: 0.5rem;">
        {% set selected_padded = "," ~ selected_calendar_ids ~ "," %}
        {% for cal in calendars %}
          <label style="display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.4rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.85rem; cursor: pointer; transition: all 0.15s ease;">
            <input type="checkbox" class="cal-check" value="{{ cal.id }}" {% if ("," ~ cal.id ~ ",") in selected_padded %}checked{% endif %} style="accent-color: var(--accent);">
            {{ cal.name }}
          </label>
        {% endfor %}
      </div>
      <input type="hidden" name="calendar_ids" id="calendar_ids" value="{{ selected_calendar_ids }}">
    </div>
    {% endif %}
  </div>
</details>

<!-- Collapsible: Access & notifications -->
<details class="card collapsible-section" style="margin-top: 1rem;"{% if editing and ((form_visibility is defined and form_visibility and form_visibility != "public") or (form_reminder_minutes is defined and form_reminder_minutes and form_reminder_minutes != 0)) %} open{% endif %}>
  <summary class="collapsible-header">
    <h2>Access &amp; notifications</h2>
    <span class="collapsible-hint" id="access-hint"></span>
    <span class="collapsible-chevron"></span>
  </summary>
  <div class="collapsible-body">
    <div class="form-group">
      <label for="visibility">Visibility</label>
      <select id="visibility" name="visibility" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text); width: 100%;">
        <option value="public" {% if form_visibility is not defined or form_visibility == "public" %}selected{% endif %}>Public — visible on your profile</option>
        <option value="internal" {% if form_visibility == "internal" %}selected{% endif %}>Internal — any colleague can generate invite links</option>
        <option value="private" {% if form_visibility == "private" %}selected{% endif %}>Private — invite link only</option>
      </select>
      <span class="hint" style="display: block; margin-top: 0.25rem;">Controls who can see and book this event type.</span>
    </div>
    <div class="form-group" style="margin-top: 0.75rem;">
      <label for="reminder_minutes">Booking reminder</label>
      <select id="reminder_minutes" name="reminder_minutes" style="padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.925rem; font-family: inherit; background: var(--surface); color: var(--text); width: 100%;">
        <option value="0" {% if form_reminder_minutes == 0 %}selected{% endif %}>No reminder</option>
        <option value="60" {% if form_reminder_minutes == 60 %}selected{% endif %}>1 hour before</option>
        <option value="240" {% if form_reminder_minutes == 240 %}selected{% endif %}>4 hours before</option>
        <option value="1440" {% if form_reminder_minutes == 1440 %}selected{% endif %}>1 day before</option>
        <option value="2880" {% if form_reminder_minutes == 2880 %}selected{% endif %}>2 days before</option>
      </select>
      <span class="hint" style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">Send a reminder email to both you and your guest before the meeting.</span>
    </div>
  </div>
</details>

{% if editing and not is_group and owner_username and form_visibility == "public" %}
<!-- Card: Dynamic Group Link -->
<div class="card" style="margin-top: 1rem;">
  <h2>Dynamic Group Link</h2>
  <p style="color: var(--text-muted); font-size: 0.85rem; margin-bottom: 0.75rem;">
    Create an ad-hoc meeting link that checks availability for you and other users.
  </p>
  <div style="position: relative;">
    <input type="text" id="dg-search-input" autocomplete="off" placeholder="Search for a user to add..." style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.85rem; font-family: inherit; background: var(--surface); color: var(--text);">
    <div id="dg-search-results" style="display: none; position: absolute; top: 100%; left: 0; right: 0; background: var(--surface); border: 1px solid var(--border); border-top: none; border-radius: 0 0 var(--radius) var(--radius); max-height: 250px; overflow-y: auto; z-index: 10; box-shadow: var(--shadow);"></div>
  </div>
  <span style="font-size: 0.75rem; color: var(--text-muted); display: block; margin-top: 0.25rem;">Only users who allow dynamic group links are shown.</span>
  <div id="dg-members" style="margin-top: 0.5rem; display: flex; flex-wrap: wrap; gap: 0.25rem;"></div>
  <div id="dg-url-box" style="display: none; margin-top: 0.75rem;">
    <label style="font-size: 0.8rem; color: var(--text-muted); display: block; margin-bottom: 0.25rem;">Group link URL</label>
    <div style="display: flex; gap: 0.5rem; align-items: center;">
      <input type="text" id="dg-url" readonly style="flex: 1; min-width: 0; padding: 0.5rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.85rem; font-family: monospace; background: var(--surface); color: var(--text);">
      <button type="button" id="dg-copy-btn" class="slot-btn" style="font-size: 0.8rem; padding: 0.375rem 0.75rem; flex-shrink: 0; cursor: pointer;">Copy</button>
    </div>
  </div>
</div>
{% endif %}

{% if is_group is defined and is_group and watcher_teams is defined and watcher_teams %}
<details class="card collapsible-section" style="margin-top: 1rem;"{% if selected_watcher_team_ids is defined and selected_watcher_team_ids %} open{% endif %}>
  <summary class="collapsible-header">
    <h2>Watcher teams</h2>
    <span class="collapsible-hint" id="watcher-hint"></span>
    <span class="collapsible-chevron"></span>
  </summary>
  <div class="collapsible-body">
    <span class="hint" style="font-size: 0.825rem; color: var(--text-muted); display: block; margin-bottom: 0.75rem;">Selected teams will be notified when bookings are made. Members can claim bookings to join as an attendee.</span>
    <div style="display: flex; flex-direction: column; gap: 0.5rem;">
      {% set watcher_padded = "," ~ selected_watcher_team_ids ~ "," %}
      {% for wt in watcher_teams %}
        <label style="display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.4rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.85rem; cursor: pointer; transition: all 0.15s ease;">
          <input type="checkbox" class="watcher-team-check" value="{{ wt.id }}" {% if ("," ~ wt.id ~ ",") in watcher_padded %}checked{% endif %} style="accent-color: var(--accent);">
          {{ wt.name }}
        </label>
      {% endfor %}
    </div>
    <input type="hidden" name="watcher_team_ids" id="watcher_team_ids" value="{{ selected_watcher_team_ids }}">
  </div>
</details>
{% endif %}

<!-- Save button -->
<div style="margin-top: 1.25rem;">
  <button type="submit" class="btn">
    {% if editing %}Save changes{% else %}Create event type{% endif %}
  </button>
</div>

</form>

<script>
  // --- Animated collapsible sections ---
  (function() {
    document.querySelectorAll('.collapsible-section').forEach(function(details) {
      var summary = details.querySelector('.collapsible-header');
      var body = details.querySelector('.collapsible-body');
      if (!summary || !body) return;

      function cleanup() {
        details.classList.remove('animating');
        body.style.maxHeight = '';
        body.style.opacity = '';
      }

      summary.addEventListener('click', function(e) {
        e.preventDefault();
        if (details.open) {
          // Closing: set start values, force layout, add transition, then animate
          body.style.maxHeight = body.scrollHeight + 'px';
          body.style.opacity = '1';
          body.offsetHeight; // force layout so browser registers start values
          details.classList.add('animating');
          requestAnimationFrame(function() {
            body.style.maxHeight = '0';
            body.style.opacity = '0';
          });
          body.addEventListener('transitionend', function handler(ev) {
            if (ev.propertyName !== 'max-height') return;
            body.removeEventListener('transitionend', handler);
            details.removeAttribute('open');
            cleanup();
          });
        } else {
          // Opening: open details, set start at 0, force layout, add transition, animate to height
          details.setAttribute('open', '');
          body.style.maxHeight = '0';
          body.style.opacity = '0';
          body.offsetHeight; // force layout
          details.classList.add('animating');
          var h = body.scrollHeight;
          requestAnimationFrame(function() {
            body.style.maxHeight = h + 'px';
            body.style.opacity = '1';
          });
          body.addEventListener('transitionend', function handler(ev) {
            if (ev.propertyName !== 'max-height') return;
            body.removeEventListener('transitionend', handler);
            cleanup();
          });
        }
      });
    });
  })();

  // --- Priority AJAX (no page reload) ---
  function sendPriority(userId, priority) {
    var url = '/dashboard/{% if is_group is defined and is_group %}group-event-types/{{ form_team_id }}{% else %}event-types{% endif %}/{{ form_slug }}/priority/' + userId;
    var csrfCookie = document.cookie.split(';').map(function(c){return c.trim();}).find(function(c){return c.startsWith('__Host-calrs_csrf=');});
    var csrf = csrfCookie ? csrfCookie.split('=')[1] : '';
    var body = '_csrf=' + encodeURIComponent(csrf) + '&priority=' + encodeURIComponent(priority);
    return fetch(url, {
      method: 'POST',
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: body,
      redirect: 'manual'
    });
  }

  function setPriority(btn, userId, priority) {
    sendPriority(userId, priority).then(function() {
      var container = document.querySelector('[data-priority-btns="' + userId + '"]');
      container.querySelectorAll('.priority-btn').forEach(function(b) { b.className = 'priority-btn'; });
      var cls = priority === 'high' ? 'active-high' : priority === 'medium' ? 'active-medium' : 'active-low';
      btn.classList.add(cls);
    });
  }

  function toggleMember(userId, included) {
    var info = document.querySelector('[data-member-info="' + userId + '"]');
    var btns = document.querySelector('[data-priority-btns="' + userId + '"]');
    if (included) {
      if (info) info.style.opacity = '1';
      if (btns) {
        btns.style.visibility = 'visible';
        btns.querySelectorAll('.priority-btn').forEach(function(b) { b.className = 'priority-btn'; });
        btns.querySelector('[data-priority="low"]').classList.add('active-low');
      }
      sendPriority(userId, 'low');
    } else {
      if (info) info.style.opacity = '0.4';
      if (btns) btns.style.visibility = 'hidden';
      sendPriority(userId, 'exclude');
    }
  }

  // Initialize visibility on load
  document.querySelectorAll('[data-include]').forEach(function(cb) {
    var uid = cb.dataset.include;
    var btns = document.querySelector('[data-priority-btns="' + uid + '"]');
    var info = document.querySelector('[data-member-info="' + uid + '"]');
    if (!cb.checked) {
      if (btns) btns.style.visibility = 'hidden';
      if (info) info.style.opacity = '0.4';
    }
  });

  // --- Auto-generate slug from title ---
  (function() {
    var titleEl = document.getElementById('title');
    var slugEl = document.getElementById('slug');
    titleEl.addEventListener('input', function() {
      if (!slugEl.value) {
        slugEl.value = titleEl.value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
      }
    });
  })();

  // --- Show/hide scheduling mode + priority card based on team selection ---
  (function() {
    var teamSel = document.getElementById('team_id');
    var modeGroup = document.getElementById('scheduling-mode-group');
    var modeSel = document.getElementById('scheduling_mode');
    var priorityCard = document.getElementById('priority-card');
    var dynamicCard = document.getElementById('dynamic-priority-card');
    var dynamicList = document.getElementById('dynamic-priority-list');

    // Team members data for dynamic priority card (creation flow)
    var teamMembers = {};
    {% if teams is defined and teams %}
    {% for t in teams %}
    teamMembers["{{ t.id }}"] = [
      {% if t.members is defined %}{% for m in t.members %}
      { userId: "{{ m.user_id }}", name: "{{ m.name }}", hasAvatar: {{ m.has_avatar | lower }}, initials: "{{ m.initials }}", timezone: "{{ m.timezone | default(value='') }}" },
      {% endfor %}{% endif %}
    ];
    {% endfor %}
    {% endif %}

    // Track priority state for creation flow
    var memberPriorities = {};

    // Current rendering mode for the dynamic card: 'round_robin' or 'collective'
    var dynamicMode = 'round_robin';
    // For collective mode: track include state per user (true = required, false = excluded)
    var memberIncluded = {};
    // Card title/description elements (set once)
    var dynamicTitle = dynamicCard ? dynamicCard.querySelector('h2') : null;
    var dynamicDesc = dynamicCard ? dynamicCard.querySelector('p') : null;

    function renderDynamicPriority(teamId, mode) {
      if (!dynamicCard || !dynamicList) return;
      var members = teamMembers[teamId];
      if (!members || members.length === 0) {
        dynamicCard.style.display = 'none';
        return;
      }
      dynamicMode = mode || 'round_robin';
      // Update title/description for the current mode
      if (dynamicTitle && dynamicDesc) {
        if (dynamicMode === 'collective') {
          dynamicTitle.textContent = 'Required members';
          dynamicDesc.textContent = 'All checked members must be free for a slot to be offered. Uncheck members you want to exclude (their availability will be ignored).';
        } else {
          dynamicTitle.textContent = 'Member Priority';
          dynamicDesc.textContent = 'Higher priority members are assigned bookings first when available. Same priority = balanced by recent booking count.';
        }
      }
      dynamicList.innerHTML = '';
      memberPriorities = {};
      memberIncluded = {};
      members.forEach(function(m, i) {
        memberPriorities[m.userId] = 'low';
        memberIncluded[m.userId] = true;
        var row = document.createElement('div');
        row.style.cssText = 'display: flex; align-items: center; padding: 0.5rem 0; gap: 0.75rem;' + (i < members.length - 1 ? ' border-bottom: 1px solid var(--border);' : '');
        // Include checkbox (collective mode only)
        if (dynamicMode === 'collective') {
          var cb = document.createElement('input');
          cb.type = 'checkbox';
          cb.checked = true;
          cb.style.cssText = 'accent-color: var(--accent); width: 1rem; height: 1rem; flex-shrink: 0; cursor: pointer;';
          cb.onchange = function() {
            memberIncluded[m.userId] = cb.checked;
            nameWrap.style.opacity = cb.checked ? '1' : '0.4';
            syncPriorityInputs();
          };
          row.appendChild(cb);
        }
        // Avatar + name (wrapped so we can dim them when excluded)
        var nameWrap = document.createElement('div');
        nameWrap.style.cssText = 'display: flex; align-items: center; gap: 0.5rem; flex: 1; min-width: 0; transition: opacity 0.15s;';
        var avatar = document.createElement('div');
        avatar.className = 'avatar-circle';
        avatar.style.cssText = 'width: 28px; height: 28px; font-size: 0.65rem;';
        if (m.hasAvatar) {
          avatar.innerHTML = '<img src="/avatar/' + m.userId + '" alt="">';
        } else {
          avatar.textContent = m.initials;
        }
        nameWrap.appendChild(avatar);
        var nameStack = document.createElement('div');
        nameStack.style.cssText = 'min-width: 0;';
        var name = document.createElement('div');
        name.style.cssText = 'font-weight: 500; font-size: 0.875rem;';
        name.textContent = m.name;
        nameStack.appendChild(name);
        if (m.timezone) {
          var tz = document.createElement('div');
          tz.style.cssText = 'font-size: 0.75rem; color: var(--text-muted);';
          tz.title = "Member's timezone. Their personal working hours are interpreted in this TZ.";
          tz.textContent = m.timezone;
          nameStack.appendChild(tz);
        }
        nameWrap.appendChild(nameStack);
        row.appendChild(nameWrap);
        // Priority buttons (round-robin only)
        if (dynamicMode === 'round_robin') {
          var btns = document.createElement('div');
          btns.style.cssText = 'display: flex; gap: 0.25rem; flex-shrink: 0;';
          ['high', 'medium', 'low'].forEach(function(level) {
            var btn = document.createElement('button');
            btn.type = 'button';
            btn.className = 'priority-btn' + (level === 'low' ? ' active-low' : '');
            btn.textContent = level.charAt(0).toUpperCase() + level.slice(1);
            btn.onclick = function() {
              memberPriorities[m.userId] = level;
              btns.querySelectorAll('.priority-btn').forEach(function(b) { b.className = 'priority-btn'; });
              btn.classList.add(level === 'high' ? 'active-high' : level === 'medium' ? 'active-medium' : 'active-low');
              syncPriorityInputs();
            };
            btns.appendChild(btn);
          });
          row.appendChild(btns);
        }
        dynamicList.appendChild(row);
      });
      syncPriorityInputs();
    }

    function syncPriorityInputs() {
      // Encode priorities/inclusion as hidden input for form submission
      var existing = document.getElementById('member_priorities_input');
      if (existing) existing.remove();
      var inp = document.createElement('input');
      inp.type = 'hidden'; inp.name = 'member_priorities'; inp.id = 'member_priorities_input';
      var parts = [];
      if (dynamicMode === 'collective') {
        // Excluded members get weight=0; included members get weight=1 (default)
        for (var uid in memberIncluded) {
          parts.push(uid + ':' + (memberIncluded[uid] ? 1 : 0));
        }
      } else {
        for (var uid in memberPriorities) {
          var w = memberPriorities[uid] === 'high' ? 3 : memberPriorities[uid] === 'medium' ? 2 : 1;
          parts.push(uid + ':' + w);
        }
      }
      inp.value = parts.join(',');
      if (dynamicList) dynamicList.appendChild(inp);
    }

    function toggleMode() {
      var isTeam = teamSel ? !!teamSel.value : {{ is_group is defined and is_group and "true" or "false" }};
      if (modeGroup) modeGroup.style.display = isTeam ? '' : 'none';
      togglePriority();
    }

    function togglePriority() {
      var isTeam = teamSel ? !!teamSel.value : {{ is_group is defined and is_group and "true" or "false" }};
      var mode = modeSel ? modeSel.value : 'round_robin';
      var showsMembers = isTeam && (mode === 'round_robin' || mode === 'collective');
      // Server-rendered card (editing)
      if (priorityCard) {
        priorityCard.style.display = showsMembers ? '' : 'none';
      }
      // Dynamic card (creation)
      if (dynamicCard) {
        if (showsMembers && teamSel) {
          renderDynamicPriority(teamSel.value, mode);
          dynamicCard.style.display = '';
        } else {
          dynamicCard.style.display = 'none';
        }
      }
    }

    if (teamSel) teamSel.addEventListener('change', toggleMode);
    if (modeSel) modeSel.addEventListener('change', togglePriority);

    // Auto-select first team when coming from ?preset=team or ?preset=internal
    {% if preset is defined and (preset == "team" or preset == "internal") %}
    if (teamSel && teamSel.options.length > 1 && !teamSel.value) {
      teamSel.selectedIndex = 1;
    }
    {% endif %}

    toggleMode();
  })();

  // Sync calendar checkboxes to hidden field
  document.querySelectorAll('.cal-check').forEach(cb => {
    cb.addEventListener('change', () => {
      const checked = [...document.querySelectorAll('.cal-check:checked')].map(c => c.value);
      document.getElementById('calendar_ids').value = checked.join(',');
    });
  });

  // Sync watcher team checkboxes to hidden field
  document.querySelectorAll('.watcher-team-check').forEach(cb => {
    cb.addEventListener('change', () => {
      const checked = [...document.querySelectorAll('.watcher-team-check:checked')].map(c => c.value);
      document.getElementById('watcher_team_ids').value = checked.join(',');
    });
  });

  // --- Dynamic hints for collapsible sections ---
  (function() {
    function $(id) { return document.getElementById(id); }
    function on(el, ev, fn) { if (el) el.addEventListener(ev, fn); }
    function fmtMinutes(m) {
      if (m >= 1440 && m % 1440 === 0) return (m / 1440) + (m / 1440 === 1 ? ' day' : ' days');
      if (m >= 60 && m % 60 === 0) return (m / 60) + 'h';
      return m + 'min';
    }

    // --- Buffers & notice ---
    var bufBefore = $('buffer_before'), bufAfter = $('buffer_after');
    var noticeVal = $('min_notice_value'), noticeUnit = $('min_notice_unit');
    var bufHint = $('buffers-hint');
    function updateBufHint() {
      if (!bufHint) return;
      var parts = [];
      var bb = bufBefore ? parseInt(bufBefore.value, 10) || 0 : 0;
      var ba = bufAfter ? parseInt(bufAfter.value, 10) || 0 : 0;
      if (bb > 0 || ba > 0) {
        if (bb > 0 && ba > 0) parts.push(bb + 'min before, ' + ba + 'min after');
        else if (bb > 0) parts.push(bb + 'min buffer before');
        else parts.push(ba + 'min buffer after');
      }
      var nv = noticeVal ? parseInt(noticeVal.value, 10) || 0 : 0;
      var nu = noticeUnit ? parseInt(noticeUnit.value, 10) : 1;
      var totalNotice = nv * nu;
      if (totalNotice > 0) parts.push(fmtMinutes(totalNotice) + ' notice');
      bufHint.textContent = parts.length > 0 ? parts.join(', ') : 'No buffers, book anytime';
    }
    on(bufBefore, 'input', updateBufHint);
    on(bufAfter, 'input', updateBufHint);
    on(noticeVal, 'input', updateBufHint);
    on(noticeUnit, 'change', updateBufHint);
    updateBufHint();

    // --- Booking limits ---
    var firstSlot = $('first-slot-toggle'), freqToggle = $('freq-limit-toggle');
    var limitsHint = $('limits-hint');
    function updateLimitsHint() {
      if (!limitsHint) return;
      var parts = [];
      if (firstSlot && firstSlot.checked) parts.push('One slot per day');
      if (freqToggle && freqToggle.checked) {
        var rows = document.querySelectorAll('[data-freq-row]');
        var periodLabels = { day: '/day', week: '/week', month: '/month', year: '/year' };
        rows.forEach(function(row) {
          var c = parseInt(row.querySelector('input[type=number]').value, 10) || 0;
          var p = row.querySelector('select').value;
          if (c > 0) parts.push('Max ' + c + (periodLabels[p] || ''));
        });
      }
      limitsHint.textContent = parts.length > 0 ? parts.join(', ') : 'No limits';
    }
    on(firstSlot, 'change', updateLimitsHint);
    on(freqToggle, 'change', function() { setTimeout(updateLimitsHint, 50); });
    // Also observe freq limit changes via mutation (rows are added/removed dynamically)
    var freqList = $('freq-limits-list');
    if (freqList) {
      new MutationObserver(function() { setTimeout(updateLimitsHint, 50); })
        .observe(freqList, { childList: true, subtree: true, attributes: true });
    }
    updateLimitsHint();

    // --- Booking options ---
    var confirmCb = document.querySelector('input[name="requires_confirmation"]');
    var guestsSel = $('max_additional_guests');
    var viewSel = $('default_calendar_view');
    var optionsHint = $('options-hint');
    function updateOptionsHint() {
      if (!optionsHint) return;
      var parts = [];
      if (confirmCb && confirmCb.checked) parts.push('Confirmation required');
      else parts.push('Auto-confirmed');
      var g = guestsSel ? parseInt(guestsSel.value, 10) || 0 : 0;
      if (g > 0) parts.push('up to ' + g + ' extra guest' + (g > 1 ? 's' : ''));
      var v = viewSel ? viewSel.value : 'month';
      if (v !== 'month') parts.push(v + ' view');
      optionsHint.textContent = parts.join(', ');
    }
    on(confirmCb, 'change', updateOptionsHint);
    on(guestsSel, 'change', updateOptionsHint);
    on(viewSel, 'change', updateOptionsHint);
    updateOptionsHint();

    // --- Access & notifications ---
    var visSel = $('visibility');
    var reminderSel = $('reminder_minutes');
    var accessHint = $('access-hint');
    var visLabels = { public: 'Public', internal: 'Internal', private: 'Private' };
    function updateAccessHint() {
      if (!accessHint) return;
      var vis = visSel ? visSel.value : 'public';
      var parts = [visLabels[vis] || vis];
      var rem = reminderSel ? parseInt(reminderSel.value, 10) || 0 : 0;
      if (rem > 0) parts.push('reminder ' + fmtMinutes(rem) + ' before');
      else parts.push('no reminder');
      accessHint.textContent = parts.join(', ');
    }
    on(visSel, 'change', updateAccessHint);
    on(reminderSel, 'change', updateAccessHint);
    updateAccessHint();
  })();

  // --- Per-day availability schedule ---
  (function() {
    var container = document.getElementById('schedule-container');
    var hidden = document.getElementById('avail_schedule');
    var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
    var dayShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

    // Parse schedule from hidden field or build defaults
    var schedule = {}; // { dayNum: [{start:'09:00', end:'17:00'}, ...] }

    function parseSchedule(str) {
      var s = {};
      if (!str || !str.trim()) return s;
      str.trim().split(';').forEach(function(seg) {
        seg = seg.trim();
        if (!seg) return;
        var parts = seg.split(':');
        if (parts.length < 2) return;
        var day = parseInt(parts[0], 10);
        if (isNaN(day) || day < 0 || day > 6) return;
        var wins = parts.slice(1).join(':').split(',').map(function(w) {
          var t = w.trim().split('-');
          return t.length === 2 && t[0] && t[1] ? { start: t[0].trim(), end: t[1].trim() } : null;
        }).filter(Boolean);
        if (wins.length) s[day] = wins;
      });
      return s;
    }

    function serializeSchedule() {
      var parts = [];
      for (var d = 0; d <= 6; d++) {
        if (schedule[d] && schedule[d].length) {
          var ws = schedule[d].map(function(w) { return w.start + '-' + w.end; }).join(',');
          parts.push(d + ':' + ws);
        }
      }
      hidden.value = parts.join(';');
      updateSchedulingHint();
    }

    function updateSchedulingHint() {
      var hint = document.getElementById('scheduling-hint');
      if (!hint) return;
      var dayShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
      var enabledDays = [];
      for (var d = 0; d <= 6; d++) { if (schedule[d] && schedule[d].length) enabledDays.push(d); }
      var dayStr = '';
      if (enabledDays.length === 0) {
        dayStr = 'No days set';
      } else if (enabledDays.length === 7) {
        dayStr = 'Every day';
      } else if (enabledDays.length === 5 && enabledDays.join(',') === '1,2,3,4,5') {
        dayStr = 'Mon\u2013Fri';
      } else {
        dayStr = enabledDays.map(function(d) { return dayShort[d]; }).join(', ');
      }
      // Find common time window if all days share the same single window
      var commonWindow = '';
      var allSame = enabledDays.length > 0;
      if (allSame) {
        var first = schedule[enabledDays[0]];
        if (first.length === 1) {
          for (var i = 1; i < enabledDays.length; i++) {
            var w = schedule[enabledDays[i]];
            if (w.length !== 1 || w[0].start !== first[0].start || w[0].end !== first[0].end) { allSame = false; break; }
          }
          if (allSame) commonWindow = ' ' + first[0].start + '\u2013' + first[0].end;
        } else { allSame = false; }
      }
      hint.textContent = dayStr + commonWindow;
    }

    function timeSelectHtml(cls, val) {
      var opts = '';
      for (var h = 0; h < 24; h++) {
        for (var m = 0; m < 60; m += 30) {
          var t = (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m;
          opts += '<option value="' + t + '"' + (t === val ? ' selected' : '') + '>' + t + '</option>';
        }
      }
      return '<select class="' + cls + '" style="padding:0.4rem 0.5rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);color:var(--text);font-family:inherit;font-size:0.85rem;min-width:90px;">' + opts + '</select>';
    }

    function renderSchedule() {
      container.innerHTML = '';
      for (var d = 0; d <= 6; d++) {
        var enabled = !!schedule[d];
        var dayRow = document.createElement('div');
        dayRow.style.cssText = 'display:flex;align-items:flex-start;gap:0.75rem;padding:0.5rem 0;' + (d < 6 ? 'border-bottom:1px solid var(--border);' : '');

        // Toggle
        var toggle = document.createElement('input');
        toggle.type = 'checkbox';
        toggle.checked = enabled;
        toggle.style.cssText = 'accent-color:var(--accent);width:1rem;height:1rem;margin-top:0.3rem;cursor:pointer;flex-shrink:0;';
        toggle.dataset.day = d;
        toggle.addEventListener('change', (function(day) {
          return function() {
            if (this.checked) {
              schedule[day] = [{ start: '09:00', end: '17:00' }];
            } else {
              delete schedule[day];
            }
            renderSchedule();
            serializeSchedule();
          };
        })(d));
        dayRow.appendChild(toggle);

        // Day name
        var label = document.createElement('div');
        label.style.cssText = 'width:80px;font-size:0.875rem;font-weight:500;padding-top:0.25rem;flex-shrink:0;' + (!enabled ? 'color:var(--text-muted);' : '');
        label.textContent = dayShort[d];
        dayRow.appendChild(label);

        // Windows container
        var winsDiv = document.createElement('div');
        winsDiv.style.cssText = 'flex:1;display:flex;flex-direction:column;gap:0.375rem;min-width:0;';

        if (enabled) {
          schedule[d].forEach(function(w, wi) {
            var winRow = document.createElement('div');
            winRow.style.cssText = 'display:flex;align-items:center;gap:0.375rem;flex-wrap:wrap;';
            winRow.innerHTML =
              timeSelectHtml('tw-s', w.start) +
              '<span style="color:var(--text-muted);font-size:0.8rem;">–</span>' +
              timeSelectHtml('tw-e', w.end);

            // Wire up change events
            winRow.querySelector('.tw-s').addEventListener('change', (function(day, idx) {
              return function() { schedule[day][idx].start = this.value; serializeSchedule(); };
            })(d, wi));
            winRow.querySelector('.tw-e').addEventListener('change', (function(day, idx) {
              return function() { schedule[day][idx].end = this.value; serializeSchedule(); };
            })(d, wi));

            // Add button (only on last window)
            if (wi === schedule[d].length - 1) {
              var addBtn = document.createElement('button');
              addBtn.type = 'button';
              addBtn.textContent = '+';
              addBtn.title = 'Add time window';
              addBtn.style.cssText = 'padding:0.2rem 0.5rem;border:1px solid var(--border);border-radius:var(--radius);background:transparent;color:var(--text-muted);cursor:pointer;font-size:0.85rem;line-height:1;';
              addBtn.addEventListener('click', (function(day) {
                return function() {
                  schedule[day].push({ start: '09:00', end: '17:00' });
                  renderSchedule();
                  serializeSchedule();
                };
              })(d));
              winRow.appendChild(addBtn);
            }

            // Remove button (only if more than one window)
            if (schedule[d].length > 1) {
              var rmBtn = document.createElement('button');
              rmBtn.type = 'button';
              rmBtn.innerHTML = '&times;';
              rmBtn.title = 'Remove window';
              rmBtn.style.cssText = 'padding:0.2rem 0.4rem;border:none;background:transparent;color:var(--text-muted);cursor:pointer;font-size:1rem;line-height:1;';
              rmBtn.addEventListener('click', (function(day, idx) {
                return function() {
                  schedule[day].splice(idx, 1);
                  renderSchedule();
                  serializeSchedule();
                };
              })(d, wi));
              winRow.appendChild(rmBtn);
            }

            winsDiv.appendChild(winRow);
          });
        }

        dayRow.appendChild(winsDiv);
        container.appendChild(dayRow);
      }
    }

    // "Copy to all days" button
    document.getElementById('copy-to-all-btn').addEventListener('click', function() {
      // Find first enabled day
      var source = null;
      for (var d = 0; d <= 6; d++) {
        if (schedule[d] && schedule[d].length) { source = d; break; }
      }
      if (source === null) return;
      var windows = JSON.parse(JSON.stringify(schedule[source]));
      for (var d = 0; d <= 6; d++) {
        if (schedule[d]) {
          schedule[d] = JSON.parse(JSON.stringify(windows));
        }
      }
      renderSchedule();
      serializeSchedule();
      var btn = document.getElementById('copy-to-all-btn');
      btn.textContent = 'Copied!';
      btn.style.color = 'var(--success)';
      btn.style.borderColor = 'var(--success)';
      setTimeout(function() { btn.textContent = 'Copy to all days'; btn.style.color = ''; btn.style.borderColor = ''; }, 1500);
    });

    // "Reset to my default" button: fetch the user's profile-default
    // availability and rehydrate the editor from it.
    document.getElementById('reset-to-default-btn').addEventListener('click', function() {
      var btn = this;
      var original = btn.textContent;
      btn.disabled = true;
      btn.textContent = 'Loading...';
      fetch('/dashboard/availability/default', { headers: { 'Accept': 'application/json' } })
        .then(function(r) { return r.json(); })
        .then(function(data) {
          var parsed = parseSchedule(data.schedule || '');
          // Empty profile schedule means the user has no defaults; treat
          // that as a no-op to avoid wiping the form silently.
          if (!Object.keys(parsed).length) {
            btn.textContent = 'No default set';
            setTimeout(function() { btn.textContent = original; btn.disabled = false; }, 1500);
            return;
          }
          schedule = parsed;
          renderSchedule();
          serializeSchedule();
          btn.textContent = 'Reset!';
          btn.style.color = 'var(--success)';
          btn.style.borderColor = 'var(--success)';
          setTimeout(function() {
            btn.textContent = original;
            btn.style.color = '';
            btn.style.borderColor = '';
            btn.disabled = false;
          }, 1500);
        })
        .catch(function() {
          btn.textContent = 'Error';
          setTimeout(function() { btn.textContent = original; btn.disabled = false; }, 1500);
        });
    });

    // Initialize from saved schedule or legacy format
    var savedSchedule = hidden.value.trim();
    if (savedSchedule) {
      schedule = parseSchedule(savedSchedule);
    }
    // Fallback: if empty, default Mon-Fri 09:00-17:00
    if (!Object.keys(schedule).length) {
      for (var d = 1; d <= 5; d++) {
        schedule[d] = [{ start: '09:00', end: '17:00' }];
      }
    }
    renderSchedule();
    serializeSchedule();

  })();

  // --- Minimum notice with unit selector ---
  (function() {
    const valueEl = document.getElementById('min_notice_value');
    const unitEl = document.getElementById('min_notice_unit');
    const hiddenEl = document.getElementById('min_notice_min');
    const totalMin = parseInt(hiddenEl.value, 10) || 0;

    if (totalMin > 0 && totalMin % 1440 === 0) {
      unitEl.value = '1440';
      valueEl.value = totalMin / 1440;
    } else if (totalMin > 0 && totalMin % 60 === 0) {
      unitEl.value = '60';
      valueEl.value = totalMin / 60;
    } else {
      unitEl.value = '1';
      valueEl.value = totalMin;
    }

    function sync() {
      const v = parseInt(valueEl.value, 10) || 0;
      const u = parseInt(unitEl.value, 10);
      hiddenEl.value = v * u;
    }
    valueEl.addEventListener('input', sync);
    unitEl.addEventListener('change', sync);
  })();

  // --- First slot only toggle styling ---
  (function() {
    const toggle = document.getElementById('first-slot-toggle');
    const track = document.getElementById('first-slot-track');
    const knob = document.getElementById('first-slot-knob');
    if (!toggle || !track || !knob) return;
    function updateStyle() {
      if (toggle.checked) {
        track.style.background = 'var(--accent, #6366f1)';
        knob.style.transform = 'translateX(20px)';
      } else {
        track.style.background = '#71717a';
        knob.style.transform = 'translateX(0)';
      }
    }
    updateStyle();
    toggle.addEventListener('change', updateStyle);
  })();

  // --- Booking frequency limits ---
  (function() {
    const toggle = document.getElementById('freq-limit-toggle');
    const container = document.getElementById('freq-limits-container');
    const list = document.getElementById('freq-limits-list');
    const addBtn = document.getElementById('add-freq-limit');
    const hidden = document.getElementById('frequency_limits');
    const track = document.getElementById('freq-toggle-track');
    const knob = document.getElementById('freq-toggle-knob');
    const periods = ['day', 'week', 'month', 'year'];
    const periodLabels = { day: 'Per day', week: 'Per week', month: 'Per month', year: 'Per year' };

    function updateToggleStyle() {
      if (toggle.checked) {
        track.style.background = 'var(--accent)';
        knob.style.transform = 'translateX(20px)';
      } else {
        track.style.background = '#71717a';
        knob.style.transform = 'translateX(0)';
      }
    }

    function updateAddBtn() {
      const used = list.querySelectorAll('select').length;
      addBtn.style.display = used >= periods.length ? 'none' : '';
    }

    function serialize() {
      if (!toggle.checked) { hidden.value = ''; return; }
      const rows = list.querySelectorAll('[data-freq-row]');
      const parts = [];
      rows.forEach(function(row) {
        const count = parseInt(row.querySelector('input[type=number]').value, 10) || 0;
        const period = row.querySelector('select').value;
        if (count > 0) parts.push(count + ':' + period);
      });
      hidden.value = parts.join(',');
      updateAddBtn();
    }

    function createRow(count, period) {
      const row = document.createElement('div');
      row.setAttribute('data-freq-row', '1');
      row.style.cssText = 'display: flex; align-items: center; gap: 0.5rem;';

      const input = document.createElement('input');
      input.type = 'number';
      input.min = '1';
      input.max = '999';
      input.value = count || 1;
      input.style.cssText = 'width: 70px; padding: 0.5rem 0.625rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.9rem; background: var(--surface); color: var(--text); font-family: inherit;';
      input.addEventListener('input', serialize);

      const select = document.createElement('select');
      select.style.cssText = 'padding: 0.5rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.9rem; background: var(--surface); color: var(--text); font-family: inherit;';
      periods.forEach(function(p) {
        const opt = document.createElement('option');
        opt.value = p;
        opt.textContent = periodLabels[p];
        if (p === period) opt.selected = true;
        select.appendChild(opt);
      });
      select.addEventListener('change', serialize);

      const del = document.createElement('button');
      del.type = 'button';
      del.textContent = '\u{1F5D1}';
      del.title = 'Remove limit';
      del.style.cssText = 'padding: 0.375rem 0.5rem; border: none; background: none; cursor: pointer; font-size: 1rem; color: var(--text-muted); opacity: 0.6; transition: opacity 0.15s;';
      del.addEventListener('mouseenter', function() { del.style.opacity = '1'; });
      del.addEventListener('mouseleave', function() { del.style.opacity = '0.6'; });
      del.addEventListener('click', function() { row.remove(); serialize(); updateAddBtn(); });

      row.appendChild(input);
      row.appendChild(select);
      row.appendChild(del);
      list.appendChild(row);
    }

    // Initialize from saved value (only enable toggle if there are saved limits)
    const saved = hidden.value;
    if (saved && saved.trim()) {
      toggle.checked = true;
      container.style.display = 'block';
      saved.split(',').forEach(function(part) {
        const s = part.split(':');
        if (s.length === 2) createRow(parseInt(s[0], 10), s[1]);
      });
      updateAddBtn();
    } else {
      // Explicitly reset — browser may restore checkbox state on back/forward navigation
      toggle.checked = false;
      container.style.display = 'none';
      list.innerHTML = '';
      hidden.value = '';
    }
    updateToggleStyle();

    toggle.addEventListener('change', function() {
      updateToggleStyle();
      if (toggle.checked) {
        container.style.display = 'block';
        if (list.children.length === 0) createRow(1, 'day');
        serialize();
      } else {
        container.style.display = 'none';
        list.innerHTML = '';
        serialize();
      }
    });

    addBtn.addEventListener('click', function() {
      // Find first unused period
      const used = [];
      list.querySelectorAll('select').forEach(function(s) { used.push(s.value); });
      var next = periods.find(function(p) { return used.indexOf(p) === -1; });
      if (!next) return;
      createRow(1, next);
      serialize();
    });
  })();

  // Auto-generate slug from title
  {% if not editing %}
  const titleEl = document.getElementById('title');
  const slugEl = document.getElementById('slug');
  let slugManuallyEdited = slugEl.value !== '';
  slugEl.addEventListener('input', () => { slugManuallyEdited = true; });
  titleEl.addEventListener('input', () => {
    if (!slugManuallyEdited) {
      slugEl.value = titleEl.value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
    }
  });
  {% endif %}

  // --- Dynamic Group Link URL builder with autocomplete ---
  (function() {
    var searchInput = document.getElementById('dg-search-input');
    if (!searchInput) return;
    var resultsDiv = document.getElementById('dg-search-results');
    var membersDiv = document.getElementById('dg-members');
    var urlBox = document.getElementById('dg-url-box');
    var urlInput = document.getElementById('dg-url');
    var copyBtn = document.getElementById('dg-copy-btn');
    var owner = '{{ owner_username }}';
    var slug = '{{ form_slug }}';
    var selected = []; // [{username, name, id, hasAvatar, initials}]

    var allUsers = [
      {% for u in dg_eligible_users %}
      { id: '{{ u.id }}', username: '{{ u.username }}', name: '{{ u.name }}', hasAvatar: {{ u.has_avatar|lower }}, initials: '{{ u.initials }}' }{% if not loop.last %},{% endif %}
      {% endfor %}
    ];

    function updateUrl() {
      if (selected.length === 0) { urlBox.style.display = 'none'; return; }
      var combined = [owner].concat(selected.map(function(u) { return u.username; })).join('+');
      var base = location.origin || (location.protocol + '//' + location.host);
      urlInput.value = base + '/u/' + combined + '/' + slug;
      urlBox.style.display = '';
    }

    function renderMembers() {
      membersDiv.innerHTML = '';
      selected.forEach(function(u, i) {
        var tag = document.createElement('span');
        tag.style.cssText = 'display:inline-flex;align-items:center;gap:0.375rem;padding:0.25rem 0.5rem;background:var(--surface-hover);border-radius:var(--radius);font-size:0.8rem;';
        var av = document.createElement('span');
        av.style.cssText = 'width:20px;height:20px;border-radius:50%;background:var(--accent);color:#fff;display:inline-flex;align-items:center;justify-content:center;font-size:0.5rem;font-weight:600;flex-shrink:0;overflow:hidden;';
        if (u.hasAvatar) {
          av.innerHTML = '<img src="/avatar/' + u.id + '" style="width:100%;height:100%;object-fit:cover;">';
        } else {
          av.textContent = u.initials;
        }
        tag.appendChild(av);
        var nameSpan = document.createElement('span');
        nameSpan.textContent = u.name;
        tag.appendChild(nameSpan);
        var rm = document.createElement('button');
        rm.type = 'button';
        rm.textContent = '\u00d7';
        rm.style.cssText = 'background:none;border:none;color:var(--error-text);cursor:pointer;font-size:1rem;padding:0;line-height:1;margin-left:0.125rem;';
        rm.onclick = function() { selected.splice(i, 1); renderMembers(); updateUrl(); };
        tag.appendChild(rm);
        membersDiv.appendChild(tag);
      });
    }

    function renderResults(query) {
      var q = (query || '').toLowerCase();
      var selectedIds = {};
      selected.forEach(function(u) { selectedIds[u.id] = true; });
      var matches = allUsers.filter(function(u) {
        if (selectedIds[u.id]) return false;
        if (q === '') return true;
        return u.name.toLowerCase().indexOf(q) !== -1 || u.username.toLowerCase().indexOf(q) !== -1;
      }).slice(0, 8);

      if (matches.length === 0) {
        resultsDiv.style.display = 'none';
        return;
      }
      resultsDiv.innerHTML = '';
      matches.forEach(function(u) {
        var row = document.createElement('div');
        row.style.cssText = 'display:flex;align-items:center;gap:0.5rem;padding:0.5rem 0.75rem;cursor:pointer;';
        row.onmouseenter = function() { row.style.background = 'var(--surface-hover)'; };
        row.onmouseleave = function() { row.style.background = ''; };
        var av = document.createElement('span');
        av.style.cssText = 'width:24px;height:24px;border-radius:50%;background:var(--accent);color:#fff;display:inline-flex;align-items:center;justify-content:center;font-size:0.55rem;font-weight:600;flex-shrink:0;overflow:hidden;';
        if (u.hasAvatar) {
          av.innerHTML = '<img src="/avatar/' + u.id + '" style="width:100%;height:100%;object-fit:cover;">';
        } else {
          av.textContent = u.initials;
        }
        row.appendChild(av);
        var info = document.createElement('div');
        var nameDiv = document.createElement('div');
        nameDiv.style.fontSize = '0.85rem';
        nameDiv.textContent = u.name;
        var usernameDiv = document.createElement('div');
        usernameDiv.style.cssText = 'font-size:0.75rem;color:var(--text-muted);';
        usernameDiv.textContent = '@' + u.username;
        info.appendChild(nameDiv);
        info.appendChild(usernameDiv);
        row.appendChild(info);
        row.onclick = function() {
          selected.push(u);
          searchInput.value = '';
          resultsDiv.style.display = 'none';
          renderMembers();
          updateUrl();
        };
        resultsDiv.appendChild(row);
      });
      resultsDiv.style.display = '';
    }

    searchInput.addEventListener('input', function() { renderResults(this.value); });
    searchInput.addEventListener('focus', function() { renderResults(this.value); });
    document.addEventListener('click', function(e) {
      if (!searchInput.contains(e.target) && !resultsDiv.contains(e.target)) {
        resultsDiv.style.display = 'none';
      }
    });

    copyBtn.onclick = function() {
      urlInput.select();
      navigator.clipboard.writeText(urlInput.value).then(function() {
        copyBtn.textContent = 'Copied!';
        setTimeout(function() { copyBtn.textContent = 'Copy'; }, 2000);
      });
    };
  })();
</script>
{% endblock dashboard_content %}
