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

  export let identifier: string;
  export let onHand: number | undefined;

  // Warehouse IDs for the fixed locations
  // Murray = Andrus 301 (1) + Andrus-205C (26) + Andrus 205D (27)
  const MURRAY_IDS = new Set([1, 26, 27]);
  const UNION_CITY_ID = 6;
  const LONDON_ID = 30;

  type InventoryRow = {
    id: number;
    qtyOnHand: number;
    warehouseId: number | null;
    warehouseBinId: number;
    warehouse: { id: number; name: string } | null;
  };

  type Breakdown = {
    murray: number;
    unionCity: number;
    london: number;
    vehicles: number;
  };

  let visible = false;
  let loading = false;
  let breakdown: Breakdown | null = null;
  let fetchedFor: string | null = null;

  let anchorEl: HTMLElement;
  let popoverX = 0;
  let popoverY = 0;

  // Portal action — moves the node to document.body so it is never
  // clipped by a parent overflow or trapped inside a CSS transform context.
  function portal(node: HTMLElement) {
    document.body.appendChild(node);
    return {
      destroy() {
        node.parentNode?.removeChild(node);
      },
    };
  }

  function onhandClass(qty: number) {
    if (qty === 0) return "onhand-zero";
    if (qty <= 3) return "onhand-low";
    return "onhand-ok";
  }

  function computeBreakdown(rows: InventoryRow[]): Breakdown {
    const result: Breakdown = { murray: 0, unionCity: 0, london: 0, vehicles: 0 };
    for (const row of rows) {
      const wId = row.warehouseId;
      const wName = row.warehouse?.name ?? "";
      if (wId != null && MURRAY_IDS.has(wId)) {
        result.murray += row.qtyOnHand;
      } else if (wId === UNION_CITY_ID) {
        result.unionCity += row.qtyOnHand;
      } else if (wId === LONDON_ID) {
        result.london += row.qtyOnHand;
      } else if (/^\d+$/.test(wName)) {
        result.vehicles += row.qtyOnHand;
      }
    }
    return result;
  }

  async function load() {
    if (fetchedFor === identifier) return;
    loading = true;
    breakdown = null;
    try {
      const result = await clientFetch<{ data: InventoryRow[] }>(
        `/procurement/catalog/inventory?id=${encodeURIComponent(identifier)}`,
      );
      breakdown = computeBreakdown(result?.data ?? []);
      fetchedFor = identifier;
    } catch {
      breakdown = { murray: 0, unionCity: 0, london: 0, vehicles: 0 };
      fetchedFor = identifier;
    } finally {
      loading = false;
    }
  }

  function updatePosition() {
    if (!anchorEl) return;
    const rect = anchorEl.getBoundingClientRect();
    popoverX = rect.left + rect.width / 2;
    popoverY = rect.top - 6;
  }

  function handleMouseEnter() {
    updatePosition();
    visible = true;
    load();
  }

  function handleMouseLeave() {
    visible = false;
  }

  onDestroy(() => {
    visible = false;
  });
</script>

<div
  class="inv-popover-anchor"
  role="button"
  tabindex="0"
  bind:this={anchorEl}
  on:mouseenter={handleMouseEnter}
  on:mouseleave={handleMouseLeave}
  on:focusin={handleMouseEnter}
  on:focusout={handleMouseLeave}
>
  <span
    class="onhand-badge"
    class:onhand-zero={onHand === 0}
    class:onhand-low={onHand != null && onHand > 0 && onHand <= 3}
    class:onhand-ok={onHand != null && onHand > 3}
  >
    {onHand ?? "—"}
  </span>
</div>

{#if visible}
  <div
    use:portal
    class="inv-popover"
    role="tooltip"
    style="left:{popoverX}px; top:{popoverY}px;"
  >
    <div class="inv-popover-title">Inventory Breakdown</div>
    {#if loading}
      <div class="inv-popover-loading">
        <span class="inv-spinner" />
        Loading…
      </div>
    {:else if breakdown}
      <div class="inv-popover-rows">
        <div class="inv-popover-row">
          <span class="inv-location">Murray, KY</span>
          <span class="onhand-badge {onhandClass(breakdown.murray)}">{breakdown.murray}</span>
        </div>
        <div class="inv-popover-row">
          <span class="inv-location">Union City, TN</span>
          <span class="onhand-badge {onhandClass(breakdown.unionCity)}">{breakdown.unionCity}</span>
        </div>
        <div class="inv-popover-row">
          <span class="inv-location">London, KY</span>
          <span class="onhand-badge {onhandClass(breakdown.london)}">{breakdown.london}</span>
        </div>
        <div class="inv-popover-row">
          <span class="inv-location">Vehicles</span>
          <span class="onhand-badge {onhandClass(breakdown.vehicles)}">{breakdown.vehicles}</span>
        </div>
      </div>
    {/if}
  </div>
{/if}

<style>
  .inv-popover-anchor {
    position: relative;
    display: inline-block;
    cursor: default;
  }

  /* Badge styles — self-contained so component works outside catalog.css context */
  .onhand-badge {
    display: inline-block;
    min-width: 28px;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 12px;
    font-weight: 600;
    text-align: center;
  }

  .onhand-zero {
    background: var(--status-inactive-bg, #fee2e2);
    color: var(--status-inactive-color, #dc2626);
  }

  .onhand-low {
    background: var(--status-pending-bg, #fef3c7);
    color: var(--status-pending-color, #d97706);
  }

  .onhand-ok {
    background: var(--status-active-bg, #dcfce7);
    color: var(--status-active-color, #16a34a);
  }

  /*
   * Portalled to document.body — fixed to viewport, above everything.
   * Note: Svelte scoped styles won't apply to portalled nodes, so the
   * popover styles below use :global() to reach across the portal boundary.
   */

  :global(.inv-popover) {
    position: fixed;
    transform: translateX(-50%) translateY(-100%);
    z-index: 9999;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 8px;
    box-shadow: var(--card-hover-shadow, 0 8px 24px rgba(0, 0, 0, 0.15));
    padding: 10px 14px;
    min-width: 210px;
    white-space: nowrap;
    pointer-events: none;
    font-family: inherit;
  }

  :global(.inv-popover-title) {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-bottom: 8px;
  }

  :global(.inv-popover-loading) {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: var(--text-muted);
    padding: 4px 0;
  }

  :global(.inv-spinner) {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 2px solid var(--border-subtle);
    border-top-color: var(--text-secondary);
    border-radius: 50%;
    animation: inv-spin 0.6s linear infinite;
    flex-shrink: 0;
  }

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

  :global(.inv-popover-rows) {
    display: flex;
    flex-direction: column;
    gap: 6px;
  }

  :global(.inv-popover-row) {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }

  :global(.inv-location) {
    font-size: 12px;
    color: var(--text-primary);
    font-weight: 500;
  }
</style>
