<script lang="ts">
  import { scale } from 'svelte/transition';
  export type Mood = 'idle' | 'talking' | 'happy' | 'thinking' | 'moving';

  interface Props {
    x: number;
    y: number;
    mood?: Mood;
  }

  let { x = $bindable(0), y = $bindable(0), mood = 'idle' }: Props = $props();

  // ── Drag ─────────────────────────────────────────────────────────────
  let dragging = $state(false);
  let dragOffsetX = 0;
  let dragOffsetY = 0;

  function onPointerDown(e: PointerEvent) {
    if (e.button !== 0) return;
    dragging = true;
    dragOffsetX = e.clientX - x;
    dragOffsetY = e.clientY - y;
    (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
    e.preventDefault();
    e.stopPropagation();
  }

  function onPointerMove(e: PointerEvent) {
    if (!dragging) return;
    x = Math.max(Math.min(e.clientX - dragOffsetX, window.innerWidth - 45), 5);
    y = Math.max(Math.min(e.clientY - dragOffsetY, window.innerHeight - 75), 5);
  }

  function onPointerUp() {
    dragging = false;
  }

  const displayMood = $derived(dragging ? 'moving' : mood);

  let mouthOpen = $state(false);

  $effect(() => {
    if (displayMood !== 'talking') {
      mouthOpen = false;
      return;
    }
    const id = setInterval(() => {
      mouthOpen = !mouthOpen;
    }, 180);
    return () => clearInterval(id);
  });

  const MOUTH_DOWN =
    'M29.5 55L28 63L23 68.5L14 70.5L6.5 66L4 58.5L10.5 29L15 24H24L28 29.5L28.5 34L23 58L16.5 61.5L10.5 59.5L8.5 53.5';
  const MOUTH_UP =
    'M29.5 55L28 63L23 68.5L14 70.5L6.5 66L4 58.5L10.5 29L15 24H24L28 29.5L28.5 34L24 56.5L17.5 60L11.5 58L9.5 52';

  const bodyPath = $derived(
    (displayMood === 'talking' && mouthOpen) || displayMood === 'happy' ? MOUTH_DOWN : MOUTH_UP
  );

  // ── Cursor-tracking pupils ────────────────────────────────────────────
  // Avatar screen positions of each eye centre (SVG natural size 46×74)
  let cursorX = $state(-9999);
  let cursorY = $state(-9999);

  function onMouseMove(e: MouseEvent) {
    cursorX = e.clientX;
    cursorY = e.clientY;
  }

  export function flash(flashMood: Mood, duration = 500) {
    const prev = displayMood;
    mood = flashMood;
    setTimeout(() => (mood = prev), duration);
  }

  function pupilOffset(cx: number, cy: number, eyeSvgX: number, eyeSvgY: number, maxPx = 2.8) {
    const ex = x + eyeSvgX;
    const ey = y + eyeSvgY;
    const dx = cx - ex;
    const dy = cy - ey;
    const dist = Math.sqrt(dx * dx + dy * dy);
    if (dist < 1) return { px: 0, py: 0 };
    // Ramp up to full offset over 120px of distance
    const t = Math.min(dist, 120) / 120;
    return { px: (dx / dist) * maxPx * t, py: (dy / dist) * maxPx * t };
  }

  const left = $derived(
    displayMood === 'talking' ? { px: 0, py: 0 } : pupilOffset(cursorX, cursorY, 9.5, 30.5)
  );
  const right = $derived(
    displayMood === 'talking' ? { px: 0, py: 0 } : pupilOffset(cursorX, cursorY, 31.5, 35.5)
  );
</script>

<svelte:window onmousemove={onMouseMove} />

<div
  class="avatar"
  role="button"
  tabindex="0"
  in:scale={{ duration: 400, delay: 300 }}
  class:mood-idle={displayMood === 'idle'}
  class:mood-thinking={displayMood === 'thinking'}
  class:mood-talking={displayMood === 'talking'}
  class:mood-happy={displayMood === 'happy'}
  class:mood-moving={displayMood === 'moving'}
  class:dragging
  style:left="{x}px"
  style:top="{y}px"
  onpointerdown={onPointerDown}
  onpointermove={onPointerMove}
  onpointerup={onPointerUp}
>
  <svg
    width="46"
    height="74"
    viewBox="0 0 46 74"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
    overflow="visible"
  >
    <!--
			Leaf hinge points (transform-box: fill-box):
			  leave-right  →  origin 0% 100%   (bottom-left of bbox)
			  leave-left   →  origin 100% 100% (bottom-right of bbox)
		-->
    <g class="leave-right">
      <path
        d="M26.9781 16.5596L22.013 23.2368L22.8082 25.306L35.2985 25.3849L43.7783 20.6393L45.8723 14.8213L35.7374 14.0864L26.9781 16.5596Z"
        fill="#4F7B41"
      />
      <path
        d="M27 16.5L22.013 23.2368L22.8082 25.306L29 21L36.5 17L45.8723 14.8213L36 14L27 16.5Z"
        fill="#406634"
      />
    </g>

    <g class="leave-left">
      <path
        d="M11.3107 19.2204L17.7636 24.7215L20.3207 25.3703L22.8257 13.0024L19.0993 2.99176L12.5794 1.95314e-05L10.0997 9.77364L11.3107 19.2204Z"
        fill="#4F7B41"
      />
      <path
        d="M11.3107 19.2204L17.7636 24.7215L20.3207 25.3703L16 17L13.5 8L12.5794 1.95314e-05L10.0997 9.77364L11.3107 19.2204Z"
        fill="#5E8751"
      />
    </g>

    <path class="body" d={bodyPath} stroke="#4F7B41" stroke-width="3" />

    <!-- Left eye — pupils translated toward cursor -->
    <g class="eye-left">
      <circle cx="9.5" cy="30.5" r="9.5" fill="white" />
      <g transform="translate({left.px} {left.py})">
        <circle class="pupil" cx="9.5" cy="30.5" r="6.5" fill="black" />
        <circle cx="10.5" cy="27.5" r="2.5" fill="white" />
      </g>
    </g>

    <!-- Right eye — pupils translated toward cursor -->
    <g class="eye-right">
      <circle cx="31.5" cy="35.5" r="9.5" fill="white" />
      <g transform="translate({right.px} {right.py})">
        <circle class="pupil" cx="30.5" cy="34.5" r="6.5" fill="black" />
        <circle cx="30.5" cy="31.5" r="2.5" fill="white" />
      </g>
    </g>
  </svg>
</div>

<style>
  /* ── Wrapper ─────────────────────────────────────────────────────── */
  .avatar {
  	position: absolute;
  	cursor: grab;
  	user-select: none;
  	pointer-events: auto;
  	filter: drop-shadow(0px 0px 10px black);
  	transition:
  		left 0.85s cubic-bezier(0.33, 1, 0.68, 1),
  		top 0.85s cubic-bezier(0.33, 1, 0.68, 1);
  }

  .dragging {
  	cursor: grabbing;
  	transition: none;
  }

  /* idle: steady vertical bob */
  @keyframes bob {
  	0%,
  	100% {
  		transform: translateY(0);
  	}
  	50% {
  		transform: translateY(-5px);
  	}
  }
  .mood-idle {
  	animation: bob 2.6s ease-in-out infinite;
  }
  .mood-happy {
  	animation: bob 1.8s ease-in-out infinite;
  }

  /* thinking: head tilted to the side — clearly different from idle */
  @keyframes think {
  	0%,
  	100% {
  		transform: rotate(-12deg) translateY(0);
  	}
  	50% {
  		transform: rotate(-12deg) translateY(-3px);
  	}
  }
  .mood-thinking {
  	animation: think 2.8s ease-in-out infinite;
  }

  /* talking: subtle head waggle */
  @keyframes waggle {
  	0%,
  	100% {
  		transform: rotate(0deg);
  	}
  	25% {
  		transform: rotate(-2deg) translateY(-1px);
  	}
  	75% {
  		transform: rotate(2deg) translateY(1px);
  	}
  }
  .mood-talking {
  	animation: waggle 0.3s ease-in-out infinite;
  }

  /* moving: forward-lean glide */
  @keyframes glide {
  	0%,
  	100% {
  		transform: translateY(0) rotate(-6deg);
  	}
  	50% {
  		transform: translateY(-8px) rotate(-4deg);
  	}
  }
  .mood-moving {
  	animation: glide 0.4s ease-in-out infinite;
  }

  /* ── Drop shadows ────────────────────────────────────────────────── */
  .body {
  	filter: drop-shadow(1px 1px 0 rgba(0, 0, 0, 0.5));
  	transition: d 0.12s ease-in-out;
  }
  .eye-left,
  .eye-right {
  	filter: drop-shadow(1px 1px 0 rgba(0, 0, 0, 0.5));
  }

  .mood-talking {
  	.eye-left,
  	.eye-right {
  		> g {
  			transition: transform 0.5s ease-in-out;
  		}
  	}
  }

  /* ── Leaves ──────────────────────────────────────────────────────── */
  .leave-right {
  	transform-box: fill-box;
  	transform-origin: 0% 100%;
  }
  .leave-left {
  	transform-box: fill-box;
  	transform-origin: 100% 100%;
  }

  /* idle: slow gentle breathing wave */
  @keyframes idle-right {
  	0%,
  	100% {
  		transform: rotate(0deg);
  	}
  	50% {
  		transform: rotate(-9deg);
  	}
  }
  @keyframes idle-left {
  	0%,
  	100% {
  		transform: rotate(0deg);
  	}
  	50% {
  		transform: rotate(7deg);
  	}
  }
  .mood-idle .leave-right {
  	animation: idle-right 3s ease-in-out infinite;
  }
  .mood-idle .leave-left {
  	animation: idle-left 3s ease-in-out infinite 0.15s;
  }

  /* thinking: wings held raised, minimal drift */
  @keyframes think-right {
  	0%,
  	100% {
  		transform: rotate(-14deg);
  	}
  	50% {
  		transform: rotate(-10deg);
  	}
  }
  @keyframes think-left {
  	0%,
  	100% {
  		transform: rotate(10deg);
  	}
  	50% {
  		transform: rotate(7deg);
  	}
  }
  .mood-thinking .leave-right {
  	animation: think-right 4s ease-in-out infinite;
  }
  .mood-thinking .leave-left {
  	animation: think-left 4s ease-in-out infinite 0.3s;
  }

  /* talking: nearly still — tiny passive counter-sway */
  @keyframes talk-right {
  	0%,
  	100% {
  		transform: rotate(-2deg);
  	}
  	50% {
  		transform: rotate(2deg);
  	}
  }
  @keyframes talk-left {
  	0%,
  	100% {
  		transform: rotate(2deg);
  	}
  	50% {
  		transform: rotate(-2deg);
  	}
  }
  .mood-talking .leave-right {
  	animation: talk-right 0.6s ease-in-out infinite;
  }
  .mood-talking .leave-left {
  	animation: talk-left 0.6s ease-in-out infinite 0.1s;
  }

  /* happy: light casual flap */
  @keyframes happy-right {
  	0%,
  	100% {
  		transform: rotate(0deg);
  	}
  	50% {
  		transform: rotate(-18deg);
  	}
  }
  @keyframes happy-left {
  	0%,
  	100% {
  		transform: rotate(0deg);
  	}
  	50% {
  		transform: rotate(13deg);
  	}
  }
  .mood-happy .leave-right {
  	animation: happy-right 1.4s ease-in-out infinite;
  }
  .mood-happy .leave-left {
  	animation: happy-left 1.4s ease-in-out infinite 0.1s;
  }

  /* moving: vigorous wing flap — full range, fast */
  @keyframes flap-right {
  	0%,
  	100% {
  		transform: rotate(0deg);
  	}
  	40% {
  		transform: rotate(-40deg);
  	}
  }
  @keyframes flap-left {
  	0%,
  	100% {
  		transform: rotate(0deg);
  	}
  	40% {
  		transform: rotate(26deg);
  	}
  }
  .mood-moving .leave-right {
  	animation: flap-right 0.34s ease-in-out infinite;
  }
  .mood-moving .leave-left {
  	animation: flap-left 0.34s ease-in-out infinite 0.04s;
  }

  /* ── Eye blink (on pupil so it doesn't fight cursor translate) ───── */
  @keyframes blink {
  	0%,
  	93%,
  	100% {
  		transform: scaleY(1);
  	}
  	96% {
  		transform: scaleY(0.05);
  	}
  }
  .pupil {
  	transform-box: fill-box;
  	transform-origin: center;
  	animation: blink 4s ease-in-out infinite;
  }
  .eye-left .pupil {
  	animation-delay: 0s;
  }
  .eye-right .pupil {
  	animation-delay: 0.07s;
  }
</style>
