<script lang="ts">
  import { createEventDispatcher } from 'svelte';
  import type { Gradient } from '../types';
  import Tooltip from './Tooltip.svelte';

  export let gradient: Gradient;
  export let focusedMode: boolean = false;

  const dispatch = createEventDispatcher<{
    change: number;
    notes: string;
  }>();

  const scaleValues = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  const CENTER = 5;

  let showNotes = false;
  let notesText = gradient.notes || '';
  let scaleEl: HTMLDivElement;

  // Glyph shown in each cell, given the current value.
  // The track fills from the center (=) out to the chosen position (#),
  // so direction and distance from the middle read at a glance.
  type CellKind = 'empty' | 'center' | 'fill' | 'marker';

  function cellKind(cell: number, value: number | null): CellKind {
    if (value === null) return cell === CENTER ? 'center' : 'empty';
    if (cell === value) return 'marker';
    if (value > CENTER && cell >= CENTER && cell < value) return 'fill';
    if (value < CENTER && cell > value && cell <= CENTER) return 'fill';
    return 'empty';
  }

  function cellGlyph(kind: CellKind): string {
    switch (kind) {
      case 'marker': return '#';
      case 'fill': return '=';
      case 'center': return '+';
      default: return '-';
    }
  }

  function selectValue(value: number) {
    dispatch('change', value);
    // Keep focus on the scale so arrow keys continue to adjust the value
    scaleEl?.focus();
  }

  function handleNotApplicable() {
    dispatch('change', null);
  }

  function handleNotesSave() {
    dispatch('notes', notesText);
    showNotes = false;
  }

  function handleKeydown(event: KeyboardEvent) {
    const current = gradient.value;
    let next: number | null = null;

    if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {
      next = current === null ? CENTER : Math.max(1, current - 1);
    } else if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {
      next = current === null ? CENTER : Math.min(9, current + 1);
    } else if (event.key === 'Home') {
      next = 1;
    } else if (event.key === 'End') {
      next = 9;
    } else {
      return;
    }

    // Handle the key here and keep it from bubbling to the app-level
    // screen navigation (which also listens for arrow keys).
    event.preventDefault();
    event.stopPropagation();
    dispatch('change', next);
  }
</script>

