'use client';
import { useEffect, useId, useRef, useState } from 'react';
import { RotateCcw, ArrowRight, Play, Pause } from 'lucide-react';
import { AdvancedType } from './advanced-type';
import { expandedType } from '@/lib/expanded-showcase';
import { Demo } from './demos';
export function TypeDemo({
  id,
  large = false,
}: {
  id: string;
  large?: boolean;
}) {
  const [value, setValue] = useState(
      id === 'type-weight' ? 600 : id === 'tracking' ? -2 : 70,
    ),
    [run, setRun] = useState(0),
    [text, setText] = useState('MAKE IT MEAN SOMETHING'),
    [number, setNumber] = useState(1280),
    [paused, setPaused] = useState(false);
  const layer = useRef<HTMLSpanElement>(null),
    timer = useRef<ReturnType<typeof setInterval> | undefined>(undefined),
    raf = useRef(0),
    uid = useId().replaceAll(':', '');
  useEffect(
    () => () => {
      clearInterval(timer.current);
      cancelAnimationFrame(raf.current);
    },
    [],
  );
  const replay = () => {
    setRun((r) => r + 1);
    clearInterval(timer.current);
    cancelAnimationFrame(raf.current);
    if (matchMedia('(prefers-reduced-motion:reduce)').matches) {
      setText('MAKE IT MEAN SOMETHING');
      setNumber(1280);
      return;
    }
    if (id === 'typewriter') {
      let n = 0;
      const full = 'MAKE IT MEAN SOMETHING';
      setText('');
      timer.current = setInterval(() => {
        n++;
        setText(full.slice(0, n));
        if (n >= full.length) clearInterval(timer.current);
      }, 55);
    }
    if (id === 'scramble') {
      let t = 0;
      const full = 'MAKE IT MEAN SOMETHING',
        chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
      timer.current = setInterval(() => {
        t++;
        setText(
          [...full]
            .map((c, i) =>
              c === ' '
                ? ' '
                : i < t / 2
                  ? c
                  : chars[(i * 7 + t * 3) % chars.length],
            )
            .join(''),
        );
        if (t > full.length * 2) clearInterval(timer.current);
      }, 28);
    }
    if (id === 'rolling-number') {
      const start = performance.now();
      const tick = (now: number) => {
        const p = Math.min(1, (now - start) / 1100);
        setNumber(Math.round(1280 * (1 - Math.pow(1 - p, 4))));
        if (p < 1) raf.current = requestAnimationFrame(tick);
      };
      raf.current = requestAnimationFrame(tick);
    }
  };
  if (id === 'type-reveal') return <Demo id="reveal" />;
  if (expandedType.some((t) => t.id === id))
    return <AdvancedType id={id} large={large} />;
  if (id === 'type-marquee') return <Demo id="marquee" />;
  return (
    <div className={`type-demo td-${id} ${large ? 'large' : ''}`}>
      {id === 'fluid-scale' && (
        <>
          <div className="fluid-frame" style={{ width: `${value}%` }}>
            <span>
              LESS,
              <br />
              BUT BETTER.
            </span>
          </div>
          <label className="type-demo-control">
            Ширина{' '}
            <input
              aria-label="Ширина контейнера"
              type="range"
              min="45"
              max="100"
              value={value}
              onChange={(e) => setValue(+e.target.value)}
            />
            <output>{value}%</output>
          </label>
        </>
      )}
      {id === 'type-weight' && (
        <>
          <div className="type-sample" style={{ fontWeight: value }}>
            Shape
            <br />
            the feeling.
          </div>
          <label className="type-demo-control">
            Вес{' '}
            <input
              aria-label="Насыщенность текста"
              type="range"
              min="400"
              max="800"
              step="100"
              value={value}
              onChange={(e) => setValue(+e.target.value)}
            />
            <output>{value}</output>
          </label>
        </>
      )}
      {id === 'tracking' && (
        <>
          <div
            className="type-sample"
            style={{ letterSpacing: `${value / 100}em` }}
          >
            SPACE
            <br />
            MATTERS.
          </div>
          <label className="type-demo-control">
            Трекинг{' '}
            <input
              aria-label="Межбуквенный интервал"
              type="range"
              min="-4"
              max="12"
              value={value}
              onChange={(e) => setValue(+e.target.value)}
            />
            <output>{value / 100}em</output>
          </label>
        </>
      )}
      {id === 'editorial-type' && (
        <div className="editorial-type-layout">
          <span>Notes on design</span>
          <p>
            The beauty
            <br />
            of{' '}
            <em>
              almost
              <br />
              nothing.
            </em>
          </p>
          <small>Ideas deserve room to breathe.</small>
        </div>
      )}
      {id === 'outline-type' && (
        <div className="outline-type-layout">
          <span>LESS</span>
          <strong>IS MORE.</strong>
          <span>OR LESS.</span>
        </div>
      )}
      {id === 'vertical-type' && (
        <div className="vertical-type-layout">
          <span>MAKE ROOM FOR</span>
          <strong>
            NEW
            <br />
            IDEAS.
          </strong>
          <small>Design in every direction.</small>
        </div>
      )}
      {id === 'text-path' && (
        <>
          <svg
            className={`circular-type ${paused ? 'paused' : ''}`}
            viewBox="0 0 240 240"
            role="img"
            aria-label="What goes around comes around"
          >
            <defs>
              <path
                id={uid}
                d="M120,120 m-82,0 a82,82 0 1,1 164,0 a82,82 0 1,1 -164,0"
              />
            </defs>
            <text>
              <textPath
                href={`#${uid}`}
                textLength="510"
                lengthAdjust="spacing"
              >
                WHAT GOES AROUND · COMES AROUND ·{' '}
              </textPath>
            </text>
            <circle cx="120" cy="120" r="28" />
          </svg>
          <button
            className="type-replay"
            onClick={() => setPaused(!paused)}
            aria-label={paused ? 'Продолжить' : 'Пауза'}
          >
            {paused ? <Play size={14} /> : <Pause size={14} />}
          </button>
        </>
      )}
      {(id === 'typewriter' || id === 'scramble') && (
        <>
          <div className="type-machine" aria-label="Make it mean something">
            <span aria-hidden="true">{text}</span>
            {id === 'typewriter' && <i />}
          </div>
          <button className="type-replay" onClick={replay}>
            <RotateCcw size={14} />
            Повторить
          </button>
        </>
      )}
      {id === 'rolling-number' && (
        <>
          <div className="rolling-type">
            <span>Made to measure.</span>
            <strong aria-label="1280">{number.toLocaleString('en-US')}</strong>
            <small>Tabular figures / ease out</small>
          </div>
          <button className="type-replay" onClick={replay}>
            <RotateCcw size={14} />
            Запустить
          </button>
        </>
      )}
      {id === 'type-spotlight' && (
        <div
          className="type-light"
          onPointerMove={(e) => {
            if (matchMedia('(prefers-reduced-motion:reduce)').matches) return;
            const b = e.currentTarget.getBoundingClientRect();
            if (layer.current)
              layer.current.style.clipPath = `circle(95px at ${e.clientX - b.left}px ${e.clientY - b.top}px)`;
          }}
        >
          <span>
            LOOK
            <br />
            CLOSER.
          </span>
          <span ref={layer} aria-hidden="true">
            LOOK
            <br />
            CLOSER.
          </span>
          <small>Проведи курсором по тексту</small>
        </div>
      )}
      {id === 'type-blend' && (
        <>
          <div
            className={`blend-orbit ${paused ? 'paused' : ''}`}
            aria-hidden="true"
          />
          <div className="blend-type">
            A NEW
            <br />
            POINT
            <br />
            OF VIEW.
          </div>
          <button className="type-replay" onClick={() => setPaused(!paused)}>
            {paused ? <Play size={14} /> : <Pause size={14} />}Пауза
          </button>
        </>
      )}
    </div>
  );
}
