<script lang="ts">
  import { goto } from "$app/navigation";
  import { afterNavigate } from "$app/navigation";
  import { fly } from "svelte/transition";
  import type { PermissionMap } from "$lib/permissions";
  import NoResultsMonkey from "../../../components/NoResultsMonkey.svelte";
  import AccessDenied from "../../../components/AccessDenied.svelte";
  import Pagination from "../../../components/Pagination.svelte";
  import InventoryPopover from "../../../components/InventoryPopover.svelte";
  import { formatDate } from "$lib/utils";
  import "../../../styles/procurement/catalog.css";
  import { clientFetch } from "$lib/client-fetch";

  type CatalogItem = {
    id: string;
    cwCatalogId: number;
    name: string;
    identifier?: string;
    description?: string;
    customerDescription?: string;
    internalNotes?: string | null;
    manufacturer?: string;
    partNumber?: string;
    vendorName?: string;
    vendorSku?: string;
    price?: number;
    cost?: number;
    inactive?: boolean;
    salesTaxable?: boolean;
    onHand?: number;
    cwLastUpdated?: string;
    createdAt?: string;
    updatedAt?: string;
    [key: string]: unknown;
  };

  type LinkedItem = {
    id: string;
    cwCatalogId: number;
    identifier?: string;
    name: string;
    description?: string;
    price?: number;
    cost?: number;
    inactive?: boolean;
    onHand?: number;
    createdAt?: string;
    updatedAt?: string;
  };

  export let data: {
    permissions: PermissionMap;
    items: CatalogItem[];
    totalPages: number;
    currentPage: number;
    totalRecords: number;
    search: string;
    includeInactive: boolean;
  };

  $: hasAccess = data.permissions["procurement.catalog.fetch.many"] === true;
  $: canLink = data.permissions["procurement.catalog.link"] === true;

  let searchInput = data.search;
  let debounceTimer: ReturnType<typeof setTimeout>;
  let isSearching = false;
  let searchInputEl: HTMLInputElement;
  let searchStartedAt = 0;
  let isUserTyping = false;

  // Filter state
  let showInactive = data.includeInactive;
  let filterOpen = false;
  let filterBtnEl: HTMLButtonElement;
  let filterPopoverEl: HTMLDivElement;

  function toggleFilterPopover() {
    filterOpen = !filterOpen;
  }

  function handleFilterClickOutside(e: MouseEvent) {
    if (!filterOpen) return;
    const target = e.target as Node;
    if (filterBtnEl?.contains(target) || filterPopoverEl?.contains(target))
      return;
    filterOpen = false;
  }

  function toggleInactive() {
    showInactive = !showInactive;
    filterOpen = false;
    navigateWithFilters({ page: 1 });
  }

  $: activeFilterCount = showInactive ? 1 : 0;

  // Detail panel state
  let selectedItem: CatalogItem | null = null;
  let linkedItems: LinkedItem[] = [];
  let linkedLoading = false;
  let linkedError = "";

  // Link search modal state
  let linkModalOpen = false;
  let linkSearchQuery = "";
  let linkSearchResults: CatalogItem[] = [];
  let linkSearchLoading = false;
  let linkSearchTimer: ReturnType<typeof setTimeout>;
  let linkingId: string | null = null;
  let unlinkingId: string | null = null;
  let linkPreviewItem: CatalogItem | null = null;
  let stagedAdds = new Set<string>();
  let stagedRemovals = new Set<string>();
  let commitLoading = false;
  let expandedLinkedId: string | null = null;

  function toggleLinkedExpand(id: string) {
    expandedLinkedId = expandedLinkedId === id ? null : id;
  }

  function selectItem(item: CatalogItem) {
    if (selectedItem?.id === item.id) {
      selectedItem = null;
      linkedItems = [];
    } else {
      selectedItem = item;
      expandedLinkedId = null;
      fetchLinkedItems(item.id);
    }
  }

  function closePanel() {
    selectedItem = null;
    linkedItems = [];
    expandedLinkedId = null;
    closeLinkModal();
  }

  async function fetchLinkedItems(itemId: string) {
    linkedLoading = true;
    linkedError = "";
    try {
      const json = await clientFetch<{ data: CatalogItem[] }>(
        `/procurement/catalog/linked?id=${encodeURIComponent(itemId)}`,
      );
      linkedItems = json?.data ?? [];
    } catch (err: unknown) {
      const msg =
        err instanceof Error ? err.message : "Failed to load linked items";
      linkedError = msg;
      linkedItems = [];
    } finally {
      linkedLoading = false;
    }
  }

  async function handleLink(targetId: string) {
    if (!selectedItem || linkingId) return;
    linkingId = targetId;
    linkedError = "";
    try {
      await clientFetch("/procurement/catalog/linked", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          action: "link",
          identifier: selectedItem.id,
          targetId,
        }),
      });
      await fetchLinkedItems(selectedItem.id);
      linkSearchResults = linkSearchResults.filter((r) => r.id !== targetId);
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : "Failed to link item";
      linkedError = msg;
    } finally {
      linkingId = null;
    }
  }

  function setLinkPreview(item: CatalogItem | LinkedItem) {
    linkPreviewItem = item as CatalogItem;
  }

  function handlePreviewKeydown(
    e: KeyboardEvent,
    item: CatalogItem | LinkedItem,
  ) {
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault();
      setLinkPreview(item);
    }
  }

  function toggleStageAdd(id: string) {
    if (stagedAdds.has(id)) {
      stagedAdds.delete(id);
    } else {
      stagedAdds.add(id);
      stagedRemovals.delete(id);
    }
    stagedAdds = new Set(stagedAdds);
    stagedRemovals = new Set(stagedRemovals);
  }

  function toggleStageRemove(id: string) {
    if (stagedRemovals.has(id)) {
      stagedRemovals.delete(id);
    } else {
      stagedRemovals.add(id);
      stagedAdds.delete(id);
    }
    stagedAdds = new Set(stagedAdds);
    stagedRemovals = new Set(stagedRemovals);
  }

  async function commitLinkChanges() {
    if (!selectedItem || commitLoading) return;
    const adds = Array.from(stagedAdds);
    const removals = Array.from(stagedRemovals);
    if (adds.length === 0 && removals.length === 0) {
      closeLinkModal();
      return;
    }
    commitLoading = true;
    linkedError = "";
    try {
      for (const targetId of removals) {
        await clientFetch("/procurement/catalog/linked", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            action: "unlink",
            identifier: selectedItem.id,
            targetId,
          }),
        });
      }
      for (const targetId of adds) {
        await clientFetch("/procurement/catalog/linked", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            action: "link",
            identifier: selectedItem.id,
            targetId,
          }),
        });
      }
      await fetchLinkedItems(selectedItem.id);
      closeLinkModal();
    } catch (err: unknown) {
      const msg =
        err instanceof Error ? err.message : "Failed to apply link changes";
      linkedError = msg;
    } finally {
      commitLoading = false;
      stagedAdds = new Set();
      stagedRemovals = new Set();
      linkPreviewItem = null;
    }
  }

  async function handleUnlink(targetId: string) {
    if (!selectedItem || unlinkingId) return;
    unlinkingId = targetId;
    linkedError = "";
    try {
      await clientFetch("/procurement/catalog/linked", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          action: "unlink",
          identifier: selectedItem.id,
          targetId,
        }),
      });
      linkedItems = linkedItems.filter((li) => li.id !== targetId);
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : "Failed to unlink item";
      linkedError = msg;
    } finally {
      unlinkingId = null;
    }
  }

  function openLinkModal() {
    linkModalOpen = true;
    linkSearchQuery = "";
    linkSearchResults = [];
    linkSearchLoading = false;
    stagedAdds = new Set();
    stagedRemovals = new Set();
    linkPreviewItem = null;
  }

  function closeLinkModal() {
    linkModalOpen = false;
    linkSearchQuery = "";
    linkSearchResults = [];
    linkSearchLoading = false;
    clearTimeout(linkSearchTimer);
    stagedAdds = new Set();
    stagedRemovals = new Set();
    linkPreviewItem = null;
  }

  function handleLinkSearch() {
    clearTimeout(linkSearchTimer);
    if (!linkSearchQuery.trim()) {
      linkSearchResults = [];
      return;
    }
    linkSearchTimer = setTimeout(async () => {
      linkSearchLoading = true;
      try {
        const json = await clientFetch<{ data: CatalogItem[] }>(
          `/procurement/catalog/search?q=${encodeURIComponent(linkSearchQuery)}`,
        );
        const results: CatalogItem[] = json?.data ?? [];
        // Exclude the currently selected item and already-linked items
        const linkedIds = new Set(linkedItems.map((li) => li.id));
        linkSearchResults = results.filter(
          (r) => r.id !== selectedItem?.id && !linkedIds.has(r.id),
        );
      } catch {
        linkSearchResults = [];
      } finally {
        linkSearchLoading = false;
      }
    }, 300);
  }

  function handlePanelKeydown(e: KeyboardEvent) {
    if (e.key === "Escape") {
      if (linkModalOpen) {
        closeLinkModal();
      } else {
        closePanel();
      }
    }
  }

  // Compute margin (markup %) from price/cost
  function computeMargin(price?: number, cost?: number): string {
    if (price == null || cost == null || cost === 0) return "—";
    const margin = ((price - cost) / cost) * 100;
    return `${margin.toFixed(1)}%`;
  }

  afterNavigate(() => {
    const elapsed = Date.now() - searchStartedAt;
    const remaining = Math.max(0, 500 - elapsed);
    setTimeout(() => {
      isSearching = false;
      isUserTyping = false;
      if (searchInputEl && document.activeElement !== searchInputEl) {
        requestAnimationFrame(() => searchInputEl?.focus());
      }
    }, remaining);
  });

  $: currentPage = data.currentPage;
  $: totalPages = data.totalPages;
  $: totalRecords = data.totalRecords;
  $: items = data.items;

  /** Build params and navigate — single source of truth */
  function navigateWithFilters(
    opts: { page?: number; keepFocus?: boolean } = {},
  ) {
    const params = new URLSearchParams();
    params.set("page", String(opts.page ?? currentPage));
    if (searchInput) params.set("search", searchInput);
    if (showInactive) params.set("includeInactive", "true");
    goto(`/procurement/catalog?${params.toString()}`, {
      replaceState: true,
      keepFocus: opts.keepFocus ?? false,
      noScroll: true,
    });
  }

  function navigateToPage(p: number) {
    navigateWithFilters({ page: p });
  }

  function handleSearch() {
    isUserTyping = true;
    searchStartedAt = Date.now();
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(() => {
      isSearching = true;
      isUserTyping = false;
      navigateWithFilters({ page: 1, keepFocus: true });
    }, 500);
  }

  function handleKeydown(e: KeyboardEvent) {
    if (e.key === "Enter") {
      isSearching = true;
      isUserTyping = false;
      searchStartedAt = Date.now();
      clearTimeout(debounceTimer);
      navigateWithFilters({ page: 1, keepFocus: true });
    }
  }

  function formatCurrency(value?: number): string {
    if (value == null) return "—";
    return new Intl.NumberFormat("en-US", {
      style: "currency",
      currency: "USD",
    }).format(value);
  }

  $: hasInactiveStaged = (() => {
    for (const id of stagedAdds) {
      const item = linkSearchResults.find((r) => r.id === id);
      if (item?.inactive) return true;
    }
    for (const id of stagedRemovals) {
      const item = linkedItems.find((li) => li.id === id);
      if (item?.inactive) return true;
    }
    return false;
  })();
