<script lang="ts">
  import { onMount, tick } from 'svelte';

  let { data } = $props();

  let activeMenuId = $state<number | null>(null);
  let activeMenuTrigger = $state<HTMLButtonElement | null>(null);
  let menuElement = $state<HTMLDivElement | null>(null);
  let menuStyle = $state('');

  function currency(value: number | null | undefined, digits = 2) {
    if (value === null || value === undefined) {
      return 'N/A';
    }

    return `$${value.toFixed(digits)}`;
  }

  const warningCount = $derived(data.mixes.reduce((sum, mix) => sum + mix.warnings.length, 0));
  const averageCost = $derived(
    data.mixes.length
      ? data.mixes.reduce((sum, mix) => sum + (mix.mix_cost_per_kg ?? 0), 0) / data.mixes.length
      : 0
  );
  const activeMix = $derived(data.mixes.find((mix) => mix.id === activeMenuId) ?? null);

  function closeMenu() {
    activeMenuId = null;
    activeMenuTrigger = null;
    menuStyle = '';
  }

  function positionMenu() {
    if (!activeMenuTrigger || !menuElement) {
      return;
    }

    const triggerRect = activeMenuTrigger.getBoundingClientRect();
    const menuRect = menuElement.getBoundingClientRect();
    const viewportPadding = 12;
    const menuGap = 8;

    let top = triggerRect.top - menuRect.height - menuGap;

    if (top < viewportPadding) {
      top = Math.min(window.innerHeight - viewportPadding - menuRect.height, triggerRect.bottom + menuGap);
    }

    let left = triggerRect.right - menuRect.width;
    left = Math.max(viewportPadding, Math.min(left, window.innerWidth - viewportPadding - menuRect.width));

    menuStyle = `top: ${Math.max(viewportPadding, top)}px; left: ${left}px;`;
  }

  async function toggleMenu(id: number, event: MouseEvent) {
    if (activeMenuId === id) {
      closeMenu();
      return;
    }

    activeMenuId = id;
    activeMenuTrigger = event.currentTarget instanceof HTMLButtonElement ? event.currentTarget : null;

    await tick();
    positionMenu();
  }

  function handlePointerDown(event: MouseEvent) {
    if (activeMenuId === null || !(event.target instanceof Node)) {
      return;
    }

    if (menuElement?.contains(event.target) || activeMenuTrigger?.contains(event.target)) {
      return;
    }

    closeMenu();
  }

  function handleKeydown(event: KeyboardEvent) {
    if (event.key === 'Escape') {
      closeMenu();
    }
  }

  function handleViewportChange() {
    if (activeMenuId !== null) {
      positionMenu();
    }
  }

  onMount(() => {
    window.addEventListener('scroll', handleViewportChange, true);
    window.addEventListener('resize', handleViewportChange);
    document.addEventListener('mousedown', handlePointerDown);
    document.addEventListener('keydown', handleKeydown);

    return () => {
      window.removeEventListener('scroll', handleViewportChange, true);
      window.removeEventListener('resize', handleViewportChange);
      document.removeEventListener('mousedown', handlePointerDown);
      document.removeEventListener('keydown', handleKeydown);
    };
  });
</script>

<section class="page-actions">
  <a class="ui-button primary" href="/mixes/new">New Mix Worksheet</a>
</section>

<section class="ui-metric-row module-section">
  <article class="ui-metric-card">
    <span>Total Mixes</span>
    <strong>{data.mixes.length}</strong>
    <p>Saved mix definitions</p>
  </article>

  <article class="ui-metric-card">
    <span>Average Cost / Kg</span>
    <strong>{currency(averageCost, 4)}</strong>
    <p>Across all saved mixes</p>
  </article>

  <article class="ui-metric-card">
    <span>Warnings</span>
    <strong>{warningCount}</strong>
    <p>Mixes needing review</p>
  </article>
</section>

<section class="ui-panel module-section">
  <div class="ui-section-heading">
    <div>
      <p class="ui-eyebrow">Table View</p>
      <h3>Saved mixes</h3>
    </div>
    <span class="ui-pill positive">Open any mix to edit</span>
  </div>

  <div class="ui-table-wrap">
    <table class="ui-table">
      <thead>
        <tr>
          <th>Mix</th>
          <th>Client</th>
          <th>Ingredients</th>
          <th>Total Kg</th>
          <th>Total Cost</th>
          <th>Cost / Kg</th>
          <th>Status</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        {#each data.mixes as mix}
          <tr>
            <td data-label="Mix">
              <div class="ui-table-identity">
                <span class="ui-row-mark">MX</span>
                <div>
                  <strong>{mix.name}</strong>
                  <span>v{mix.version ?? 1}</span>
                </div>
              </div>
            </td>
            <td data-label="Client">{mix.client_name}</td>
            <td data-label="Ingredients">{mix.ingredients.length}</td>
            <td data-label="Total Kg">{mix.total_mix_kg}</td>
            <td data-label="Total Cost">{currency(mix.total_mix_cost)}</td>
            <td data-label="Cost / Kg">{currency(mix.mix_cost_per_kg, 4)}</td>
            <td data-label="Status">
              <span class={`ui-pill ${mix.warnings.length ? 'warning' : 'positive'}`}>{mix.status}</span>
            </td>
            <td class="menu-cell" data-label="Actions">
              <div class="menu-wrap">
                <button
                  aria-expanded={activeMenuId === mix.id}
                  aria-haspopup="menu"
                  class="ui-button secondary menu-trigger"
                  type="button"
                  onclick={(event) => toggleMenu(mix.id, event)}
                >
                  Actions
                </button>
              </div>
            </td>
          </tr>
        {/each}
      </tbody>
    </table>
  </div>

  {#if activeMix}
    <div bind:this={menuElement} class="menu-panel" role="menu" style={menuStyle}>
      <a href={`/mixes/${activeMix.id}`} onclick={closeMenu}>Edit worksheet</a>
      <a href={`/mixes/${activeMix.id}`} onclick={closeMenu}>Open live cost view</a>
    </div>
  {/if}
</section>

<style>
  h3,
  p {
    margin: 0;
  }

  .module-section {
    margin-bottom: 1.12rem;
  }

  .page-actions {
    margin-bottom: 1.12rem;
    display: flex;
    justify-content: flex-end;
  }

  .menu-cell {
    width: 1%;
  }

  .menu-wrap {
    display: flex;
    justify-content: flex-end;
  }

  .menu-trigger {
    min-height: 2.25rem;
    padding: 0.52rem 0.72rem;
  }

  .menu-panel {
    position: fixed;
    z-index: 40;
    min-width: 10rem;
    width: min(14rem, calc(100vw - 1.5rem));
    display: grid;
    gap: 0.18rem;
    padding: 0.32rem;
    border: 1px solid var(--line);
    border-radius: 0.84rem;
    background: rgba(255, 255, 255, 0.98);
    box-shadow: none;
  }

  .menu-panel a {
    padding: 0.64rem 0.72rem;
    border-radius: 0.7rem;
  }

  .menu-panel a:hover {
    background: var(--panel-soft);
  }

  @media (max-width: 760px) {
    .menu-wrap,
    .menu-trigger {
      width: 100%;
    }

    .menu-trigger {
      justify-content: space-between;
    }
  }
</style>
