<!-- @format -->
<script lang="ts">
  import { goto } from "$app/navigation";
  import AppModal from "$lib/components/AppModal.svelte";
  import Navbar from "$lib/components/Navbar.svelte";
  import {
    addFragmentType,
    addSettingsTag,
    removeFragmentType,
    removeSettingsTag,
    setDefaultStartupView,
    settingsDefaultStartupView,
    settingsFragmentTypes,
    settingsTags,
    updateFragmentType,
    updateSettingsTag,
  } from "$lib/stores/settings";
  import { invoke, isTauriRuntime } from "$lib/runtime/invoke";
  import { onMount } from "svelte";

  const activeSection = "settings";

  let modalOpen = false;
  let modalTitle = "";
  let modalMessage = "";
  let modalConfirmText = "OK";
  let modalCancelText = "Cancel";
  let modalShowCancel = false;
  let modalTone: "default" | "danger" = "default";
  let modalAction: "logout-confirm" | "logout-info" | null = null;
  let newTag = "";
  let newFragmentType = "";
  let editingTagIndex: number | null = null;
  let editingTagValue = "";
  let editingFragmentTypeIndex: number | null = null;
  let editingFragmentTypeValue = "";
  let sidecarRoot = "";
  let sidecarRootIsCustom = false;
  let sidecarRootError = "";
  let sidecarBrowseBusy = false;
  let gatewayRootBusy = false;
  let gatewayRootError = "";
  let gatewayRootStatus: {
    authoritativeRoot: string;
    gatewayConfigPath: string;
    configuredRoot?: string | null;
    needsAdoption: boolean;
  } | null = null;
  let returnSection = "entries";

  onMount(async () => {
    const queryReturn =
      new URLSearchParams(window.location.search)
        .get("return")
        ?.trim()
        .toLowerCase() ?? "";
    if (
      ["entries", "calendar", "fragments", "todos", "lists"].includes(
        queryReturn,
      )
    ) {
      returnSection = queryReturn;
    }

    try {
      const result: any = await invoke("get_sidecar_root");
      sidecarRoot = result.root;
      sidecarRootIsCustom = result.isCustom;
    } catch (e) {
      sidecarRootError = String(e);
    }

    await refreshGatewayRootStatus();
  });

  async function saveSidecarRoot() {
    sidecarRootError = "";
    try {
      const result: any = await invoke("set_sidecar_root", {
        path: sidecarRoot,
      });
      sidecarRoot = result.root;
      sidecarRootIsCustom = result.isCustom;
      await refreshGatewayRootStatus();
    } catch (e) {
      sidecarRootError = String(e);
    }
  }

  async function resetSidecarRoot() {
    sidecarRootError = "";
    try {
      const result: any = await invoke("set_sidecar_root", { path: "" });
      sidecarRoot = result.root;
      sidecarRootIsCustom = result.isCustom;
      await refreshGatewayRootStatus();
    } catch (e) {
      sidecarRootError = String(e);
    }
  }

  async function browseSidecarRoot() {
    sidecarRootError = "";
    if (!isTauriRuntime()) {
      sidecarRootError = "Folder picker is only available in desktop app.";
      return;
    }
    sidecarBrowseBusy = true;
    try {
      const { open } = await import("@tauri-apps/plugin-dialog");
      const picked = await open({
        directory: true,
        multiple: false,
        title: "Select Sidecar Root Directory",
      });
      if (typeof picked === "string" && picked.trim()) {
        sidecarRoot = picked;
        await saveSidecarRoot();
      }
    } catch (e) {
      sidecarRootError = String(e);
    } finally {
      sidecarBrowseBusy = false;
    }
  }

  async function refreshGatewayRootStatus() {
    gatewayRootError = "";
    gatewayRootStatus = null;
    if (!isTauriRuntime()) {
      return;
    }

    try {
      gatewayRootStatus = await invoke<any>("get_gateway_root_status");
    } catch (e) {
      gatewayRootError = String(e);
    }
  }

  async function adoptGatewayRoot() {
    gatewayRootError = "";
    if (!isTauriRuntime()) {
      gatewayRootError =
        "Gateway root adoption is only available in the desktop app.";
      return;
    }

    gatewayRootBusy = true;
    try {
      gatewayRootStatus = await invoke<any>("adopt_sidecar_root_for_gateway");
    } catch (e) {
      gatewayRootError = String(e);
    } finally {
      gatewayRootBusy = false;
    }
  }

  function showModal(options: {
    action: "logout-confirm" | "logout-info";
    title: string;
    message: string;
    confirmText?: string;
    cancelText?: string;
    showCancel?: boolean;
    tone?: "default" | "danger";
  }) {
    modalAction = options.action;
    modalTitle = options.title;
    modalMessage = options.message;
    modalConfirmText = options.confirmText ?? "OK";
    modalCancelText = options.cancelText ?? "Cancel";
    modalShowCancel = options.showCancel ?? false;
    modalTone = options.tone ?? "default";
    modalOpen = true;
  }

  function closeModal() {
    modalOpen = false;
    modalAction = null;
  }

  function handleModalConfirm() {
    if (modalAction === "logout-confirm") {
      showModal({
        action: "logout-info",
        title: "Logout Requested",
        message: "You have been logged out.",
        confirmText: "Close",
      });
      return;
    }

    closeModal();
  }

  function handleSelect(id: string) {
    if (id === "logout") {
      showModal({
        action: "logout-confirm",
        title: "Confirm Logout",
        message: "Are you sure you want to log out?",
        confirmText: "Log Out",
        cancelText: "Cancel",
        showCancel: true,
        tone: "danger",
      });
      return;
    }

    if (id === "settings") {
      return;
    }

    if (id === "account") {
      goto("/account");
      return;
    }

    goto(`/?section=${encodeURIComponent(id)}`);
  }

  function closeSettings() {
    goto(`/?section=${encodeURIComponent(returnSection)}`);
  }

  function addTag() {
    if (addSettingsTag(newTag)) {
      newTag = "";
    }
  }

  function startEditTag(index: number, tag: string) {
    editingTagIndex = index;
    editingTagValue = tag;
  }

  function saveEditTag() {
    if (editingTagIndex === null) return;
    if (updateSettingsTag(editingTagIndex, editingTagValue)) {
      editingTagIndex = null;
      editingTagValue = "";
    }
  }

  function cancelEditTag() {
    editingTagIndex = null;
    editingTagValue = "";
  }

  function removeTag(index: number) {
    if (!removeSettingsTag(index)) return;
    if (editingTagIndex === index) {
      cancelEditTag();
    }
  }

  function addFragmentTypeLocal() {
    if (addFragmentType(newFragmentType)) {
      newFragmentType = "";
    }
  }

  function startEditFragmentType(index: number, fragmentType: string) {
    editingFragmentTypeIndex = index;
    editingFragmentTypeValue = fragmentType;
  }

  function saveEditFragmentType() {
    if (editingFragmentTypeIndex === null) return;
    if (
      updateFragmentType(editingFragmentTypeIndex, editingFragmentTypeValue)
    ) {
      editingFragmentTypeIndex = null;
      editingFragmentTypeValue = "";
    }
  }

  function cancelEditFragmentType() {
    editingFragmentTypeIndex = null;
    editingFragmentTypeValue = "";
  }

  function removeFragmentTypeLocal(index: number) {
    if (!removeFragmentType(index)) return;
    if (editingFragmentTypeIndex === index) {
      cancelEditFragmentType();
    }
  }

  function updateDefaultStartupView(value: string) {
    setDefaultStartupView(value);
  }