</script>

<svelte:window
  on:keydown={handlePanelKeydown}
  on:click={handleFilterClickOutside}
/>

<svelte:head>
  <title>Product Catalog — Procurement — Project Optima</title>
</svelte:head>

{#if !hasAccess}
  <AccessDenied
    message="You don't have permission to view the Product Catalog. Contact your administrator to request access."
  />
{:else}
  <div class="catalog-page" class:panel-open={selectedItem}>
    <!-- Toolbar -->
    <div class="catalog-toolbar">
      <div class="catalog-toolbar-left">
        {#if totalRecords > 0}
          <span class="catalog-result-count">
            {totalRecords} item{totalRecords === 1 ? "" : "s"}
          </span>
        {/if}
      </div>
      <div class="catalog-toolbar-right">
        <div class="catalog-search-bar">
          <svg
            class="catalog-search-icon"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
          >
            <circle cx="11" cy="11" r="8" />
            <path d="M21 21l-4.35-4.35" />
          </svg>
          <input
            type="text"
            placeholder="Search by name, part #, vendor…"
            bind:this={searchInputEl}
            bind:value={searchInput}
            on:input={handleSearch}
            on:keydown={handleKeydown}
          />
          {#if searchInput}
            <button
              class="catalog-search-clear"
              on:click={() => {
                searchInput = "";
                handleSearch();
              }}
              aria-label="Clear search"
            >
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                width="14"
                height="14"
              >
                <path d="M18 6L6 18M6 6l12 12" />
              </svg>
            </button>
          {/if}
        </div>

        <!-- Filter button -->
        <div class="catalog-filter-wrap">
          <button
            class="catalog-filter-btn"
            class:has-filters={activeFilterCount > 0}
            bind:this={filterBtnEl}
            on:click={toggleFilterPopover}
            aria-label="Filters"
            aria-expanded={filterOpen}
          >
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              width="15"
              height="15"
            >
              <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3" />
            </svg>
            Filters
            {#if activeFilterCount > 0}
              <span class="catalog-filter-badge">{activeFilterCount}</span>
            {/if}
          </button>

          {#if filterOpen}
            <div class="catalog-filter-popover" bind:this={filterPopoverEl}>
              <label class="catalog-filter-option">
                <input
                  type="checkbox"
                  checked={showInactive}
                  on:change={toggleInactive}
                />
                <span>Show inactive items</span>
              </label>
            </div>
          {/if}
        </div>
      </div>
    </div>

    <!-- Main content area: table + detail panel -->
    <div class="catalog-content">
      <!-- Table -->
      <div class="catalog-table-wrapper">
        {#if isSearching && !isUserTyping}
          <div class="catalog-loading-overlay">
            <div class="catalog-spinner"></div>
          </div>
        {/if}

        {#if items.length === 0}
          <div class="catalog-empty">
            <NoResultsMonkey
              message={searchInput
                ? "No catalog items match your search"
                : "No catalog items found"}
            />
          </div>
        {:else}
          <table class="catalog-table">
            <thead>
              <tr>
                <th class="col-name">Name</th>
                <th class="col-part">Part #</th>
                <th class="col-manufacturer">Manufacturer</th>
                <th class="col-vendor">Vendor</th>
                <th class="col-price">Price</th>
                <th class="col-cost">Cost</th>
                <th class="col-onhand">On Hand</th>
                <th class="col-status">Status</th>
                <th class="col-updated">Last Updated</th>
              </tr>
            </thead>
            <tbody>
              {#each items as item (item.id)}
                <tr
                  class="catalog-row"
                  class:inactive-row={item.inactive}
                  class:selected-row={selectedItem?.id === item.id}
                  on:click={() => selectItem(item)}
                >
                  <td class="col-name">
                    <div class="item-name-cell">
                      <span class="item-name">{item.name}</span>
                      {#if item.identifier}
                        <span class="item-desc mono">{item.identifier}</span>
                      {/if}
                    </div>
                  </td>
                  <td class="col-part">
                    <span class="mono">{item.partNumber || "—"}</span>
                  </td>
                  <td class="col-manufacturer">{item.manufacturer || "—"}</td>
                  <td class="col-vendor">
                    <div class="vendor-cell">
                      <span>{item.vendorName || "—"}</span>
                      {#if item.vendorSku}
                        <span class="vendor-sku mono">{item.vendorSku}</span>
                      {/if}
                    </div>
                  </td>
                  <td class="col-price">{formatCurrency(item.price)}</td>
                  <td class="col-cost">{formatCurrency(item.cost)}</td>
                  <td class="col-onhand">
                    <InventoryPopover identifier={item.id} onHand={item.onHand} />
                  </td>
                  <td class="col-status">
                    <span
                      class="status-badge"
                      class:status-active={!item.inactive}
                      class:status-inactive={item.inactive}
                    >
                      {item.inactive ? "Inactive" : "Active"}
                    </span>
                  </td>
                  <td class="col-updated"
                    >{formatDate(item.cwLastUpdated || item.updatedAt)}</td
                  >
                </tr>
              {/each}
            </tbody>
          </table>
        {/if}
      </div>

      <!-- Detail panel -->
      {#if selectedItem}
        <div
          class="detail-panel"
          aria-label="Item details"
          transition:fly={{ x: 380, duration: 200, opacity: 1 }}
        >
          <!-- Panel header -->
          <div class="detail-panel-header">
            <div class="detail-panel-title-wrap">
              <h3 class="detail-panel-title">{selectedItem.name}</h3>
              {#if selectedItem.identifier}
                <span class="detail-panel-identifier mono"
                  >{selectedItem.identifier}</span
                >
              {/if}
            </div>
            <button
              class="detail-panel-close"
              on:click={closePanel}
              aria-label="Close detail panel"
            >
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                width="18"
                height="18"
              >
                <path d="M18 6L6 18M6 6l12 12" />
              </svg>
            </button>
          </div>

          <!-- Panel body -->
          <div class="detail-panel-body">
            <!-- Status + Pricing -->
            <div class="detail-section">
              <div class="detail-status-row">
                <span
                  class="status-badge"
                  class:status-active={!selectedItem.inactive}
                  class:status-inactive={selectedItem.inactive}
                >
                  {selectedItem.inactive ? "Inactive" : "Active"}
                </span>
                {#if selectedItem.salesTaxable}
                  <span class="detail-tag">Taxable</span>
                {/if}
              </div>
            </div>

            <div class="detail-section">
              <h4 class="detail-section-heading">
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  width="14"
                  height="14"
                >
                  <line x1="12" y1="1" x2="12" y2="23" />
                  <path d="M17 5H9.5a3.5 3.5 0 000 7h5a3.5 3.5 0 010 7H6" />
                </svg>
                Pricing
              </h4>
              <div class="detail-fields">
                <div class="detail-field">
                  <span class="detail-label">Price</span>
                  <span class="detail-value"
                    >{formatCurrency(selectedItem.price)}</span
                  >
                </div>
                <div class="detail-field">
                  <span class="detail-label">Cost</span>
                  <span class="detail-value"
                    >{formatCurrency(selectedItem.cost)}</span
                  >
                </div>
                <div class="detail-field">
                  <span class="detail-label">Margin</span>
                  <span class="detail-value"
                    >{computeMargin(
                      selectedItem.price,
                      selectedItem.cost,
                    )}</span
                  >
                </div>
                <div class="detail-field">
                  <span class="detail-label">On Hand</span>
                  <span class="detail-value">
                    <InventoryPopover identifier={selectedItem.id} onHand={selectedItem.onHand} />
                  </span>
                </div>
              </div>
            </div>

            <!-- Product details -->
            <div class="detail-section">
              <h4 class="detail-section-heading">
                <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="16" x2="12" y2="12" />
                  <line x1="12" y1="8" x2="12.01" y2="8" />
                </svg>
                Details
              </h4>
              <div class="detail-fields">
                {#if selectedItem.description}
                  <div class="detail-field detail-field-full">
                    <span class="detail-label">Description</span>
                    <span class="detail-value">{selectedItem.description}</span>
                  </div>
                {/if}
                {#if selectedItem.customerDescription}
                  <div class="detail-field detail-field-full">
                    <span class="detail-label">Customer Description</span>
                    <span class="detail-value"
                      >{selectedItem.customerDescription}</span
                    >
                  </div>
                {/if}
                <div class="detail-field">
                  <span class="detail-label">Part Number</span>
                  <span class="detail-value mono"
                    >{selectedItem.partNumber || "—"}</span
                  >
                </div>
                <div class="detail-field">
                  <span class="detail-label">Manufacturer</span>
                  <span class="detail-value"
                    >{selectedItem.manufacturer || "—"}</span
                  >
                </div>
              </div>
            </div>

            <!-- Vendor -->
            <div class="detail-section">
              <h4 class="detail-section-heading">
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  width="14"
                  height="14"
                >
                  <path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2" />
                  <circle cx="12" cy="7" r="4" />
                </svg>
                Vendor
              </h4>
              <div class="detail-fields">
                <div class="detail-field">
                  <span class="detail-label">Name</span>
                  <span class="detail-value"
                    >{selectedItem.vendorName || "—"}</span
                  >
                </div>
                <div class="detail-field">
                  <span class="detail-label">SKU</span>
                  <span class="detail-value mono"
                    >{selectedItem.vendorSku || "—"}</span
                  >
                </div>
              </div>
            </div>

            <!-- Internal -->
            {#if selectedItem.internalNotes}
              <div class="detail-section">
                <h4 class="detail-section-heading">
                  <svg
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                    width="14"
                    height="14"
                  >
                    <path
                      d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"
                    />
                    <polyline points="14 2 14 8 20 8" />
                    <line x1="16" y1="13" x2="8" y2="13" />
                    <line x1="16" y1="17" x2="8" y2="17" />
                    <polyline points="10 9 9 9 8 9" />
                  </svg>
                  Internal Notes
                </h4>
                <p class="detail-notes">{selectedItem.internalNotes}</p>
              </div>
            {/if}

            <!-- Linked Items -->
            <div class="detail-section">
              <div class="detail-section-heading-row">
                <h4 class="detail-section-heading">
                  <svg
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                    width="14"
                    height="14"
                  >
                    <path
                      d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"
                    />
                    <path
                      d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"
                    />
                  </svg>
                  Linked Items
                  {#if linkedItems.length > 0}
                    <span class="linked-count">{linkedItems.length}</span>
                  {/if}
                </h4>
                {#if canLink}
                  <button
                    class="linked-add-btn"
                    on:click={openLinkModal}
                    aria-label="Link an item"
                  >
                    <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>
                  </button>
                {/if}
              </div>

              {#if linkedError}
                <p class="linked-error">{linkedError}</p>
              {/if}

              {#if linkedLoading}
                <div class="linked-loading">
                  <div
                    class="catalog-spinner"
                    style="width:20px;height:20px;border-width:2px"
                  ></div>
                </div>
              {:else if linkedItems.length === 0}
                <p class="linked-empty">No linked items</p>
              {:else}
                <div class="linked-list">
                  {#each linkedItems as li (li.id)}
                    <div class="linked-item-wrap">
                      <button
                        class="linked-item"
                        class:linked-item-inactive={li.inactive}
                        class:linked-item-expanded={expandedLinkedId === li.id}
                        on:click={() => toggleLinkedExpand(li.id)}
                      >
                        <div class="linked-item-info">
                          <span class="linked-item-name">{li.name}</span>
                          {#if li.identifier}
                            <span class="linked-item-id mono"
                              >{li.identifier}</span
                            >
                          {/if}
                        </div>
                        <div class="linked-item-meta">
                          {#if li.price != null}
                            <span class="linked-item-price"
                              >{formatCurrency(li.price)}</span
                            >
                          {/if}
                          <svg
                            class="linked-chevron"
                            class:linked-chevron-open={expandedLinkedId ===
                              li.id}
                            viewBox="0 0 24 24"
                            fill="none"
                            stroke="currentColor"
                            stroke-width="2"
                            width="13"
                            height="13"
                          >
                            <path d="M6 9l6 6 6-6" />
                          </svg>
                        </div>
                      </button>
                      {#if expandedLinkedId === li.id}
                        <div
                          class="linked-detail"
                          transition:fly={{ y: -6, duration: 150 }}
                        >
                          <div class="linked-detail-fields">
                            <div class="linked-detail-field">
                              <span class="detail-label">Price</span>
                              <span class="detail-value"
                                >{formatCurrency(li.price)}</span
                              >
                            </div>
                            <div class="linked-detail-field">
                              <span class="detail-label">Cost</span>
                              <span class="detail-value"
                                >{formatCurrency(li.cost)}</span
                              >
                            </div>
                            <div class="linked-detail-field">
                              <span class="detail-label">Margin</span>
                              <span class="detail-value"
                                >{computeMargin(li.price, li.cost)}</span
                              >
                            </div>
                            <div class="linked-detail-field">
                              <span class="detail-label">On Hand</span>
                              <span class="detail-value">
                                <InventoryPopover identifier={li.id} onHand={li.onHand} />
                              </span>
                            </div>
                            <div class="linked-detail-field">
                              <span class="detail-label">Status</span>
                              <span class="detail-value">
                                <span
                                  class="status-badge"
                                  class:status-active={!li.inactive}
                                  class:status-inactive={li.inactive}
                                >
                                  {li.inactive ? "Inactive" : "Active"}
                                </span>
                              </span>
                            </div>
                            {#if li.description}
                              <div
                                class="linked-detail-field linked-detail-full"
                              >
                                <span class="detail-label">Description</span>
                                <span class="detail-value"
                                  >{li.description}</span
                                >
                              </div>
                            {/if}
                          </div>
                          {#if canLink}
                            <button
                              class="linked-unlink-btn-full"
                              on:click|stopPropagation={() =>
                                handleUnlink(li.id)}
                              disabled={unlinkingId === li.id}
                            >
                              {#if unlinkingId === li.id}
                                <div
                                  class="catalog-spinner"
                                  style="width:12px;height:12px;border-width:2px"
                                ></div>
                              {:else}
                                <svg
                                  viewBox="0 0 24 24"
                                  fill="none"
                                  stroke="currentColor"
                                  stroke-width="2"
                                  width="13"
                                  height="13"
                                >
                                  <path d="M18 6L6 18M6 6l12 12" />
                                </svg>
                                Unlink
                              {/if}
                            </button>
                          {/if}
                        </div>
                      {/if}
                    </div>
                  {/each}
                </div>
              {/if}
            </div>

            <!-- Metadata -->
            <div class="detail-section">
              <h4 class="detail-section-heading">
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  width="14"
                  height="14"
                >
                  <circle cx="12" cy="12" r="10" />
                  <polyline points="12 6 12 12 16 14" />
                </svg>
                Timestamps
              </h4>
              <div class="detail-fields">
                <div class="detail-field">
                  <span class="detail-label">CW Last Updated</span>
                  <span class="detail-value"
                    >{formatDate(selectedItem.cwLastUpdated)}</span
                  >
                </div>
                <div class="detail-field">
                  <span class="detail-label">Created</span>
                  <span class="detail-value"
                    >{formatDate(selectedItem.createdAt)}</span
                  >
                </div>
                <div class="detail-field">
                  <span class="detail-label">Updated</span>
                  <span class="detail-value"
                    >{formatDate(selectedItem.updatedAt)}</span
                  >
                </div>
                {#if selectedItem.cwCatalogId}
                  <div class="detail-field">
                    <span class="detail-label">CW Catalog ID</span>
                    <span class="detail-value mono"
                      >{selectedItem.cwCatalogId}</span
                    >
                  </div>
                {/if}
              </div>
            </div>
          </div>
        </div>
      {/if}

      <!-- Link search modal -->
      {#if linkModalOpen && selectedItem}
        <div
          class="link-modal-overlay"
          on:click={closeLinkModal}
          role="presentation"
        >
          <!-- svelte-ignore a11y_no_static_element_interactions a11y_click_events_have_key_events -->
          <div class="link-modal" on:click|stopPropagation>
            <div class="link-modal-header">
              <div class="link-modal-header-text">
                <h4 class="link-modal-title">Link Item</h4>
                <span class="link-modal-context"
                  >Linking to <strong>{selectedItem.name}</strong></span
                >
              </div>
              <button
                class="detail-panel-close"
                on:click={closeLinkModal}
                aria-label="Close"
              >
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  width="16"
                  height="16"
                >
                  <path d="M18 6L6 18M6 6l12 12" />
                </svg>
              </button>
            </div>
            <div class="link-modal-body" class:has-preview={!!linkPreviewItem}>
              <div class="link-modal-pane">
                <div class="link-modal-search">
                  <svg
                    class="link-modal-search-icon"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                  >
                    <circle cx="11" cy="11" r="8" />
                    <path d="M21 21l-4.35-4.35" />
                  </svg>
                  <input
                    type="text"
                    placeholder="Search catalog items…"
                    bind:value={linkSearchQuery}
                    on:input={handleLinkSearch}
                  />
                </div>
                <div class="link-modal-results">
                  <div class="link-modal-section">
                    <span class="link-modal-section-title">Linked Items</span>
                    {#if linkedLoading}
                      <div class="linked-loading">
                        <div
                          class="catalog-spinner"
                          style="width:20px;height:20px;border-width:2px"
                        ></div>
                      </div>
                    {:else if linkedItems.length === 0}
                      <p class="linked-empty">No linked items yet</p>
                    {:else}
                      {#each linkedItems as li (li.id)}
                        <div
                          class="link-result-row"
                          class:link-result-inactive={li.inactive}
                          class:link-result-selected={linkPreviewItem?.id ===
                            li.id}
                          class:link-result-pending={stagedRemovals.has(li.id)}
                          on:click={() => setLinkPreview(li)}
                          on:keydown={(e) => handlePreviewKeydown(e, li)}
                          tabindex="0"
                          role="button"
                        >
                          <div class="link-result-info">
                            <span class="link-result-name">{li.name}</span>
                            {#if li.identifier}
                              <span class="link-result-id mono"
                                >{li.identifier}</span
                              >
                            {/if}
                          </div>
                          <button
                            class="link-action-btn link-action-remove"
                            class:link-action-active={stagedRemovals.has(li.id)}
                            on:click|stopPropagation={() =>
                              toggleStageRemove(li.id)}
                            disabled={commitLoading}
                            aria-label="Toggle remove {li.name}"
                          >
                            {#if stagedRemovals.has(li.id)}
                              <svg
                                viewBox="0 0 24 24"
                                fill="none"
                                stroke="currentColor"
                                stroke-width="2"
                                width="14"
                                height="14"
                              >
                                <path d="M20 6L9 17l-5-5" />
                              </svg>
                            {:else}
                              <svg
                                viewBox="0 0 24 24"
                                fill="none"
                                stroke="currentColor"
                                stroke-width="2"
                                width="14"
                                height="14"
                              >
                                <line x1="5" y1="12" x2="19" y2="12" />
                              </svg>
                            {/if}
                          </button>
                        </div>
                      {/each}
                    {/if}
                  </div>
                  <div class="link-modal-divider"></div>
                  <div class="link-modal-section">
                    <span class="link-modal-section-title">Search Results</span>
                    {#if linkSearchLoading}
                      <div class="linked-loading">
                        <div
                          class="catalog-spinner"
                          style="width:20px;height:20px;border-width:2px"
                        ></div>
                      </div>
                    {:else if linkSearchQuery && linkSearchResults.length === 0}
                      <p class="linked-empty">No items found</p>
                    {:else}
                      {#each linkSearchResults as result (result.id)}
                        <div
                          class="link-result-row"
                          class:link-result-inactive={result.inactive}
                          class:link-result-selected={linkPreviewItem?.id ===
                            result.id}
                          class:link-result-pending={stagedAdds.has(result.id)}
                          on:click={() => setLinkPreview(result)}
                          on:keydown={(e) => handlePreviewKeydown(e, result)}
                          tabindex="0"
                          role="button"
                        >
                          <div class="link-result-info">
                            <span class="link-result-name">{result.name}</span>
                            {#if result.identifier}
                              <span class="link-result-id mono"
                                >{result.identifier}</span
                              >
                            {/if}
                          </div>
                          <button
                            class="link-action-btn"
                            class:link-action-active={stagedAdds.has(result.id)}
                            on:click|stopPropagation={() =>
                              toggleStageAdd(result.id)}
                            disabled={commitLoading}
                            aria-label="Toggle add {result.name}"
                          >
                            {#if stagedAdds.has(result.id)}
                              <svg
                                viewBox="0 0 24 24"
                                fill="none"
                                stroke="currentColor"
                                stroke-width="2"
                                width="14"
                                height="14"
                              >
                                <path d="M20 6L9 17l-5-5" />
                              </svg>
                            {:else}
                              <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>
                            {/if}
                          </button>
                        </div>
                      {/each}
                    {/if}
                  </div>
                </div>
              </div>
              {#if linkPreviewItem}
                <div
                  class="link-modal-preview"
                  transition:fly={{ x: 20, duration: 150 }}
                >
                  <div class="link-preview-content">
                    <div class="link-preview-header">
                      <span class="link-preview-title">Preview</span>
                      {#if linkPreviewItem.identifier}
                        <span class="link-preview-id mono"
                          >{linkPreviewItem.identifier}</span
                        >
                      {/if}
                    </div>
                    <div class="link-preview-name">{linkPreviewItem.name}</div>
                    <div class="link-preview-fields">
                      <div class="link-preview-field">
                        <span class="detail-label">Price</span>
                        <span class="detail-value"
                          >{formatCurrency(linkPreviewItem.price)}</span
                        >
                      </div>
                      <div class="link-preview-field">
                        <span class="detail-label">Cost</span>
                        <span class="detail-value"
                          >{formatCurrency(linkPreviewItem.cost)}</span
                        >
                      </div>
                      <div class="link-preview-field">
                        <span class="detail-label">Margin</span>
                        <span class="detail-value">
                          {computeMargin(
                            linkPreviewItem.price,
                            linkPreviewItem.cost,
                          )}
                        </span>
                      </div>
                      <div class="link-preview-field">
                        <span class="detail-label">Status</span>
                        <span class="detail-value">
                          <span
                            class="status-badge"
                            class:status-active={!linkPreviewItem.inactive}
                            class:status-inactive={linkPreviewItem.inactive}
                          >
                            {linkPreviewItem.inactive ? "Inactive" : "Active"}
                          </span>
                        </span>
                      </div>
                      <div class="link-preview-field">
                        <span class="detail-label">On Hand</span>
                        <span class="detail-value">
                          <InventoryPopover identifier={linkPreviewItem.id} onHand={linkPreviewItem.onHand} />
                        </span>
                      </div>
                      {#if linkPreviewItem.manufacturer}
                        <div class="link-preview-field">
                          <span class="detail-label">Manufacturer</span>
                          <span class="detail-value"
                            >{linkPreviewItem.manufacturer}</span
                          >
                        </div>
                      {/if}
                      {#if linkPreviewItem.partNumber}
                        <div class="link-preview-field">
                          <span class="detail-label">Part #</span>
                          <span class="detail-value"
                            >{linkPreviewItem.partNumber}</span
                          >
                        </div>
                      {/if}
                      {#if linkPreviewItem.vendorName}
                        <div class="link-preview-field">
                          <span class="detail-label">Vendor</span>
                          <span class="detail-value"
                            >{linkPreviewItem.vendorName}</span
                          >
                        </div>
                      {/if}
                      {#if linkPreviewItem.vendorSku}
                        <div class="link-preview-field">
                          <span class="detail-label">Vendor SKU</span>
                          <span class="detail-value"
                            >{linkPreviewItem.vendorSku}</span
                          >
                        </div>
                      {/if}
                      {#if linkPreviewItem.description}
                        <div class="link-preview-field link-preview-full">
                          <span class="detail-label">Description</span>
                          <span class="detail-value"
                            >{linkPreviewItem.description}</span
                          >
                        </div>
                      {/if}
                    </div>
                  </div>
                </div>
              {/if}
            </div>
            <div class="link-modal-footer">
              {#if hasInactiveStaged}
                <div class="link-modal-warning">
                  <svg
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                    width="16"
                    height="16"
                  >
                    <path
                      d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"
                    />
                    <line x1="12" y1="9" x2="12" y2="13" />
                    <line x1="12" y1="17" x2="12.01" y2="17" />
                  </svg>
                  <span>Adding or removing inactive product(s)</span>
                </div>
              {/if}
              <div class="link-modal-summary">
                {#if stagedAdds.size || stagedRemovals.size}
                  <span>Adding {stagedAdds.size}</span>
                  <span class="link-modal-summary-divider">•</span>
                  <span>Removing {stagedRemovals.size}</span>
                {:else}
                  <span>No pending changes</span>
                {/if}
              </div>
              <button
                class="link-modal-commit"
                on:click={commitLinkChanges}
                disabled={commitLoading ||
                  (stagedAdds.size === 0 && stagedRemovals.size === 0)}
              >
                {#if commitLoading}
                  <div
                    class="catalog-spinner"
                    style="width:14px;height:14px;border-width:2px"
                  ></div>
                  Applying…
                {:else}
                  Apply changes
                {/if}
              </button>
            </div>
          </div>
        </div>
      {/if}
    </div>

    <!-- Pagination -->
    <div class="catalog-footer">
      <Pagination {currentPage} {totalPages} onNavigate={navigateToPage} />
    </div>
  </div>
{/if}