<div class="gradient-container">
  <div class="gradient-row" class:focused={focusedMode}>
    {#if !focusedMode}
      <div class="term left">
        <Tooltip text={gradient.term_left_description}>
          {gradient.term_left}
        </Tooltip>
      </div>
    {/if}

    <div class="bar-container">
      <div
        class="scale"
        bind:this={scaleEl}
        role="slider"
        tabindex="0"
        aria-label="Gradient scale between {gradient.term_left} and {gradient.term_right}"
        aria-valuemin="1"
        aria-valuemax="9"
        aria-valuenow={gradient.value}
        aria-valuetext={gradient.value === null ? 'Not set' : String(gradient.value)}
        on:keydown={handleKeydown}
      >
        <span class="bracket" aria-hidden="true">[</span>
        {#each scaleValues as n}
          {@const kind = cellKind(n, gradient.value)}
          <button
            type="button"
            class="cell {kind}"
            tabindex="-1"
            aria-label="Set value {n}"
            aria-pressed={gradient.value === n}
            title="{n}"
            on:click={() => selectValue(n)}
          >
            {cellGlyph(kind)}
          </button>
        {/each}
        <span class="bracket" aria-hidden="true">]</span>
      </div>
    </div>

    {#if !focusedMode}
      <div class="term right">
        <Tooltip text={gradient.term_right_description}>
          {gradient.term_right}
        </Tooltip>
      </div>
    {/if}
  </div>

  <div class="controls">
    <div class="button-row">
      <button
        class="na-btn"
        class:active={gradient.value === null}
        on:click={handleNotApplicable}
        aria-label="Mark as not applicable"
        title="Mark this gradient as not applicable"
      >
        N/A
      </button>
      <button
        class="notes-btn"
        class:has-notes={gradient.notes}
        on:click={() => showNotes = !showNotes}
        aria-label="Add notes"
      >
        {gradient.notes ? '📝' : '➕'} Notes
      </button>
    </div>
  </div>

  <div class="value-display">
    Value: {gradient.value !== null ? gradient.value : ''}
  </div>

  {#if showNotes}
    <div class="notes-editor">
      <textarea
        bind:value={notesText}
        placeholder="Add notes or reference..."
        rows="2"
      />
      <div class="notes-buttons">
        <button on:click={handleNotesSave}>Save</button>
        <button on:click={() => showNotes = false}>Cancel</button>
      </div>
    </div>
  {/if}
</div>

<style>
  .gradient-container {
    margin: 1rem 0;
    padding: 0.5rem;
  }

  .gradient-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1rem;
    margin-bottom: 0.5rem;
  }

  .gradient-row.focused {
    display: flex;
    justify-content: center;
  }

  .term {
    text-align: center;
    font-size: 0.9rem;
  }

  .term.left {
    text-align: right;
  }

  .term.right {
    text-align: left;
  }

  /* The bar is always centered within its container, on every screen size. */
  .bar-container {
    display: flex;
    justify-content: center;
  }

  .scale {
    display: inline-flex;
    align-items: stretch;
    font-family: 'Courier New', Courier, monospace;
    font-size: 1.8rem;
    line-height: 1;
    user-select: none;
    padding: 0.25rem 0.4rem;
    border: 2px solid transparent;
    border-radius: 3px;
  }

  .scale:focus-visible {
    outline: none;
    border-color: var(--hover-color);
  }

  .bracket {
    display: flex;
    align-items: center;
    opacity: 0.45;
  }

  .cell {
    font-family: inherit;
    font-size: inherit;
    line-height: 1;
    background: transparent;
    color: var(--fg-color);
    border: none;
    padding: 0.35rem 0.3rem;
    min-width: auto;
    min-height: auto;
    cursor: pointer;
    transition: opacity 0.15s, color 0.15s;
  }

  /* Opacity tiers reinforce the gradient feel: faint track, brighter
     fill, fully solid marker. */
  .cell.empty {
    opacity: 0.35;
  }

  .cell.center {
    opacity: 0.55;
  }

  .cell.fill {
    opacity: 0.75;
  }

  .cell.marker {
    opacity: 1;
    font-weight: bold;
  }

  .cell:hover {
    opacity: 1;
    color: var(--hover-color);
    background: transparent;
  }

  .value-display {
    text-align: center;
    margin-top: 0.75rem;
    font-size: 0.9rem;
    color: #888888;
  }

  .controls {
    margin-top: 0.5rem;
    display: flex;
    justify-content: center;
  }

  .button-row {
    display: flex;
    gap: 0.5rem;
    width: auto;
  }

  .na-btn {
    padding: 0.25rem 0.75rem;
    font-size: 0.85rem;
    opacity: 0.6;
    flex-shrink: 0;
    min-height: auto;
    width: auto;
  }

  .na-btn:hover {
    opacity: 1;
    background-color: transparent;
    color: var(--fg-color);
    border-color: var(--hover-color);
  }

  .na-btn.active {
    opacity: 1;
    background-color: var(--input-bg);
    border-color: var(--fg-color);
  }

  .notes-btn {
    padding: 0.25rem 0.75rem;
    font-size: 0.85rem;
    opacity: 0.6;
    min-height: auto;
    width: auto;
  }

  .notes-btn:hover {
    opacity: 1;
    background-color: transparent;
    color: var(--fg-color);
    border-color: var(--hover-color);
  }

  .notes-btn.has-notes {
    opacity: 1;
    border-color: var(--hover-color);
  }

  .notes-btn.has-notes:hover {
    background-color: transparent;
    color: var(--fg-color);
  }

  .notes-editor {
    margin-top: 0.5rem;
    padding: 0.5rem;
    border: 1px solid var(--border-color);
  }

  .notes-buttons {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
  }

  .notes-buttons button {
    flex: 1;
  }

  @media (max-width: 900px) {
    .gradient-row {
      grid-template-columns: 1fr;
      grid-template-rows: auto auto auto;
      gap: 0.5rem;
    }

    .term.left {
      text-align: left;
      grid-row: 1;
    }

    .bar-container {
      grid-row: 2;
    }

    .term.right {
      text-align: right;
      grid-row: 3;
    }

    .scale {
      font-size: 1.5rem;
      padding: 0.25rem 0.2rem;
    }

    /* Slim horizontal padding keeps the full track inside narrow
       viewports; vertical padding preserves a tall tap target. */
    .cell {
      padding: 0.5rem 0.2rem;
    }
  }
</style>
