<script lang="ts">
  import { ArrowUpDown, Download, Printer } from 'lucide-svelte';
  import { formatDate, formatNumber } from '$lib/format';
  import type { MixCalculatorPreview, MixCalculatorSession } from '$lib/types';

  let {
    preview,
    sessionNumber = null,
    onPrint = null,
    onDownloadPdf = null
  }: {
    preview: MixCalculatorPreview | MixCalculatorSession | null;
    sessionNumber?: string | null;
    onPrint?: (() => void) | null;
    onDownloadPdf?: (() => void) | null;
  } = $props();

  // ── Ingredient sorting ──────────────────────────────────────────
  // Default to heaviest ingredient first; clicking a header toggles direction
  // (or switches column). Required kg starts descending, the name ascending.
  type LineSortKey = 'raw_material_name' | 'required_kg';
  let sortKey = $state<LineSortKey>('required_kg');
  let sortDir = $state<'asc' | 'desc'>('desc');

  function toggleSort(key: LineSortKey) {
    if (sortKey === key) {
      sortDir = sortDir === 'asc' ? 'desc' : 'asc';
      return;
    }
    sortKey = key;
    sortDir = key === 'required_kg' ? 'desc' : 'asc';
  }

  function ariaSort(key: LineSortKey): 'ascending' | 'descending' | 'none' {
    if (sortKey !== key) return 'none';
    return sortDir === 'asc' ? 'ascending' : 'descending';
  }

  const sortedLines = $derived.by(() => {
    const dir = sortDir === 'asc' ? 1 : -1;
    return [...(preview?.lines ?? [])].sort((a, b) => {
      const result =
        sortKey === 'required_kg'
          ? (a.required_kg ?? 0) - (b.required_kg ?? 0)
          : a.raw_material_name.localeCompare(b.raw_material_name, undefined, { sensitivity: 'base' });
      return result * dir;
    });
  });
</script>

