<script lang="ts">
  import { createEventDispatcher } from "svelte";
  import type { OpportunityNote } from "../types";
  import { noteAuthorInitials, formatDateTime } from "../types";
  import type { PermissionMap } from "$lib/permissions";
  import NoResultsMonkey from "../../../../../components/NoResultsMonkey.svelte";
  import { clientFetch } from "$lib/client-fetch";

  export let notes: OpportunityNote[] = [];
  export let permissions: PermissionMap = {} as PermissionMap;
  export let opportunityId: string;
  export let isClosedOpportunity: boolean = false;

  const dispatch = createEventDispatcher();

  $: canCreate =
    !isClosedOpportunity &&
    permissions["sales.opportunity.note.create"] === true;
  $: canUpdate =
    !isClosedOpportunity &&
    permissions["sales.opportunity.note.update"] === true;
  $: canDelete =
    !isClosedOpportunity &&
    permissions["sales.opportunity.note.delete"] === true;

  // ── Compose state ──
  let composing = false;
  let composeText = "";
  let composeFlagged = false;
  let composeSaving = false;
  let composeError = "";

  // ── Edit state ──
  let editingNoteId: number | null = null;
  let editText = "";
  let editFlagged = false;
  let editSaving = false;
  let editError = "";

  // ── Delete state ──
  let deletingNoteId: number | null = null;
  let deleteLoading = false;
  let deleteError = "";

  // ── Menu state ──
  let openMenuId: number | null = null;

  function toggleMenu(id: number) {
    openMenuId = openMenuId === id ? null : id;
  }

  function handleMenuClickOutside(e: MouseEvent) {
    if (openMenuId === null) return;
    const target = e.target as HTMLElement;
    if (target.closest(".note-menu-wrap")) return;
    openMenuId = null;
  }

  // ── Compose ──
  function startCompose() {
    composing = true;
    composeText = "";
    composeFlagged = false;
    composeError = "";
  }

  function cancelCompose() {
    composing = false;
    composeText = "";
    composeFlagged = false;
    composeError = "";
  }

  async function submitNote() {
    if (!composeText.trim()) return;
    composeSaving = true;
    composeError = "";
    try {
      await clientFetch(`/sales/opportunity/${opportunityId}/notes`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          text: composeText.trim(),
          flagged: composeFlagged,
        }),
      });
      composing = false;
      composeText = "";
      composeFlagged = false;
      dispatch("notesChanged");
    } catch (err: unknown) {
      composeError =
        err instanceof Error ? err.message : "Failed to create note";
    } finally {
      composeSaving = false;
    }
  }

  // ── Edit ──
  function startEdit(note: OpportunityNote) {
    editingNoteId = note.id;
    editText = note.text ?? "";
    editFlagged = note.flagged ?? false;
    editError = "";
    openMenuId = null;
  }

  function cancelEdit() {
    editingNoteId = null;
    editText = "";
    editFlagged = false;
    editError = "";
  }

  async function submitEdit() {
    if (editingNoteId === null || !editText.trim()) return;
    editSaving = true;
    editError = "";
    try {
      await clientFetch(
        `/sales/opportunity/${opportunityId}/notes/${editingNoteId}`,
        {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ text: editText.trim(), flagged: editFlagged }),
        },
      );
      editingNoteId = null;
      editText = "";
      editFlagged = false;
      dispatch("notesChanged");
    } catch (err: unknown) {
      editError = err instanceof Error ? err.message : "Failed to update note";
    } finally {
      editSaving = false;
    }
  }

  // ── Delete ──
  function confirmDelete(noteId: number) {
    deletingNoteId = noteId;
    deleteError = "";
    openMenuId = null;
  }

  function cancelDelete() {
    deletingNoteId = null;
    deleteError = "";
  }

  async function executeDelete() {
    if (deletingNoteId === null) return;
    deleteLoading = true;
    deleteError = "";
    try {
      await clientFetch(
        `/sales/opportunity/${opportunityId}/notes/${deletingNoteId}`,
        { method: "DELETE" },
      );
      deletingNoteId = null;
      dispatch("notesChanged");
    } catch (err: unknown) {
      deleteError =
        err instanceof Error ? err.message : "Failed to delete note";
    } finally {
      deleteLoading = false;
    }
  }

  function handleComposeKeydown(e: KeyboardEvent) {
    if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
      e.preventDefault();
      submitNote();
    }
    if (e.key === "Escape") {
      cancelCompose();
    }
  }

  function handleEditKeydown(e: KeyboardEvent) {
    if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
      e.preventDefault();
      submitEdit();
    }
    if (e.key === "Escape") {
      cancelEdit();
    }
  }
