<script lang="ts">
  import { onMount, onDestroy } from 'svelte'
  import type { PickingDrill } from '../../drills'
  import { effectiveMeter, patternFromAccents } from '../../drills'
  import { MetronomeController } from '../../lib/audio/metronomeController.svelte'
  import * as storage from '../../lib/storage'
  import { router } from '../../router.svelte'
  import DrillLayout from '../common/DrillLayout.svelte'
  import Transport from '../metronome/Transport.svelte'
  import PickingLane from '../patterns/PickingLane.svelte'
  import ChordDiagram from '../diagrams/ChordDiagram.svelte'
  import { getChordShape } from '../../lib/music/chords'

  interface Props {
    drill: PickingDrill
    params: URLSearchParams
  }

  let { drill, params }: Props = $props()

  function initialBpm(): number {
    const q = Number(params.get('bpm'))
    if (Number.isFinite(q) && q > 0) return q
    return storage.getDrillBpm(drill.code, drill.defaultBpm)
  }
  function initialVariantId(): string {
    const q = params.get('variant')
    if (q && drill.variants.some((v) => v.id === q)) return q
    const stored = storage.getDrillVariant(drill.code, drill.variants[0].id)
    return drill.variants.some((v) => v.id === stored) ? stored : drill.variants[0].id
  }

  const controller = new MetronomeController(initialBpm())
  let variantId = $state(initialVariantId())
  let variant = $derived(
    drill.variants.find((v) => v.id === variantId) ?? drill.variants[0],
  )
  let meter = $derived(effectiveMeter(drill, variant))

  $effect(() => {
    controller.setPattern(patternFromAccents(meter, variant.accentSteps))
  })

  function persistBpm(bpm: number) {
    storage.setDrillBpm(drill.code, bpm)
  }
  function selectVariant(id: string) {
    variantId = id
    storage.setDrillVariant(drill.code, id)
    router.setQuery({ variant: id })
  }

  function onKey(e: KeyboardEvent) {
    const t = e.target as HTMLElement
    if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA')) return
    if (e.code === 'Space') {
      e.preventDefault()
      controller.toggle()
    } else if (e.key === 'ArrowUp') {
      e.preventDefault()
      controller.nudgeBpm(2)
      persistBpm(controller.bpm)
    } else if (e.key === 'ArrowDown') {
      e.preventDefault()
      controller.nudgeBpm(-2)
      persistBpm(controller.bpm)
    }
  }

  onMount(() => window.addEventListener('keydown', onKey))
  onDestroy(() => {
    window.removeEventListener('keydown', onKey)
    controller.destroy()
  })
</script>

<DrillLayout
  code={drill.code}
  name={drill.name}
  category={drill.category}
  description={drill.description}
  meterLabel={meter.meterLabel}
>
  <Transport {controller} stepsPerBeat={meter.stepsPerBeat} onBpmCommit={persistBpm} />

  <PickingLane
    steps={variant.steps}
    stepsPerBeat={meter.stepsPerBeat}
    currentStep={controller.currentStep}
  />

  {#if drill.chordLabels && drill.chordLabels.length}
    <div class="chords">
      <span class="eyebrow">Chords{drill.chordLabels.length > 1 ? ' (one per bar)' : ''}</span>
      <div class="chip-row">
        {#each drill.chordLabels as c}
          {@const shape = getChordShape(c)}
          {#if shape}
            <ChordDiagram {shape} label={c} size={96} />
          {:else}
            <span class="chord num">{c}</span>
          {/if}
        {/each}
      </div>
    </div>
  {/if}

  {#if drill.variants.length > 1}
    <div class="variants">
      <span class="eyebrow">Variant</span>
      <div class="chips">
        {#each drill.variants as v}
          <button class="chip" class:sel={v.id === variantId} onclick={() => selectVariant(v.id)}>
            {v.label}
          </button>
        {/each}
      </div>
    </div>
  {/if}
</DrillLayout>

<style>
  .chords,
  .variants {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    margin-bottom: 1.25rem;
  }
  .chip-row {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
  }
  .chord {
    padding: 0.4rem 0.7rem;
    background: var(--walnut);
    border: 1px solid var(--fretwire-dim);
    border-radius: var(--radius);
    color: var(--inlay);
    font-size: var(--step-2);
  }
  .chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
  }
  .chip {
    padding: 0.55rem 0.8rem;
    background: var(--walnut);
    border: 1px solid var(--fretwire-dim);
    border-radius: 999px;
    color: var(--inlay-dim);
    font-size: var(--step-0);
  }
  .chip:hover {
    border-color: var(--fretwire);
    color: var(--inlay);
  }
  .chip.sel {
    color: var(--tubeglow);
    border-color: var(--tubeglow-soft);
    background: color-mix(in srgb, var(--tubeglow) 10%, transparent);
  }
</style>