<article class="result-card">
  {#if sessionNumber}
    <div class="result-toolbar">
      <div class="session-chip">
        <span>Session</span>
        <strong>{sessionNumber}</strong>
      </div>
    </div>
  {/if}

  {#if preview}
    <div class="metric-row">
      <article class="metric-card">
        <span>Total kg</span>
        <strong>{formatNumber(preview.total_kg, 2)}</strong>
        <p>Scaled batch size</p>
      </article>
      <article class="metric-card">
        <span>Total bags</span>
        <strong>{formatNumber(preview.total_bags, 2)}</strong>
        <p>{preview.product_unit_of_measure}</p>
      </article>
      <article class="metric-card">
        <span>Prepared by</span>
        <strong>{preview.prepared_by_name}</strong>
        <p>{formatDate(preview.mix_date)}</p>
      </article>
    </div>

    {#if preview.warnings.length}
      <div class="warning-stack">
        {#each preview.warnings as warning}
          <p>{warning}</p>
        {/each}
      </div>
    {/if}

    <div class="summary-grid">
      <div>
        <span>Client</span>
        <strong>{preview.client_name}</strong>
      </div>
      <div>
        <span>Mix</span>
        <strong>{preview.product_name}</strong>
      </div>
      <div>
        <span>Formula source</span>
        <strong>{preview.mix_name}</strong>
      </div>
      <div>
        <span>Unit size</span>
        <strong>{formatNumber(preview.product_unit_size_kg, 2)}kg</strong>
      </div>
    </div>

    <div class="table-wrap">
      <table>
        <thead>
          <tr>
            <th aria-sort={ariaSort('raw_material_name')}>
              <button
                type="button"
                class="sort-head"
                class:active={sortKey === 'raw_material_name'}
                onclick={() => toggleSort('raw_material_name')}
              >
                <span>Raw material</span>
                <ArrowUpDown size={13} strokeWidth={2.1} aria-hidden="true" />
              </button>
            </th>
            <th aria-sort={ariaSort('required_kg')}>
              <button
                type="button"
                class="sort-head"
                class:active={sortKey === 'required_kg'}
                onclick={() => toggleSort('required_kg')}
              >
                <span>Required kg</span>
                <ArrowUpDown size={13} strokeWidth={2.1} aria-hidden="true" />
              </button>
            </th>
          </tr>
        </thead>
        <tbody>
          {#each sortedLines as line}
            <tr>
              <td data-label="Raw material">
                <strong>{line.raw_material_name}</strong>
              </td>
              <td data-label="Required kg">{formatNumber(line.required_kg, line.rounding_decimals ?? 2)}kg</td>
            </tr>
          {/each}
        </tbody>
      </table>
    </div>

    <div class="output-actions">
      <button class="primary-button" disabled={!onPrint} type="button" onclick={() => onPrint?.()}>
        <Printer size={18} strokeWidth={1.9} aria-hidden="true" />
        Print
      </button>
      <button class="secondary-button" disabled={!onDownloadPdf} type="button" onclick={() => onDownloadPdf?.()}>
        <Download size={18} strokeWidth={1.9} aria-hidden="true" />
        Download PDF
      </button>
    </div>
  {:else}
    <div class="empty-state">
      <div class="empty-shimmer-metrics">
        <div class="shimmer-metric"><div class="shimmer-line short"></div><div class="shimmer-line wide"></div></div>
        <div class="shimmer-metric"><div class="shimmer-line short"></div><div class="shimmer-line wide"></div></div>
        <div class="shimmer-metric"><div class="shimmer-line short"></div><div class="shimmer-line wide"></div></div>
      </div>
      <div class="empty-state-copy">
        <div class="empty-icon" aria-hidden="true">
          <span></span><span></span><span></span>
        </div>
        <strong>No calculation yet</strong>
        <span>Choose a client, mix, date, and batch size on the left, then click Calculate mix.</span>
      </div>
      <div class="empty-shimmer-rows">
        {#each [1,2,3,4,5] as _}
          <div class="shimmer-row">
            <div class="shimmer-line wide"></div>
            <div class="shimmer-line medium"></div>
          </div>
        {/each}
      </div>
    </div>
  {/if}
</article>

<style>
  p {
    margin: 0;
  }

  .metric-card p,
  .summary-grid span,
  .empty-state span {
    color: var(--color-text-muted);
  }

  .result-card,
  .metric-card {
    border: 1px solid var(--color-border);
    background: var(--color-bg-surface);
  }

  .result-card {
    padding: 1.2rem;
    border-radius: var(--radius-panel);
  }

  .metric-card {
    border-radius: var(--radius-row);
  }

  .result-toolbar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 1rem;
  }

  .session-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.4rem 0.78rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg-app);
  }

  .session-chip span {
    color: var(--color-text-muted);
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

  .metric-row,
  .summary-grid {
    display: grid;
    gap: 0.85rem;
  }

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

  .metric-card {
    padding: 1rem;
  }

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

  .metric-card strong {
    display: block;
    margin: 0.45rem 0 0.18rem;
    font-size: 1.45rem;
  }

  .warning-stack {
    display: grid;
    gap: 0.45rem;
    margin-top: 1rem;
    padding: 0.92rem;
    border: 1px solid color-mix(in srgb, var(--color-warning) 35%, transparent);
    border-radius: var(--radius-row);
    background: var(--color-warning-tint);
    color: var(--color-warning-text);
  }

  .summary-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-bottom: 1rem;
  }

  .summary-grid div {
    padding: 0.88rem 0.92rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-row);
    background: var(--color-bg-app);
  }

  .summary-grid span {
    display: block;
    margin-bottom: 0.2rem;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

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

  .output-actions {
    display: flex;
    justify-content: flex-start;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 1rem;
  }

  table {
    width: 100%;
    min-width: 30rem;
    border-collapse: collapse;
  }

  th,
  td {
    padding: 0.9rem 0.85rem;
    text-align: left;
    border-bottom: 1px solid var(--color-border);
  }

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

  /* Clickable header: inherits the th look, adds a sort affordance. */
  .sort-head {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    cursor: pointer;
    transition: color 140ms ease;
  }

  .sort-head :global(svg) {
    opacity: 0.45;
    transition: opacity 140ms ease;
  }

  .sort-head:hover,
  .sort-head.active {
    color: var(--color-text-primary);
  }

  .sort-head.active :global(svg) {
    opacity: 1;
  }

  .sort-head:focus-visible {
    outline: 3px solid color-mix(in srgb, var(--color-brand) 45%, transparent);
    outline-offset: 2px;
    border-radius: 0.3rem;
  }

  .primary-button,
  .secondary-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.78rem 0.96rem;
    border-radius: var(--radius-control);
    border: 1px solid var(--color-border);
    font-weight: 600;
    cursor: pointer;
    transition:
      background-color 160ms ease,
      border-color 160ms ease;
  }

  .primary-button {
    border: none;
    background: var(--color-brand);
    color: var(--color-on-brand);
  }

  .secondary-button {
    background: var(--color-bg-surface);
    color: var(--color-text-primary);
  }

  .primary-button:hover:not(:disabled) {
    background: var(--color-brand-hover);
  }

  .primary-button:active:not(:disabled) {
    background: var(--color-brand-hover);
  }

  .secondary-button:hover:not(:disabled) {
    border-color: var(--color-text-muted);
    background: var(--color-bg-app);
  }

  .primary-button:focus-visible,
  .secondary-button:focus-visible {
    outline: 3px solid color-mix(in srgb, var(--color-brand) 45%, transparent);
    outline-offset: 2px;
  }

  button:disabled {
    cursor: not-allowed;
    opacity: 0.65;
  }

  .empty-state {
    display: flex;
    flex-direction: column;
    gap: 0;
    border-radius: 1rem;
    overflow: hidden;
    border: 1px solid var(--color-border);
  }

  .empty-shimmer-metrics {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
    padding: 1rem;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg-app);
  }

  .shimmer-metric {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.85rem;
    border: 1px solid var(--color-border);
    border-radius: 0.85rem;
    background: var(--color-bg-surface);
  }

  .empty-state-copy {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 2rem 1.5rem;
    text-align: center;
    background: var(--color-bg-surface);
    border-bottom: 1px solid var(--color-border);
  }

  .empty-state-copy strong {
    font-size: 0.98rem;
    font-weight: 700;
    color: var(--color-text-primary);
  }

  .empty-state-copy span {
    max-width: 26rem;
    font-size: 0.84rem;
    line-height: 1.5;
  }

  .empty-icon {
    display: flex;
    align-items: flex-end;
    gap: 0.28rem;
    height: 2.2rem;
    margin-bottom: 0.35rem;
  }

  .empty-icon span {
    width: 0.38rem;
    border-radius: 999px 999px 0 0;
    background: var(--color-border);
    animation: bar-pulse 1.6s ease-in-out infinite;
  }

  .empty-icon span:nth-child(1) { height: 60%; animation-delay: 0s; }
  .empty-icon span:nth-child(2) { height: 100%; animation-delay: 0.2s; }
  .empty-icon span:nth-child(3) { height: 40%; animation-delay: 0.4s; }

  @keyframes bar-pulse {
    0%, 100% { opacity: 0.35; }
    50% { opacity: 1; }
  }

  .empty-shimmer-rows {
    display: flex;
    flex-direction: column;
    background: var(--color-bg-app);
  }

  .shimmer-row {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 1rem;
    align-items: center;
    padding: 0.78rem 1rem;
    border-bottom: 1px solid var(--color-border);
  }

  .shimmer-row:last-child {
    border-bottom: none;
  }

  .shimmer-line {
    height: 0.7rem;
    border-radius: 999px;
    background: linear-gradient(
      90deg,
      var(--color-border) 25%,
      color-mix(in srgb, var(--color-border) 45%, var(--color-bg-surface)) 50%,
      var(--color-border) 75%
    );
    background-size: 200% 100%;
    animation: shimmer 1.8s ease-in-out infinite;
  }

  .shimmer-line.short { width: 40%; }
  .shimmer-line.medium { width: 65%; }
  .shimmer-line.wide { width: 90%; }

  @keyframes shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
  }

  @media (max-width: 980px) {
    .metric-row {
      grid-template-columns: 1fr;
    }
  }

  @media (max-width: 720px) {
    .summary-grid {
      grid-template-columns: 1fr;
    }

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

    thead {
      display: none;
    }

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

    tbody tr {
      border: 1px solid var(--color-border);
      border-radius: 1rem;
      background: var(--color-bg-app);
      overflow: hidden;
    }

    tbody td {
      border-bottom: 1px solid var(--color-border);
    }

    tbody td:last-child {
      border-bottom: none;
    }

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