</script>

<svelte:window on:click={handleMenuClickOutside} />

<div class="notes-tab">
  <!-- Header bar -->
  <div class="notes-header">
    <div class="notes-header-left">
      <span class="notes-count">
        {notes.length} note{notes.length === 1 ? "" : "s"}
      </span>
    </div>
    {#if !composing}
      <button
        class="notes-add-btn"
        on:click={startCompose}
        type="button"
        disabled={!canCreate}
      >
        <svg
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          width="14"
          height="14"
        >
          <line x1="12" y1="5" x2="12" y2="19" />
          <line x1="5" y1="12" x2="19" y2="12" />
        </svg>
        Add Note
      </button>
    {/if}
  </div>

  <!-- Compose area -->
  {#if composing}
    <div class="note-compose">
      <textarea
        class="note-compose-textarea"
        placeholder="Write a note…"
        bind:value={composeText}
        on:keydown={handleComposeKeydown}
        rows="3"
        disabled={composeSaving}
      ></textarea>
      <div class="note-compose-footer">
        <label class="note-flag-toggle">
          <input
            type="checkbox"
            bind:checked={composeFlagged}
            disabled={composeSaving}
          />
          <svg
            viewBox="0 0 24 24"
            fill={composeFlagged ? "currentColor" : "none"}
            stroke="currentColor"
            stroke-width="2"
            width="14"
            height="14"
            class="flag-icon"
            class:flagged={composeFlagged}
          >
            <path
              d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"
            /><line x1="4" y1="22" x2="4" y2="15" />
          </svg>
          Flag
        </label>
        <div class="note-compose-actions">
          {#if composeError}
            <span class="note-error">{composeError}</span>
          {/if}
          <button
            class="note-btn-cancel"
            on:click={cancelCompose}
            disabled={composeSaving}
            type="button"
          >
            Cancel
          </button>
          <button
            class="note-btn-save"
            on:click={submitNote}
            disabled={composeSaving || !composeText.trim()}
            type="button"
          >
            {#if composeSaving}
              Saving…
            {:else}
              Save
            {/if}
          </button>
        </div>
      </div>
    </div>
  {/if}

  <!-- Notes list -->
  {#if notes.length === 0 && !composing}
    <div class="tab-empty">
      <NoResultsMonkey message="No notes yet" />
    </div>
  {:else}
    <div class="notes-list">
      {#each notes as note (note.id)}
        {#if editingNoteId === note.id}
          <!-- Inline edit -->
          <div class="note-card editing">
            <textarea
              class="note-edit-textarea"
              bind:value={editText}
              on:keydown={handleEditKeydown}
              rows="3"
              disabled={editSaving}
            ></textarea>
            <div class="note-compose-footer">
              <label class="note-flag-toggle">
                <input
                  type="checkbox"
                  bind:checked={editFlagged}
                  disabled={editSaving}
                />
                <svg
                  viewBox="0 0 24 24"
                  fill={editFlagged ? "currentColor" : "none"}
                  stroke="currentColor"
                  stroke-width="2"
                  width="14"
                  height="14"
                  class="flag-icon"
                  class:flagged={editFlagged}
                >
                  <path
                    d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"
                  /><line x1="4" y1="22" x2="4" y2="15" />
                </svg>
                Flag
              </label>
              <div class="note-compose-actions">
                {#if editError}
                  <span class="note-error">{editError}</span>
                {/if}
                <button
                  class="note-btn-cancel"
                  on:click={cancelEdit}
                  disabled={editSaving}
                  type="button"
                >
                  Cancel
                </button>
                <button
                  class="note-btn-save"
                  on:click={submitEdit}
                  disabled={editSaving || !editText.trim()}
                  type="button"
                >
                  {#if editSaving}
                    Saving…
                  {:else}
                    Update
                  {/if}
                </button>
              </div>
            </div>
          </div>
        {:else}
          <!-- Read-only note card -->
          <div class="note-card" class:flagged={note.flagged}>
            <div class="note-card-header">
              <div class="note-header-left">
                {#if canUpdate || canDelete}
                  <div class="note-menu-wrap">
                    <button
                      class="note-menu-btn"
                      on:click|stopPropagation={() => toggleMenu(note.id)}
                      type="button"
                      aria-label="Note actions"
                    >
                      <svg
                        viewBox="0 0 16 16"
                        fill="currentColor"
                        width="14"
                        height="14"
                      >
                        <circle cx="8" cy="3" r="1.5" />
                        <circle cx="8" cy="8" r="1.5" />
                        <circle cx="8" cy="13" r="1.5" />
                      </svg>
                    </button>
                    {#if openMenuId === note.id}
                      <div class="note-menu-dropdown">
                        {#if canUpdate}
                          <button
                            class="note-menu-item"
                            on:click={() => startEdit(note)}
                            type="button"
                          >
                            <svg
                              viewBox="0 0 24 24"
                              fill="none"
                              stroke="currentColor"
                              stroke-width="2"
                              width="13"
                              height="13"
                            >
                              <path
                                d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"
                              />
                              <path
                                d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"
                              />
                            </svg>
                            Edit
                          </button>
                        {/if}
                        {#if canDelete}
                          <button
                            class="note-menu-item danger"
                            on:click={() => confirmDelete(note.id)}
                            type="button"
                          >
                            <svg
                              viewBox="0 0 24 24"
                              fill="none"
                              stroke="currentColor"
                              stroke-width="2"
                              width="13"
                              height="13"
                            >
                              <polyline points="3 6 5 6 21 6" />
                              <path
                                d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"
                              />
                            </svg>
                            Delete
                          </button>
                        {/if}
                      </div>
                    {/if}
                  </div>
                {/if}
                {#if note.type?.name}
                  <span class="note-type-badge">{note.type.name}</span>
                {/if}
                {#if note.flagged}
                  <svg
                    class="note-flag-icon"
                    viewBox="0 0 24 24"
                    fill="currentColor"
                    stroke="currentColor"
                    stroke-width="2"
                    width="13"
                    height="13"
                  >
                    <path
                      d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"
                    /><line x1="4" y1="22" x2="4" y2="15" />
                  </svg>
                {/if}
              </div>
              <div class="note-header-right">
                <div class="note-author-info">
                  <span class="note-author-name"
                    >{note.enteredBy?.name ?? "Unknown"}</span
                  >
                  <span class="note-timestamp"
                    >{formatDateTime(note.dateEntered)}</span
                  >
                </div>
                <div
                  class="note-avatar"
                  title={note.enteredBy?.name ?? "Unknown"}
                >
                  {noteAuthorInitials(note.enteredBy?.name)}
                </div>
              </div>
            </div>
            <div class="note-card-body">
              <p class="note-text">{note.text ?? ""}</p>
            </div>
          </div>
        {/if}
      {/each}
    </div>
  {/if}
</div>

<!-- Delete confirmation modal -->
{#if deletingNoteId !== null}
  <!-- svelte-ignore a11y-click-events-have-key-events -->
  <div class="note-delete-overlay" on:click={cancelDelete} role="presentation">
    <!-- svelte-ignore a11y-click-events-have-key-events -->
    <div
      class="note-delete-modal"
      on:click|stopPropagation
      role="dialog"
      aria-modal="true"
      tabindex="-1"
    >
      <h4 class="note-delete-title">Delete Note</h4>
      <p class="note-delete-msg">
        Are you sure you want to delete this note? This action cannot be undone.
      </p>
      {#if deleteError}
        <p class="note-error">{deleteError}</p>
      {/if}
      <div class="note-delete-actions">
        <button
          class="note-btn-cancel"
          on:click={cancelDelete}
          disabled={deleteLoading}
          type="button"
        >
          Cancel
        </button>
        <button
          class="note-btn-delete"
          on:click={executeDelete}
          disabled={deleteLoading}
          type="button"
        >
          {#if deleteLoading}
            Deleting…
          {:else}
            Delete
          {/if}
        </button>
      </div>
    </div>
  </div>
{/if}
