<script lang="ts">
  import { createEventDispatcher } from "svelte";
  import { clientFetch } from "$lib/client-fetch";

  const dispatch = createEventDispatcher<{
    success: void;
    close: void;
    createScheduleEntry: void;
  }>();

  export let isOpen = false;
  export let opportunityId: string;

  type Activity = { cwActivityId: number; name: string; optimaType: string | null };

  let activities: Activity[] = [];
  let isLoadingActivities = false;
  let selectedActivityId: number | null = null;
  let startDate = "";
  let startHour = "";
  let endDate = "";
  let endHour = "";
  let notes = "";
  let isSubmitting = false;
  let error: string | null = null;
  let activityIdError = "";
  let timeError = "";

  function toLocalDate(d: Date): string {
    const y = d.getFullYear();
    const mo = String(d.getMonth() + 1).padStart(2, "0");
    const da = String(d.getDate()).padStart(2, "0");
    return `${y}-${mo}-${da}`;
  }

  function toLocalTime(d: Date): string {
    const h = String(d.getHours()).padStart(2, "0");
    const mi = String(d.getMinutes()).padStart(2, "0");
    return `${h}:${mi}`;
  }

  function initTimes() {
    const now = new Date();
    const mins = now.getMinutes();
    const roundedUp = Math.ceil(mins / 15) * 15;
    const ended = new Date(now);
    ended.setMinutes(roundedUp, 0, 0);
    const started = new Date(ended.getTime() - 15 * 60 * 1000);
    startDate = toLocalDate(started);
    startHour = toLocalTime(started);
    endDate = toLocalDate(ended);
    endHour = toLocalTime(ended);
  }
  initTimes();

  $: if (!isLoadingActivities && activities.length === 1) {
    selectedActivityId = activities[0]?.cwActivityId ?? null;
  }

  async function loadActivities() {
    isLoadingActivities = true;
    activities = [];
    selectedActivityId = null;
    try {
      const result = await clientFetch<{
        successful: boolean;
        data: { activities: Activity[] };
      }>(`/sales/opportunity/${opportunityId}/activities`);
      activities = result.data?.activities ?? [];
    } catch {
      activities = [];
    } finally {
      isLoadingActivities = false;
    }
  }

  $: if (isOpen) loadActivities();

  function validate(): boolean {
    activityIdError = "";
    timeError = "";
    if (!selectedActivityId) {
      activityIdError = "Please select an activity.";
      return false;
    }
    if (!startDate || !startHour || !endDate || !endHour) {
      timeError = "Start and end date/time are required.";
      return false;
    }
    const start = new Date(`${startDate}T${startHour}`);
    const end = new Date(`${endDate}T${endHour}`);
    if (end <= start) {
      timeError = "End time must be after start time.";
      return false;
    }
    return true;
  }

  async function handleSubmit() {
    if (!validate()) return;
    isSubmitting = true;
    error = null;
    try {
      const result = await clientFetch<{
        successful: boolean;
        message?: string;
      }>(`/sales/opportunity/${opportunityId}/time`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          activityId: selectedActivityId,
          timeStarted: new Date(`${startDate}T${startHour}`).toISOString(),
          timeEnded: new Date(`${endDate}T${endHour}`).toISOString(),
          notes: notes.trim() || undefined,
        }),
      });

      if (result.successful === false) {
        error = result.message ?? "Failed to submit time entry.";
        return;
      }
      dispatch("success");
      handleClose();
    } catch (err) {
      error = err instanceof Error ? err.message : "Failed to submit time entry.";
    } finally {
      isSubmitting = false;
    }
  }

  function handleClose() {
    if (isSubmitting) return;
    error = null;
    activityIdError = "";
    timeError = "";
    notes = "";
    activities = [];
    isLoadingActivities = false;
    initTimes();
    dispatch("close");
  }

  function handleBackdropClick(e: MouseEvent) {
    if ((e.target as HTMLElement).classList.contains("wf-modal-backdrop")) {
      handleClose();
    }
  }

  function handleKeydown(e: KeyboardEvent) {
    if (e.key === "Escape") handleClose();
  }
</script>

