<script lang="ts">
  import type { Snippet } from 'svelte';
  import { onDestroy } from 'svelte';
  import { app } from '../lib/app.svelte';
  import { createTapConfirm } from '../lib/tapconfirm';

  // A two-tap confirmation control: the first tap on the trigger arms a ~durationMs
  // window during which a ✅ is shown (fading out, unless reduce-motion); a tap on the
  // ✅ within the window confirms. Replaces the press-and-hold and pop-up confirms.
  // onConfirming reports the window opening/closing so a parent can swap adjacent content
  // (e.g. a score for an "Add friend?" label). The click never bubbles, so the control can
  // sit inside another clickable surface (the score bar) without triggering it.
  let {
    onconfirm,
    durationMs = 2000,
    disabled = false,
    triggerClass = '',
    label,
    onConfirming,
    children,
  }: {
    onconfirm: () => void;
    durationMs?: number;
    disabled?: boolean;
    triggerClass?: string;
    /** Accessible label for the control (applied in both states). */
    label?: string;
    /** Notified whenever the confirming flag flips, so a parent can react. */
    onConfirming?: (confirming: boolean) => void;
    children: Snippet;
  } = $props();

  let confirming = $state(false);
  const ctl = createTapConfirm({
    get durationMs() {
      return durationMs;
    },
    onConfirm: () => onconfirm(),
    onChange: (c) => {
      confirming = c;
      onConfirming?.(c);
    },
  });
  onDestroy(() => ctl.dispose());

  // A control disabled mid-window (e.g. it became the opponent's turn) closes it.
  $effect(() => {
    if (disabled && confirming) ctl.cancel();
  });

  function onclick(e: MouseEvent) {
    e.stopPropagation();
    if (confirming) ctl.confirm();
    else if (!disabled) ctl.arm();
  }
</script>

<button class="tapconfirm {triggerClass}" class:confirming {disabled} aria-label={label} {onclick}>
  {#if confirming}
    <span class="sq ok" class:fade={!app.reduceMotion} style="--tc-ms: {durationMs}ms">✅</span>
  {:else}
    {@render children()}
  {/if}
</button>

<style>
  .tapconfirm {
    background: none;
    border: none;
    padding: 0;
    color: inherit;
    font: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    user-select: none;
    -webkit-user-select: none;
  }
  .tapconfirm:disabled {
    opacity: 0.4;
  }
  /* Outside the tab bar (where :global(.tab .sq) supplies the size) the confirm icon
     needs a size of its own: inherit the trigger's, so ✅ matches the idle icon. */
  .tapconfirm:not(.tab) .sq {
    display: inline-grid;
    place-items: center;
    font-size: 1em;
  }
  .ok.fade {
    animation: tc-fade var(--tc-ms) linear forwards;
  }
  @keyframes tc-fade {
    from {
      opacity: 1;
    }
    to {
      opacity: 0;
    }
  }
</style>
