<script lang="ts">
  import type { FxOf } from "../fx";
  import { CELL } from "./geom";
  let { fx }: { fx: FxOf<"portal" | "portal-cell"> } = $props();
  const uid = $props.id();
</script>

{#if fx.kind === "portal"}
  {@const x1 = fx.side === "E" ? (fx.cell.x + 1) * CELL : fx.cell.x * CELL}
  {@const y1 = fx.side === "S" ? (fx.cell.y + 1) * CELL : fx.cell.y * CELL}
  {@const x2 = fx.side === "W" ? fx.cell.x * CELL : (fx.cell.x + 1) * CELL}
  {@const y2 = fx.side === "N" ? fx.cell.y * CELL : (fx.cell.y + 1) * CELL}
  <line {x1} {y1} {x2} {y2} class="curtain glow" />
  <line {x1} {y1} {x2} {y2} class="curtain" pathLength="100" />
{:else}
  <defs>
    <radialGradient id={`portal-void-${uid}`}>
      <stop offset="0" stop-color="#0d2430" stop-opacity="0.85" />
      <stop offset="0.6" stop-color="#12414a" stop-opacity="0.5" />
      <stop offset="1" stop-color="#9be3e0" stop-opacity="0.1" />
    </radialGradient>
  </defs>
  <rect x={fx.at.x * CELL + 5} y={fx.at.y * CELL + 5}
    width={CELL - 10} height={CELL - 10} rx="8"
    fill={`url(#portal-void-${uid})`} class="void"
    style={`transform-origin: ${fx.at.x * CELL + CELL / 2}px ${fx.at.y * CELL + CELL / 2}px`} />
  {@const vx = fx.at.x * CELL + CELL / 2}
  {@const vy = fx.at.y * CELL + CELL / 2}
  <g class="swirl" style={`transform-origin: ${vx}px ${vy}px`}>
    <path d={`M ${vx + 12} ${vy} A 12 12 0 0 1 ${vx - 6} ${vy + 10}`} class="arm" />
    <path d={`M ${vx - 12} ${vy} A 12 12 0 0 1 ${vx + 6} ${vy - 10}`} class="arm" />
    <path d={`M ${vx} ${vy + 7} A 7 7 0 0 1 ${vx - 6} ${vy - 4}`} class="arm faint" />
  </g>
  <rect x={fx.at.x * CELL + 3} y={fx.at.y * CELL + 3}
    width={CELL - 6} height={CELL - 6} rx="6" class="veil outer"
    style={`transform-origin: ${fx.at.x * CELL + CELL / 2}px ${fx.at.y * CELL + CELL / 2}px`} />
  <rect x={fx.at.x * CELL + 3} y={fx.at.y * CELL + 3}
    width={CELL - 6} height={CELL - 6} rx="6" class="veil inner"
    style={`transform-origin: ${fx.at.x * CELL + CELL / 2}px ${fx.at.y * CELL + CELL / 2}px`} />
{/if}

<style>
  /* The threshold opens, light ripples along it, and it pinches shut. */
  .curtain {
    stroke: #9be3e0;
    stroke-dasharray: 6 5;
    stroke-linecap: round;
    filter: drop-shadow(0 0 4px rgba(155, 227, 224, 0.9));
    animation: open-ripple-pinch 0.95s ease-in-out forwards;
  }
  .curtain.glow {
    stroke: rgba(180, 138, 224, 0.5);
    stroke-dasharray: none;
    filter: blur(2px);
    animation: glow-swell 0.95s ease-in-out forwards;
  }
  @keyframes open-ripple-pinch {
    0% { opacity: 0; stroke-width: 0.5; stroke-dashoffset: 0; }
    22% { opacity: 1; stroke-width: 6; }
    60% { stroke-width: 4.5; stroke-dashoffset: 22; }
    88% { opacity: 0.9; stroke-width: 1.5; stroke-dashoffset: 34; }
    100% { opacity: 0; stroke-width: 0.5; stroke-dashoffset: 38; }
  }
  @keyframes glow-swell {
    0% { opacity: 0; stroke-width: 2; }
    25% { opacity: 0.85; stroke-width: 14; }
    70% { opacity: 0.6; stroke-width: 9; }
    100% { opacity: 0; stroke-width: 2; }
  }
  /* Cell mouths: rings of energy collapse inward through the token. */
  .veil {
    fill: none;
    stroke: #9be3e0;
    stroke-dasharray: 7 5;
    filter: drop-shadow(0 0 4px rgba(155, 227, 224, 0.8));
  }
  .void { animation: void-open 0.9s ease-out forwards; }
  .arm {
    fill: none;
    stroke: rgba(155, 227, 224, 0.7);
    stroke-width: 1.8;
    stroke-linecap: round;
  }
  .arm.faint { stroke: rgba(180, 138, 224, 0.55); }
  .swirl { animation: swirl-turn 0.9s ease-in forwards; }
  @keyframes swirl-turn {
    0% { opacity: 0; transform: rotate(0deg) scale(1.1); }
    25% { opacity: 1; }
    100% { opacity: 0; transform: rotate(160deg) scale(0.4); }
  }
  .veil.outer { stroke-width: 2.5; animation: veil-in 0.9s ease-in forwards; }
  .veil.inner {
    stroke: rgba(180, 138, 224, 0.8);
    stroke-width: 2;
    animation: veil-in 0.9s ease-in 0.2s forwards;
    opacity: 0;
  }
  @keyframes void-open {
    0% { opacity: 0; transform: scale(0.4); }
    30% { opacity: 1; transform: scale(1); }
    75% { opacity: 0.9; transform: scale(0.92); }
    100% { opacity: 0; transform: scale(0.5); }
  }
  @keyframes veil-in {
    0% { opacity: 0; transform: scale(1.25); }
    25% { opacity: 1; }
    100% { opacity: 0; transform: scale(0.45); }
  }
</style>
