<script lang="ts">
  import { api } from '$lib/api';
  import type { EditorChangeEvent } from '$lib/types';
  import { Clock, History, X } from 'lucide-svelte';
  import { onMount } from 'svelte';

  let {
    entityType,
    entityId,
    title,
    subtitle = '',
    onClose
  }: {
    entityType: 'mix' | 'ingredient';
    entityId: number;
    title: string;
    subtitle?: string;
    onClose: () => void;
  } = $props();

  let events = $state<EditorChangeEvent[] | null>(null);
  let error = $state<string | null>(null);

  onMount(async () => {
    try {
      events =
        entityType === 'mix'
          ? await api.editorMixHistory(entityId)
          : await api.editorIngredientHistory(entityId);
    } catch (err) {
      error = err instanceof Error ? err.message : 'Unable to load history';
    }
  });

  const ACTION_LABELS: Record<string, string> = {
    created: 'Created',
    updated: 'Updated',
    formula_updated: 'Formula updated',
    ingredient_added: 'Ingredient added',
    ingredient_updated: 'Ingredient updated',
    ingredient_removed: 'Ingredient removed'
  };

  function actionLabel(action: string) {
    return ACTION_LABELS[action] ?? action.replace(/_/g, ' ');
  }

  function formatWhen(value: string) {
    // Stored as a naive UTC timestamp; treat it as UTC for display.
    const iso = value.endsWith('Z') || value.includes('+') ? value : `${value}Z`;
    const date = new Date(iso);
    if (Number.isNaN(date.getTime())) return value;
    return date.toLocaleString(undefined, {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    });
  }
</script>

<div class="history-backdrop" role="presentation" onclick={onClose}>
  <div
    class="history-modal"
    role="dialog"
    aria-modal="true"
    aria-label={`Change history for ${title}`}
    tabindex="-1"
    onclick={(event) => event.stopPropagation()}
    onkeydown={(event) => {
      if (event.key === 'Escape') onClose();
    }}
  >
    <header class="history-head">
      <div class="history-title">
        <span class="kicker"><History size={14} strokeWidth={2.2} /> Change history</span>
        <h3>{title}</h3>
        {#if subtitle}<p class="subtitle">{subtitle}</p>{/if}
      </div>
      <button class="icon-close" type="button" onclick={onClose} aria-label="Close history">
        <X size={18} strokeWidth={2.2} />
      </button>
    </header>

    <div class="history-body">
      {#if error}
        <p class="state error">{error}</p>
      {:else if events === null}
        <p class="state">Loading history…</p>
      {:else if events.length === 0}
        <div class="empty">
          <Clock size={22} strokeWidth={1.8} />
          <p>No changes recorded yet.</p>
          <span>Edits made from here on will appear in this list.</span>
        </div>
      {:else}
        <ol class="timeline">
          {#each events as event (event.id)}
            <li class="event">
              <div class="event-head">
                <span class="badge">{actionLabel(event.action)}</span>
                <time>{formatWhen(event.created_at)}</time>
              </div>
              <p class="summary">{event.summary}</p>
              {#if event.changes.length}
                <ul class="deltas">
                  {#each event.changes as delta}
                    <li>
                      <span class="delta-label">{delta.label}</span>
                      <span class="delta-values">
                        <span class="before">{delta.before ?? '—'}</span>
                        <span class="arrow" aria-hidden="true">→</span>
                        <span class="after">{delta.after ?? '—'}</span>
                      </span>
                    </li>
                  {/each}
                </ul>
              {/if}
              <p class="actor">by {event.actor_name}{#if event.actor_role} · {event.actor_role}{/if}</p>
            </li>
          {/each}
        </ol>
      {/if}
    </div>
  </div>
</div>

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

  .history-backdrop {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: grid;
    place-items: center;
    padding: 1rem;
    background: rgba(17, 24, 20, 0.52);
    backdrop-filter: blur(8px);
  }

  .history-modal {
    display: flex;
    flex-direction: column;
    width: min(620px, 100%);
    max-height: calc(100vh - 2rem);
    border: 1px solid var(--color-border);
    border-radius: 0.9rem;
    background: var(--color-bg-surface);
    overflow: hidden;
  }

  .history-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.1rem;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg-app);
  }

  .history-title {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
  }

  .kicker {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--color-text-muted);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
  }

  .history-title h3 {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--color-text-primary);
  }

  .subtitle {
    color: var(--color-text-secondary);
    font-size: 0.84rem;
  }

  .icon-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border: 1px solid var(--color-border);
    border-radius: 0.45rem;
    background: var(--color-bg-surface);
    color: var(--color-text-secondary);
    cursor: pointer;
  }

  .icon-close:hover {
    border-color: var(--color-text-muted);
    color: var(--color-text-primary);
  }

  .history-body {
    padding: 1rem 1.1rem 1.2rem;
    overflow-y: auto;
  }

  .state {
    padding: 1.5rem 0;
    text-align: center;
    color: var(--color-text-secondary);
    font-weight: 600;
  }

  .state.error {
    color: var(--color-error);
  }

  .empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    padding: 2rem 1rem;
    text-align: center;
    color: var(--color-text-secondary);
  }

  .empty p {
    font-weight: 650;
    color: var(--color-text-primary);
  }

  .empty span {
    font-size: 0.84rem;
  }

  .timeline {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .event {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.8rem 0.9rem;
    border: 1px solid var(--color-divider);
    border-radius: 0.6rem;
    background: var(--color-bg-app);
  }

  .event-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
  }

  .badge {
    display: inline-flex;
    align-items: center;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    background: var(--color-brand-tint);
    color: var(--color-brand);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }

  .event-head time {
    color: var(--color-text-muted);
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
  }

  .summary {
    color: var(--color-text-primary);
    font-size: 0.9rem;
    font-weight: 600;
  }

  .deltas {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin: 0.1rem 0 0;
    padding: 0.5rem 0.6rem;
    list-style: none;
    border-radius: 0.45rem;
    background: var(--color-bg-surface);
    border: 1px solid var(--color-divider);
  }

  .deltas li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
  }

  .delta-label {
    color: var(--color-text-secondary);
    font-size: 0.82rem;
    font-weight: 600;
  }

  .delta-values {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.82rem;
    font-variant-numeric: tabular-nums;
  }

  .before {
    color: var(--color-text-muted);
    text-decoration: line-through;
  }

  .arrow {
    color: var(--color-text-muted);
  }

  .after {
    color: var(--color-text-primary);
    font-weight: 700;
  }

  .actor {
    color: var(--color-text-muted);
    font-size: 0.78rem;
  }
</style>
