<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="primary-button" href="/mixes/new">New Mix Worksheet</a>
</section>

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

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

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

<section class="table-card">
  <div class="section-heading">
    <div>
      <p class="eyebrow">Table View</p>
      <h3>Saved mixes</h3>
    </div>
    <span class="soft-pill">Open any mix to edit</span>
  </div>

  <div class="table-wrap">
    <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="table-item">
                <span class="row-badge">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={`status-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="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>
  h2,
  h3,
  p {
    margin: 0;
  }

  .eyebrow {
    color: #7f8e85;
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  .page-actions,
  .metric-row,
  .table-card {
    margin-bottom: 1.12rem;
  }

  .page-actions {
    display: flex;
    justify-content: flex-end;
  }

  .metric-card,
  .table-card {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 1.16rem;
    box-shadow: var(--shadow);
  }

  .page-intro,
  .table-card {
    padding: 1.08rem;
  }

  .page-intro,
  .section-heading,
  .intro-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.68rem;
  }

  .page-intro {
    align-items: end;
  }

  .page-intro h2 {
    margin: 0.3rem 0 0.4rem;
    font-size: clamp(1.56rem, 3vw, 2.02rem);
    font-weight: 700;
  }

  .page-intro p:last-child,
  .metric-card p,
  .table-item span:last-child {
    color: var(--muted);
  }

  .primary-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.82rem;
    padding: 0.74rem 0.9rem;
    font-weight: 600;
    color: #fff;
    background: var(--color-brand);
    box-shadow: none;
  }

  .metric-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.9rem;
  }

  .metric-card {
    padding: 1.04rem 1.08rem;
  }

  .metric-card span {
    display: block;
    color: var(--muted);
    font-size: 0.84rem;
  }

  .metric-card strong {
    display: block;
    margin: 0.48rem 0 0.26rem;
    font-size: 1.72rem;
    font-weight: 700;
  }

  .section-heading {
    align-items: flex-start;
    margin-bottom: 0.9rem;
  }

  .section-heading h3 {
    font-size: 1.02rem;
    font-weight: 700;
  }

  .soft-pill {
    padding: 0.42rem 0.72rem;
    border-radius: 999px;
    color: var(--green-deep);
    background: var(--green-soft);
    font-size: 0.82rem;
    font-weight: 600;
  }

  .table-wrap {
    overflow-x: auto;
  }

  table {
    width: 100%;
    min-width: 48rem;
    border-collapse: separate;
    border-spacing: 0 0.54rem;
  }

  th,
  td {
    padding: 0.88rem 0.92rem;
    text-align: left;
    white-space: nowrap;
  }

  th {
    color: var(--muted);
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }

  tbody td {
    background: var(--panel-soft);
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
  }

  tbody td:first-child {
    border-left: 1px solid var(--line);
    border-radius: 0.92rem 0 0 0.92rem;
  }

  tbody td:last-child {
    border-right: 1px solid var(--line);
    border-radius: 0 0.92rem 0.92rem 0;
  }

  .table-item {
    display: flex;
    align-items: center;
    gap: 0.74rem;
  }

  .table-item strong {
    display: block;
    font-size: 0.94rem;
  }

  .table-item span:last-child {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.8rem;
  }

  .row-badge {
    width: 2.04rem;
    height: 2.04rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border-radius: 0.72rem;
    color: #fff;
    background: var(--color-brand);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.05em;
  }

  .status-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.38rem 0.7rem;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: capitalize;
  }

  .status-pill.positive {
    color: var(--green-deep);
    background: var(--green-soft);
  }

  .status-pill.warning {
    color: #a9681d;
    background: #fff6e6;
  }

  .menu-cell {
    width: 1%;
  }

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

  .menu-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line-strong);
    border-radius: 0.76rem;
    padding: 0.6rem 0.74rem;
    color: #304038;
    background: #fff;
    font-weight: 600;
    cursor: pointer;
  }

  .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: 980px) {
    .metric-row {
      grid-template-columns: 1fr;
    }
  }

  @media (max-width: 760px) {
    .page-intro,
    .section-heading {
      flex-direction: column;
      align-items: flex-start;
    }

    .table-card {
      padding: 1rem;
    }

    table,
    thead,
    tbody,
    tr,
    td {
      display: block;
      width: 100%;
    }

    table {
      min-width: 0;
      border-spacing: 0;
    }

    thead {
      display: none;
    }

    tbody {
      display: grid;
      gap: 0.9rem;
    }

    tbody tr {
      padding: 0.3rem;
      border: 1px solid var(--line);
      border-radius: 1rem;
      background: var(--panel-soft);
    }

    tbody td {
      padding: 0.78rem 0.8rem;
      white-space: normal;
      border: none;
      border-radius: 0;
      background: transparent;
    }

    tbody td:first-child,
    tbody td:last-child {
      border: none;
      border-radius: 0;
    }

    tbody td + td {
      border-top: 1px solid var(--line);
    }

    tbody td::before {
      content: attr(data-label);
      display: block;
      margin-bottom: 0.35rem;
      color: var(--muted);
      font-size: 0.72rem;
      font-weight: 700;
      letter-spacing: 0.06em;
      text-transform: uppercase;
    }

    .menu-wrap,
    .menu-trigger {
      width: 100%;
    }

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