'use client';
import { useId, useRef, useState, type CSSProperties } from 'react';
import { RotateCcw, Play, Pause } from 'lucide-react';
import { useSpecimenActivity } from './specimen-activity';
export function AdvancedType({
  id,
  large = false,
}: {
  id: string;
  large?: boolean;
}) {
  const { root, active, playing, setPlaying } = useSpecimenActivity(),
    [run, setRun] = useState(0),
    [text, setText] = useState('MAKE WAVES'),
    [value, setValue] = useState(40),
    [word, setWord] = useState(0),
    [number, setNumber] = useState(2486),
    [progress, setProgress] = useState(0);
  const uid = useId().replaceAll(':', ''),
    letters = useRef<HTMLDivElement>(null);
  const chars = Array.from(text || 'MAKE WAVES');
  const wordText = ['something', 'a little', 'the future', 'it happen'][
    word % 4
  ];
  const shadow = Array.from(
    { length: 30 },
    (_, i) => `${((i + 1) * (value - 50)) / 50}px ${i + 1}px 0 #b1ab92`,
  ).join(',');
  return (
    <div
      ref={root}
      className={`advanced-type at-${id} ${active ? 'is-active' : ''} ${large ? 'large' : ''}`}
      style={
        { '--curve': value + 'px', '--progress': progress } as CSSProperties
      }
      onPointerMove={(e) => {
        if (!active) return;
        const b = e.currentTarget.getBoundingClientRect(),
          x = (e.clientX - b.left) / b.width,
          y = (e.clientY - b.top) / b.height;
        e.currentTarget.style.setProperty('--mx', String(x));
        e.currentTarget.style.setProperty('--my', String(y));
        if (id === 'elastic-type' && letters.current)
          [...letters.current.children].forEach((n) => {
            const el = n as HTMLElement,
              r = el.getBoundingClientRect(),
              d = Math.abs(e.clientX - r.left - r.width / 2);
            el.style.transform = `scaleY(${1 + 0.7 * Math.max(0, 1 - d / 90)})`;
          });
      }}
      onPointerLeave={() => {
        if (letters.current)
          [...letters.current.children].forEach(
            (n) => ((n as HTMLElement).style.transform = ''),
          );
      }}
    >
      <div className="advanced-type-stage" key={run}>
        {[
          'letter-rotate',
          'baseline-wave',
          'type-shutter',
          'type-bounce',
          'char-roll',
          'elastic-type',
        ].includes(id) && (
          <div
            ref={letters}
            tabIndex={id === 'char-roll' ? 0 : undefined}
            className="at-letters"
            aria-label={text}
          >
            {chars.map((c, i) => (
              <span
                aria-hidden="true"
                key={i}
                style={
                  {
                    '--i': i,
                    animationDelay: `${i * (id === 'baseline-wave' ? -90 : 35)}ms`,
                  } as CSSProperties
                }
              >
                <b>{c === ' ' ? '\u00a0' : c}</b>
                {id === 'char-roll' && <b>{c === ' ' ? '\u00a0' : c}</b>}
              </span>
            ))}
          </div>
        )}
        {[
          'blur-focus',
          'gradient-sweep',
          'image-type',
          'extruded-type',
          'long-shadow',
        ].includes(id) && (
          <div
            className="at-display"
            style={id === 'long-shadow' ? { textShadow: shadow } : undefined}
          >
            {text}
          </div>
        )}
        {[
          'outline-draw',
          'liquid-type',
          'ink-spread',
          'path-flow',
          'marker-highlight',
          'underline-sketch',
        ].includes(id) && (
          <svg
            className="at-svg"
            viewBox="0 0 420 240"
            role="img"
            aria-label={text}
          >
            <defs>
              <filter
                id={uid + '-liquid'}
                x="-15%"
                y="-30%"
                width="130%"
                height="160%"
              >
                <feTurbulence
                  type="fractalNoise"
                  baseFrequency=".013 .025"
                  numOctaves="2"
                  seed="5"
                  result="noise"
                >
                  {active && (
                    <animate
                      attributeName="baseFrequency"
                      values=".013 .025;.023 .01;.013 .025"
                      dur="7s"
                      repeatCount="indefinite"
                    />
                  )}
                </feTurbulence>
                <feDisplacementMap
                  in="SourceGraphic"
                  in2="noise"
                  scale={active ? 16 : 0}
                />
              </filter>
              <filter id={uid + '-ink'}>
                <feMorphology operator="dilate" radius="0">
                  {active && (
                    <animate
                      attributeName="radius"
                      values="3;0"
                      dur="1.3s"
                      fill="freeze"
                    />
                  )}
                </feMorphology>
              </filter>
              <path
                id={uid + '-path'}
                d={`M20 155 C120 ${155 - value * 2},300 ${155 + value},400 110`}
              />
            </defs>
            {id === 'path-flow' ? (
              <>
                <use
                  href={'#' + uid + '-path'}
                  fill="none"
                  stroke="#a4ad92"
                  strokeDasharray="3 5"
                />
                <text fontSize="28" fill="currentColor">
                  <textPath
                    href={'#' + uid + '-path'}
                    textLength="365"
                    lengthAdjust="spacing"
                  >
                    {text} · {text}
                  </textPath>
                </text>
              </>
            ) : (
              <>
                {['marker-highlight', 'underline-sketch'].includes(id) && (
                  <path
                    className="at-draw-path"
                    d={
                      id === 'marker-highlight'
                        ? 'M35 153 Q190 130 387 146'
                        : 'M25 160 Q200 133 396 157 Q240 170 280 181'
                    }
                    fill="none"
                    stroke={id === 'marker-highlight' ? '#d9ef82' : '#be5034'}
                    strokeWidth={id === 'marker-highlight' ? 25 : 3}
                    strokeLinecap="round"
                    pathLength="1"
                  />
                )}
                <text
                  x="210"
                  y="147"
                  textAnchor="middle"
                  textLength="365"
                  lengthAdjust="spacingAndGlyphs"
                  fontSize="63"
                  fontWeight="800"
                  fontFamily="Manrope"
                  className={id === 'outline-draw' ? 'at-stroke' : ''}
                  fill={id === 'outline-draw' ? 'none' : 'currentColor'}
                  filter={
                    id === 'liquid-type'
                      ? `url(#${uid}-liquid)`
                      : id === 'ink-spread'
                        ? `url(#${uid}-ink)`
                        : undefined
                  }
                >
                  {text}
                </text>
              </>
            )}
          </svg>
        )}
        {['chromatic-type', 'text-slices', 'outline-fill'].includes(id) && (
          <div className="at-layered" tabIndex={0} aria-label={text}>
            {[0, 1, 2].map((i) => (
              <span aria-hidden="true" key={i}>
                {text}
              </span>
            ))}
          </div>
        )}
        {id === 'kinetic-repeat' && (
          <div className="at-repeats" aria-label={text}>
            {Array.from({ length: 7 }, (_, i) => (
              <span
                aria-hidden="true"
                key={i}
                style={{ '--i': i } as CSSProperties}
              >
                {text}
              </span>
            ))}
          </div>
        )}
        {id === 'type-cylinder' && (
          <div className="at-cylinder" aria-label={text}>
            {Array.from({ length: 6 }, (_, i) => (
              <span
                key={i}
                aria-hidden="true"
                style={{ transform: `rotateX(${i * 60}deg) translateZ(65px)` }}
              >
                {text}
              </span>
            ))}
          </div>
        )}
        {id === 'word-rotator' && (
          <div className="at-rotator">
            Make{' '}
            <span>
              <b key={word}>{wordText}</b>
            </span>
            <button onClick={() => setWord((v) => v + 1)}>
              Сменить слово →
            </button>
          </div>
        )}
        {id === 'scroll-reading' && (
          <div
            className="at-reading-scroll"
            onScroll={(e) => {
              const el = e.currentTarget;
              setProgress(el.scrollTop / (el.scrollHeight - el.clientHeight));
            }}
            tabIndex={0}
          >
            <div>
              <p>
                {'The best ideas need a little room to breathe. Give every word its own moment and let the story unfold.'
                  .split(' ')
                  .map((w, i) => (
                    <span
                      key={i}
                      style={{
                        opacity: i < progress * 24 || !active ? 1 : 0.28,
                      }}
                    >
                      {w}{' '}
                    </span>
                  ))}
              </p>
            </div>
          </div>
        )}
        {id === 'split-flap' && (
          <div className="at-flap">
            <div aria-label={String(number)}>
              {String(number)
                .split('')
                .map((n, i) => (
                  <span key={i}>
                    <b key={number}>{n}</b>
                  </span>
                ))}
            </div>
            <button
              onClick={() => setNumber((n) => ((n + 1379) % 9000) + 1000)}
            >
              Следующее значение
            </button>
          </div>
        )}
        {id === 'text-zoom' && (
          <div className="at-tunnel" aria-label={text}>
            {Array.from({ length: 5 }, (_, i) => (
              <span
                key={i}
                aria-hidden="true"
                style={{ animationDelay: `${-i * 0.8}s` }}
              >
                {text}
              </span>
            ))}
          </div>
        )}
      </div>
      <div className="specimen-controls">
        {['path-flow', 'long-shadow'].includes(id) ? (
          <label>
            Форма
            <input
              type="range"
              min="0"
              max="100"
              value={value}
              onChange={(e) => setValue(+e.target.value)}
            />
          </label>
        ) : (
          <span>
            {['elastic-type', 'image-type', 'extruded-type'].includes(id)
              ? 'Двигай курсором'
              : id === 'scroll-reading'
                ? 'Прокрути внутри сцены'
                : [
                      'chromatic-type',
                      'char-roll',
                      'outline-fill',
                      'text-slices',
                    ].includes(id)
                  ? 'Наведи или выбери Tab'
                  : 'Живая типографика'}
          </span>
        )}
        <button onClick={() => setRun((v) => v + 1)} aria-label="Повторить">
          <RotateCcw size={13} />
        </button>
        <button
          onClick={() => setPlaying((v) => !v)}
          aria-label={playing ? 'Пауза' : 'Продолжить'}
        >
          {playing ? <Pause size={13} /> : <Play size={13} />}
        </button>
      </div>
      {large && (
        <label className="specimen-text-input">
          Свой текст
          <input
            value={text}
            maxLength={22}
            onChange={(e) => setText(e.target.value)}
          />
        </label>
      )}
    </div>
  );
}