</script>

<div class="app-shell panel-closed">
  <Navbar {activeSection} onSelect={handleSelect} />

  <main class="route-view">
    <header class="route-header">
      <div class="route-header-main">
        <h1>Settings</h1>
        <p>Configure app behavior and interface options.</p>
      </div>
      <button
        type="button"
        class="header-close-btn"
        on:click={closeSettings}
        aria-label="Close settings"
      >
        <span class="material-symbols-outlined" aria-hidden="true">close</span>
      </button>
    </header>

    <div class="settings-grid">
      <section class="route-card">
        <div class="card-head">
          <h2 class="card-title">
            <span class="material-symbols-outlined" aria-hidden="true"
              >rocket_launch</span
            >
            Startup
          </h2>
        </div>
        <label>
          Default startup view
          <select
            value={$settingsDefaultStartupView}
            on:change={(event) =>
              updateDefaultStartupView(
                (event.currentTarget as HTMLSelectElement).value,
              )}
          >
            <option value="entries">Entries</option>
            <option value="calendar">Calendar</option>
            <option value="fragments">Fragments</option>
            <option value="todos">To-Do List</option>
            <option value="lists">Lists</option>
          </select>
        </label>
      </section>

      <section class="route-card list-card">
        <div class="card-head">
          <h2 class="card-title">
            <span class="material-symbols-outlined" aria-hidden="true"
              >label</span
            >
            Tags
          </h2>
          <p class="section-copy">
            Add and manage tags used for notes and entries.
          </p>
        </div>

        <div class="create-row">
          <input
            type="text"
            placeholder="Add tag (example: Research)"
            bind:value={newTag}
            on:keydown={(event) => event.key === "Enter" && addTag()}
          />
          <button type="button" class="secondary-btn" on:click={addTag}
            >Add</button
          >
        </div>

        <ul class="item-list">
          {#each $settingsTags as tag, index}
            <li class="item-row">
              {#if editingTagIndex === index}
                <input
                  type="text"
                  bind:value={editingTagValue}
                  on:keydown={(event) => {
                    if (event.key === "Enter") saveEditTag();
                    if (event.key === "Escape") cancelEditTag();
                  }}
                />
                <div class="row-actions">
                  <button
                    type="button"
                    class="secondary-btn"
                    on:click={saveEditTag}>Save</button
                  >
                  <button
                    type="button"
                    class="ghost-btn"
                    on:click={cancelEditTag}>Cancel</button
                  >
                </div>
              {:else}
                <span>{tag}</span>
                <div class="row-actions">
                  <button
                    type="button"
                    class="ghost-btn"
                    on:click={() => startEditTag(index, tag)}>Edit</button
                  >
                  <button
                    type="button"
                    class="danger-btn"
                    on:click={() => removeTag(index)}>Remove</button
                  >
                </div>
              {/if}
            </li>
          {/each}
        </ul>
      </section>

      <section class="route-card list-card">
        <div class="card-head">
          <h2 class="card-title">
            <span class="material-symbols-outlined" aria-hidden="true"
              >category</span
            >
            Fragment Types
          </h2>
          <p class="section-copy">
            Configure custom fragment types for the Fragments section.
          </p>
        </div>

        <div class="create-row">
          <input
            type="text"
            placeholder="Add fragment type (example: Observation)"
            bind:value={newFragmentType}
            on:keydown={(event) =>
              event.key === "Enter" && addFragmentTypeLocal()}
          />
          <button
            type="button"
            class="secondary-btn"
            on:click={addFragmentTypeLocal}>Add</button
          >
        </div>

        <ul class="item-list">
          {#each $settingsFragmentTypes as type, index}
            <li class="item-row">
              {#if editingFragmentTypeIndex === index}
                <input
                  type="text"
                  bind:value={editingFragmentTypeValue}
                  on:keydown={(event) => {
                    if (event.key === "Enter") saveEditFragmentType();
                    if (event.key === "Escape") cancelEditFragmentType();
                  }}
                />
                <div class="row-actions">
                  <button
                    type="button"
                    class="secondary-btn"
                    on:click={saveEditFragmentType}>Save</button
                  >
                  <button
                    type="button"
                    class="ghost-btn"
                    on:click={cancelEditFragmentType}>Cancel</button
                  >
                </div>
              {:else}
                <span>{type}</span>
                <div class="row-actions">
                  <button
                    type="button"
                    class="ghost-btn"
                    on:click={() => startEditFragmentType(index, type)}
                    >Edit</button
                  >
                  <button
                    type="button"
                    class="danger-btn"
                    on:click={() => removeFragmentTypeLocal(index)}
                    >Remove</button
                  >
                </div>
              {/if}
            </li>
          {/each}
        </ul>
      </section>

      <section class="route-card">
        <div class="card-head">
          <h2 class="card-title">
            <span class="material-symbols-outlined" aria-hidden="true">hub</span
            >
            Sidecar
          </h2>
          <p class="section-copy">
            Root directory containing the Journal.Sidecar project.
          </p>
        </div>

        <div class="create-row">
          <input
            type="text"
            placeholder="Auto-detected from working directory"
            bind:value={sidecarRoot}
            on:keydown={(event) => event.key === "Enter" && saveSidecarRoot()}
          />
          <button
            type="button"
            class="ghost-btn"
            on:click={browseSidecarRoot}
            disabled={sidecarBrowseBusy}
          >
            {sidecarBrowseBusy ? "Browsing..." : "Browse"}
          </button>
          {#if sidecarRootIsCustom}
            <button type="button" class="ghost-btn" on:click={resetSidecarRoot}
              >Reset</button
            >
          {/if}
        </div>

        {#if sidecarRootError}
          <p class="error-text">{sidecarRootError}</p>
        {/if}
      </section>

      <section class="route-card">
        <div class="card-head">
          <h2 class="card-title">
            <span class="material-symbols-outlined" aria-hidden="true"
              >publish</span
            >
            Gateway Root
          </h2>
          <p class="section-copy">
            Published WebGateway builds should point at one authoritative root.
            Use this one-time adopt action to align the packaged gateway with
            the desktop app.
          </p>
        </div>

        {#if isTauriRuntime()}
          <div class="row-actions">
            <button
              type="button"
              class="ghost-btn"
              on:click={refreshGatewayRootStatus}
              disabled={gatewayRootBusy}
            >
              Refresh
            </button>
            <button
              type="button"
              class="secondary-btn"
              on:click={adoptGatewayRoot}
              disabled={gatewayRootBusy}
            >
              {gatewayRootBusy ? "Adopting..." : "Adopt Current Root"}
            </button>
          </div>

          {#if gatewayRootStatus}
            <label>
              Desktop authoritative root
              <input
                type="text"
                value={gatewayRootStatus.authoritativeRoot}
                readonly
              />
            </label>
            <label>
              Gateway config path
              <input
                type="text"
                value={gatewayRootStatus.gatewayConfigPath}
                readonly
              />
            </label>
            <label>
              Gateway configured root
              <input
                type="text"
                value={gatewayRootStatus.configuredRoot ?? "(not set)"}
                readonly
              />
            </label>
            <label>
              Status
              <input
                type="text"
                value={gatewayRootStatus.needsAdoption ? "Needs adoption" : "Aligned"}
                readonly
              />
            </label>
          {/if}
        {:else}
          <p class="section-copy">
            Configure `GatewaySettings:RepoRoot` or `JOURNAL_PROJECT_ROOT`
            before starting the published gateway.
          </p>
        {/if}

        {#if gatewayRootError}
          <p class="error-text">{gatewayRootError}</p>
        {/if}
      </section>
    </div>
  </main>
</div>

<AppModal
  open={modalOpen}
  title={modalTitle}
  message={modalMessage}
  confirmText={modalConfirmText}
  cancelText={modalCancelText}
  showCancel={modalShowCancel}
  tone={modalTone}
  onConfirm={handleModalConfirm}
  onCancel={closeModal}
/>

<style>
  .route-view {
    height: 100vh;
    height: 100dvh;
    min-height: 0;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 18px;
    overflow: hidden;
    background: var(--bg-editor);
    color: var(--text-primary);
  }

  .route-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
    padding: 2px 2px 0;
  }

  .route-header-main {
    display: flex;
    flex-direction: column;
    gap: 4px;
  }

  .route-header h1 {
    font-size: 1.2rem;
    font-weight: 700;
    letter-spacing: 0.01em;
  }

  .route-header p {
    color: var(--text-muted);
    font-size: 0.88rem;
  }

  .header-close-btn {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: 8px;
    border: 1px solid var(--border-soft);
    background: color-mix(in srgb, var(--surface-1) 92%, var(--bg-editor) 8%);
    color: var(--text-muted);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition:
      background-color 120ms ease,
      color 120ms ease,
      border-color 120ms ease,
      transform 120ms ease;
  }

  .header-close-btn .material-symbols-outlined {
    font-size: 1rem;
  }

  .header-close-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
    border-color: var(--border-strong);
    transform: translateY(-1px);
  }

  .settings-grid {
    flex: 1;
    min-height: 0;
    columns: 2;
    column-gap: 14px;
    overflow: hidden;
  }

  .route-card {
    break-inside: avoid;
    border: 1px solid var(--border-soft);
    background: color-mix(in srgb, var(--surface-1) 92%, var(--bg-editor) 8%);
    border-radius: 12px;
    padding: 14px 14px 13px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-height: 0;
    overflow: hidden;
    box-shadow:
      inset 0 1px 0 color-mix(in srgb, var(--zinc-300) 8%, transparent 92%),
      0 8px 24px color-mix(in srgb, var(--bg-app) 32%, transparent 68%);
    margin-bottom: 14px;
  }

  .list-card {
    overflow: hidden;
    max-height: clamp(280px, 46vh, 520px);
  }

  .card-head {
    display: flex;
    flex-direction: column;
    gap: 5px;
  }

  .card-title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.96rem;
    font-weight: 650;
    color: var(--text-primary);
    letter-spacing: 0.01em;
  }

  .card-title .material-symbols-outlined {
    font-size: 1rem;
    color: var(--text-dim);
  }

  .route-card label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    color: var(--text-muted);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.01em;
  }

  .route-card select {
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    background-color: color-mix(
      in srgb,
      var(--surface-2) 88%,
      var(--bg-editor) 12%
    );
    color: var(--text-primary);
    padding: 9px 34px 9px 10px;
    font-size: 0.84rem;
  }

  .section-copy {
    font-size: 0.8rem;
    color: var(--text-muted);
    line-height: 1.4;
  }

  .create-row {
    display: flex;
    gap: 8px;
    align-items: center;
  }

  .create-row input {
    flex: 1;
    min-width: 0;
  }

  .item-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 7px;
    flex: 1;
    min-height: 0;
    overflow: auto;
    padding-right: 2px;
  }

  .item-row {
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    padding: 9px 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    font-size: 0.83rem;
    color: var(--text-primary);
    background: color-mix(in srgb, var(--surface-1) 90%, var(--bg-editor) 10%);
  }

  .item-row input,
  .route-card input {
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    background: color-mix(in srgb, var(--surface-2) 88%, var(--bg-editor) 12%);
    color: var(--text-primary);
    padding: 8px 10px;
    font-size: 0.84rem;
    min-width: 200px;
  }

  .row-actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
  }

  .secondary-btn,
  .ghost-btn,
  .danger-btn {
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    padding: 7px 11px;
    font-size: 0.76rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    cursor: pointer;
    color: var(--text-primary);
    transition:
      background-color 120ms ease,
      color 120ms ease,
      border-color 120ms ease,
      transform 120ms ease;
  }

  .secondary-btn {
    background: color-mix(in srgb, var(--surface-2) 84%, var(--bg-hover) 16%);
    border-color: var(--border-strong);
  }

  .ghost-btn {
    background: color-mix(in srgb, var(--surface-1) 92%, var(--bg-editor) 8%);
    color: var(--text-muted);
  }

  .danger-btn {
    background: transparent;
    color: var(--text-muted);
  }

  .secondary-btn:hover,
  .ghost-btn:hover,
  .danger-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
    border-color: var(--border-strong);
    transform: translateY(-1px);
  }

  .error-text {
    color: #e74c3c;
    font-size: 0.82rem;
  }

  @media (max-width: 1100px) {
    .settings-grid {
      columns: 1;
      overflow: auto;
      padding-right: 2px;
    }

    .list-card {
      max-height: min(42dvh, 460px);
    }
  }

  @media (max-width: 720px) {
    .route-view {
      padding: 14px 12px;
      gap: 14px;
    }

    .route-card {
      border-radius: 10px;
      padding: 12px;
      gap: 10px;
    }

    .route-header {
      align-items: center;
    }

    .create-row {
      flex-wrap: wrap;
    }

    .create-row > * {
      flex: 1 1 auto;
    }

    .list-card {
      max-height: min(48dvh, 360px);
    }

    .item-row {
      align-items: flex-start;
      flex-direction: column;
      gap: 8px;
    }

    .item-row input,
    .route-card input {
      min-width: 0;
    }

    .row-actions {
      width: 100%;
      justify-content: flex-end;
    }
  }
</style>