{#if isOpen}
  <div
    class="wf-modal-backdrop"
    on:click={handleBackdropClick}
    on:keydown={handleKeydown}
    role="dialog"
    aria-modal="true"
    aria-label="Add Time"
    tabindex="-1"
  >
    <div class="wf-modal" on:click|stopPropagation>
      <div class="wf-modal-header">
        <h3 class="wf-modal-title">Add Time</h3>
        <button
          class="wf-modal-close"
          on:click={handleClose}
          disabled={isSubmitting}
          aria-label="Close"
        >
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
            <line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" />
          </svg>
        </button>
      </div>

      <div class="wf-modal-body">
        {#if isLoadingActivities}
          <div class="at-loading">
            <span class="at-spinner"></span>
            <span>Loading activities…</span>
          </div>
        {:else if activities.length === 0}
          <div class="at-empty-state">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="36" height="36" class="at-empty-icon">
              <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="13"/><circle cx="12" cy="16" r="0.5" fill="currentColor"/>
            </svg>
            <p class="at-empty-title">No open activities</p>
            <p class="at-empty-sub">There are no open activities on this opportunity to log time against. You can create a schedule entry instead.</p>
          </div>
        {:else}

        {#if error}
          <div class="wf-inline-error">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14">
              <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>
            {error}
          </div>
        {/if}

        <!-- Activity selector -->
        {#if activities.length > 1}
          <div class="at-form-group">
            <label class="at-label" for="at-activity-select">Activity <span class="at-req">*</span></label>
            <select
              id="at-activity-select"
              class="at-select"
              class:at-input-error={!!activityIdError}
              bind:value={selectedActivityId}
              disabled={isSubmitting}
            >
              <option value={null} disabled>Select an activity…</option>
              {#each activities as act}
                <option value={act.cwActivityId}>
                  {act.name}{act.optimaType ? ` · ${act.optimaType}` : ""}
                </option>
              {/each}
            </select>
            {#if activityIdError}
              <span class="at-field-error">{activityIdError}</span>
            {/if}
          </div>
        {:else}
          <div class="at-form-group">
            <label class="at-label">Activity</label>
            <div class="at-activity-chip">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="13" height="13">
                <circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>
              </svg>
              {activities[0].name}{activities[0].optimaType ? ` · ${activities[0].optimaType}` : ""}
            </div>
          </div>
        {/if}

        <!-- Date/time grid -->
        <div class="at-grid">
          <div class="at-form-group">
            <label class="at-label" for="at-start-date">Start Date <span class="at-req">*</span></label>
            <input
              id="at-start-date"
              type="date"
              class="at-input"
              class:at-input-error={!!timeError}
              bind:value={startDate}
              disabled={isSubmitting}
              on:change={() => (timeError = "")}
            />
          </div>
          <div class="at-form-group">
            <label class="at-label" for="at-start-time">Start Time <span class="at-req">*</span></label>
            <input
              id="at-start-time"
              type="time"
              class="at-input"
              class:at-input-error={!!timeError}
              bind:value={startHour}
              disabled={isSubmitting}
              on:change={() => (timeError = "")}
            />
          </div>
          <div class="at-form-group">
            <label class="at-label" for="at-end-date">End Date <span class="at-req">*</span></label>
            <input
              id="at-end-date"
              type="date"
              class="at-input"
              class:at-input-error={!!timeError}
              bind:value={endDate}
              disabled={isSubmitting}
              on:change={() => (timeError = "")}
            />
          </div>
          <div class="at-form-group">
            <label class="at-label" for="at-end-time">End Time <span class="at-req">*</span></label>
            <input
              id="at-end-time"
              type="time"
              class="at-input"
              class:at-input-error={!!timeError}
              bind:value={endHour}
              disabled={isSubmitting}
              on:change={() => (timeError = "")}
            />
          </div>
        </div>
        {#if timeError}
          <span class="at-field-error">{timeError}</span>
        {/if}

        <!-- Notes -->
        <div class="at-form-group">
          <label class="at-label" for="at-notes">Notes <span class="at-optional">(optional)</span></label>
          <textarea
            id="at-notes"
            class="at-textarea"
            rows={3}
            placeholder="Describe the work performed…"
            bind:value={notes}
            disabled={isSubmitting}
          ></textarea>
        </div>

        {/if}<!-- end else (has activities) -->
      </div>

      {#if isLoadingActivities}
        <!-- no footer while loading -->
      {:else if activities.length === 0}
        <div class="wf-modal-footer">
          <button class="wf-action-btn wf-btn-ghost" on:click={handleClose}>
            Close
          </button>
          <button class="wf-action-btn wf-btn-primary" on:click={() => { handleClose(); dispatch('createScheduleEntry'); }}>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14">
              <rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/>
            </svg>
            Create Schedule Entry
          </button>
        </div>
      {:else}
        <div class="wf-modal-footer">
          <button class="wf-action-btn wf-btn-ghost" on:click={handleClose} disabled={isSubmitting}>
            Cancel
          </button>
          <button
            class="wf-action-btn wf-btn-primary"
            on:click={handleSubmit}
            disabled={isSubmitting}
          >
            {#if isSubmitting}
              <span class="wf-spinner"></span> Saving…
            {:else}
              Log Time
            {/if}
          </button>
        </div>
      {/if}
    </div>
  </div>
{/if}

<style>
  /* ── Layout ── */
  .at-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-bottom: 14px;
  }

  .at-form-group {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin-bottom: 14px;
  }

  /* ── Labels ── */
  .at-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted, #888);
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }

  .at-req {
    color: #ef4444;
    font-weight: 700;
  }

  .at-optional {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    font-size: 11px;
  }

  /* ── Inputs ── */
  .at-input,
  .at-select {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--border-subtle, #ddd);
    border-radius: 8px;
    background: var(--bg-inset, #fafafa);
    font-size: 13px;
    color: var(--text-primary, #1a1a1a);
    box-sizing: border-box;
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
  }

  .at-input:focus,
  .at-select:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.12);
    background: var(--bg-surface, #fff);
  }

  .at-input:disabled,
  .at-select:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .at-input-error {
    border-color: #ef4444 !important;
  }

  .at-field-error {
    font-size: 11.5px;
    color: #ef4444;
    margin-top: -8px;
    margin-bottom: 8px;
    display: block;
  }

  /* ── Select chevron ── */
  .at-select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 30px;
  }

  /* ── Activity chip (single activity) ── */
  .at-activity-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border-radius: 8px;
    background: rgba(59, 130, 246, 0.06);
    border: 1px solid rgba(59, 130, 246, 0.18);
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary, #1a1a1a);
  }

  .at-activity-chip svg {
    color: #3b82f6;
    flex-shrink: 0;
  }

  /* ── Textarea ── */
  .at-textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--border-subtle, #ddd);
    border-radius: 8px;
    background: var(--bg-inset, #fafafa);
    font-size: 13px;
    color: var(--text-primary, #1a1a1a);
    box-sizing: border-box;
    resize: vertical;
    font-family: inherit;
    line-height: 1.5;
    transition: border-color 0.15s, box-shadow 0.15s;
  }

  .at-textarea:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.12);
    background: var(--bg-surface, #fff);
  }

  .at-textarea::placeholder {
    color: var(--text-muted, #aaa);
  }

  .at-textarea:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  /* ── Loading state ── */
  .at-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 40px 20px;
    color: var(--text-muted, #888);
    font-size: 13px;
  }

  .at-spinner {
    display: inline-block;
    width: 18px;
    height: 18px;
    border: 2px solid rgba(59, 130, 246, 0.2);
    border-top-color: #3b82f6;
    border-radius: 50%;
    animation: at-spin 0.7s linear infinite;
    flex-shrink: 0;
  }

  @keyframes at-spin {
    to { transform: rotate(360deg); }
  }

  /* ── Empty state ── */
  .at-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 32px 24px 24px;
    gap: 8px;
  }

  .at-empty-icon {
    color: var(--text-muted, #aaa);
    margin-bottom: 4px;
  }

  .at-empty-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary, #1a1a1a);
    margin: 0;
  }

  .at-empty-sub {
    font-size: 13px;
    color: var(--text-muted, #888);
    margin: 0;
    max-width: 320px;
    line-height: 1.5;
  }

  /* ── Footer ── */
  .wf-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-top: 1px solid var(--border-color, #333);
  }
</style>
