'use client';
import {
  useEffect,
  useLayoutEffect,
  useRef,
  useState,
  useId,
  type CSSProperties,
} from 'react';
import {
  ArrowLeft,
  ArrowRight,
  Plus,
  Check,
  X,
  RotateCcw,
  Pause,
  Play,
  Music,
  Image,
  Heart,
  Mail,
  Star,
} from 'lucide-react';
import { useSpecimenActivity } from './specimen-activity';
const labels = ['Explore', 'Collect', 'Create'];
export function AdvancedMotion({ id }: { id: string }) {
  const { root, active, playing, setPlaying } = useSpecimenActivity(),
    [open, setOpen] = useState(false),
    [tab, setTab] = useState(0),
    [run, setRun] = useState(0),
    [value, setValue] = useState(50),
    [order, setOrder] = useState([0, 1, 2, 3]),
    [toasts, setToasts] = useState(0),
    [progress, setProgress] = useState(0),
    [origin, setOrigin] = useState([4, 3]),
    [drag, setDrag] = useState(0),
    [slide, setSlide] = useState(0);
  const grid = useRef<HTMLDivElement>(null),
    rects = useRef<DOMRect[]>([]),
    pointer = useRef<{ x: number; start: number } | null>(null),
    uid = useId().replaceAll(':', ''),
    animations = useRef<Animation[]>([]);
  useLayoutEffect(() => {
    const children = grid.current?.querySelectorAll<HTMLElement>('[data-key]');
    if (!children || !rects.current.length || !active) return;
    animations.current.forEach((a) => a.cancel());
    children.forEach((node, i) => {
      const prev = rects.current[+node.dataset.key!],
        next = node.getBoundingClientRect();
      if (prev)
        animations.current.push(
          node.animate(
            [
              {
                transform: `translate(${prev.left - next.left}px,${prev.top - next.top}px)`,
              },
              { transform: 'translate(0,0)' },
            ],
            {
              duration: 550,
              delay: i * 35,
              easing: 'cubic-bezier(.22,1,.36,1)',
            },
          ),
        );
    });
  }, [order, active]);
  useEffect(() => () => animations.current.forEach((a) => a.cancel()), []);
  const reorder = () => {
    if (grid.current)
      grid.current
        .querySelectorAll<HTMLElement>('[data-key]')
        .forEach(
          (n) => (rects.current[+n.dataset.key!] = n.getBoundingClientRect()),
        );
    setOrder((v) => [v[2], v[0], v[3], v[1]]);
  };
  const slideNext = (direction = 1) => {
    setSlide((v) => (v + direction + 3) % 3);
    setDrag(0);
  };
  return (
    <div
      ref={root}
      className={`advanced-motion am-${id} ${active ? 'is-active' : ''} ${open ? 'is-open' : ''}`}
      style={{ '--progress': progress, '--value': value } as CSSProperties}
    >
      <div className="advanced-motion-stage" key={run}>
        {id === 'layout-tabs' && (
          <div className="am-tabs">
            <div role="tablist" aria-label="Разделы примера">
              <i style={{ transform: `translateX(${tab * 100}%)` }} />
              {labels.map((t, i) => (
                <button
                  role="tab"
                  aria-selected={tab === i}
                  aria-controls={uid + 'panel'}
                  tabIndex={tab === i ? 0 : -1}
                  id={uid + i}
                  key={t}
                  onClick={() => setTab(i)}
                  onKeyDown={(e) => {
                    if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
                      e.preventDefault();
                      const next = (i + (e.key === 'ArrowRight' ? 1 : 2)) % 3;
                      setTab(next);
                      document.getElementById(uid + next)?.focus();
                    }
                  }}
                >
                  {t}
                </button>
              ))}
            </div>
            <section
              id={uid + 'panel'}
              role="tabpanel"
              aria-labelledby={uid + tab}
            >
              <span>0{tab + 1}</span>
              <b key={tab}>
                {
                  [
                    'Find something new.',
                    'Keep what matters.',
                    'Make it your own.',
                  ][tab]
                }
              </b>
            </section>
          </div>
        )}
        {id === 'grid-reorder' && (
          <>
            <div className="am-reorder" ref={grid}>
              {order.map((n) => (
                <div key={n} data-key={n} className={'tile-' + n}>
                  <span>0{n + 1}</span>
                  <b>{['Aa', '↗', '◎', '&'][n]}</b>
                </div>
              ))}
            </div>
            <button className="am-action" onClick={reorder}>
              Переставить <RotateCcw size={14} />
            </button>
          </>
        )}
        {id === 'card-expand' && (
          <button
            className="am-expand"
            aria-expanded={open}
            onClick={() => setOpen((v) => !v)}
          >
            <span className="am-expand-art">◎</span>
            <b>A quieter place.</b>
            <span className="am-expand-copy">
              A collection of small moments, familiar objects and ideas worth
              keeping.
            </span>
            <span>{open ? 'Свернуть −' : 'Подробнее +'}</span>
          </button>
        )}
        {id === 'carousel-depth' && (
          <>
            <div className="am-depth">
              {[0, 1, 2].map((i) => {
                const p = ((i - slide + 3) % 3) - 1;
                return (
                  <div
                    key={i}
                    style={{
                      transform: `translateX(${p * 88}px) translateZ(${-Math.abs(p) * 70}px) rotateY(${-p * 23}deg) scale(${1 - Math.abs(p) * 0.12})`,
                      zIndex: 3 - Math.abs(p),
                    }}
                  >
                    <span>0{i + 1}</span>
                    <b>{['FORM', 'SPACE', 'OBJECT'][i]}</b>
                    <i />
                  </div>
                );
              })}
            </div>
            <div className="am-arrows">
              <button aria-label="Предыдущий" onClick={() => slideNext(-1)}>
                <ArrowLeft size={17} />
              </button>
              <span aria-live="polite">{slide + 1} / 3</span>
              <button aria-label="Следующий" onClick={() => slideNext()}>
                <ArrowRight size={17} />
              </button>
            </div>
          </>
        )}
        {id === 'accordion-spring' && (
          <div className="am-accordion">
            {labels.map((l, i) => (
              <div key={l}>
                <button
                  aria-expanded={tab === i && open}
                  onClick={() => {
                    setTab(i);
                    setOpen(tab === i ? !open : true);
                  }}
                >
                  {l}
                  <Plus size={16} />
                </button>
                <div
                  className={tab === i && open ? 'expanded' : ''}
                  aria-hidden={!(tab === i && open)}
                >
                  <p>
                    {
                      [
                        'A space for your next idea.',
                        'Gather references that tell a story.',
                        'Build something with a point of view.',
                      ][i]
                    }
                  </p>
                </div>
              </div>
            ))}
          </div>
        )}
        {id === 'toast-stack' && (
          <>
            <div className="am-toasts" aria-live="polite">
              {Array.from({ length: Math.min(3, toasts) }, (_, i) => (
                <div
                  key={toasts - i}
                  style={{
                    transform: `translateY(${-i * 13}px) scale(${1 - i * 0.05})`,
                    zIndex: 3 - i,
                  }}
                  aria-hidden={i !== 0}
                >
                  <Check size={20} />
                  <div>
                    <b>Изменения сохранены</b>
                    <p>Версия {toasts - i} доступна в проекте.</p>
                  </div>
                </div>
              ))}
            </div>
            <button
              className="am-action"
              onClick={() => setToasts((v) => v + 1)}
            >
              Сохранить версию <Plus size={14} />
            </button>
          </>
        )}
        {id === 'menu-curtain' && (
          <>
            <div className="am-curtain-strips" aria-hidden="true">
              {[0, 1, 2, 3, 4].map((i) => (
                <i key={i} style={{ transitionDelay: i * 45 + 'ms' }} />
              ))}
            </div>
            <div className="am-curtain-menu" aria-hidden={!open}>
              {['Selected work', 'The studio', 'Get in touch'].map((t) => (
                <span key={t}>{t} ↗</span>
              ))}
            </div>
            <button
              className="am-menu-toggle"
              aria-expanded={open}
              onClick={() => setOpen((v) => !v)}
            >
              {open ? 'Закрыть' : 'Открыть меню'}{' '}
              {open ? <X size={16} /> : <Plus size={16} />}
            </button>
          </>
        )}
        {id === 'menu-radial' && (
          <div className="am-radial">
            {[Music, Image, Heart, Mail, Star].map((Icon, i) => (
              <button
                key={i}
                disabled={!open}
                aria-label={
                  ['Музыка', 'Изображения', 'Избранное', 'Почта', 'Оценить'][i]
                }
                style={{
                  transform: `translate(${open ? Math.cos((i * Math.PI * 2) / 5 - Math.PI / 2) * 85 : 0}px,${open ? Math.sin((i * Math.PI * 2) / 5 - Math.PI / 2) * 85 : 0}px) scale(${open ? 1 : 0.3})`,
                  opacity: open ? 1 : 0,
                }}
                onClick={() => {
                  setTab(i);
                  setOpen(false);
                }}
              >
                <Icon size={20} />
              </button>
            ))}
            <button
              aria-expanded={open}
              className="am-radial-center"
              onClick={() => setOpen((v) => !v)}
            >
              <Plus size={24} />
            </button>
            <small>
              {['Музыка', 'Изображения', 'Избранное', 'Почта', 'Оценить'][tab]}
            </small>
          </div>
        )}
        {id === 'dock-magnify' && (
          <div
            className="am-dock"
            onPointerMove={(e) => {
              if (!active) return;
              for (const n of e.currentTarget.children) {
                const el = n as HTMLElement,
                  b = el.getBoundingClientRect(),
                  d = Math.abs(e.clientX - b.left - b.width / 2);
                el.style.setProperty('--lift', String(Math.max(0, 1 - d / 90)));
              }
            }}
            onPointerLeave={(e) =>
              [...e.currentTarget.children].forEach((n) =>
                (n as HTMLElement).style.setProperty('--lift', '0'),
              )
            }
          >
            {[Music, Image, Heart, Mail, Star].map((Icon, i) => (
              <button
                key={i}
                aria-label={
                  ['Музыка', 'Изображения', 'Избранное', 'Почта', 'Оценить'][i]
                }
                onClick={() => setTab(i)}
                aria-pressed={tab === i}
              >
                <Icon size={24} />
              </button>
            ))}
          </div>
        )}
        {id === 'drag-snap' && (
          <div className="am-snap">
            <div className="am-snap-track">
              <i />
              <i />
              <i />
              <button
                aria-label="Перетащить маркер"
                style={{ transform: `translateX(${drag}px)` }}
                onPointerDown={(e) => {
                  pointer.current = { x: e.clientX, start: drag };
                  e.currentTarget.setPointerCapture(e.pointerId);
                }}
                onPointerMove={(e) => {
                  if (pointer.current)
                    setDrag(
                      Math.max(
                        0,
                        Math.min(
                          200,
                          pointer.current.start + e.clientX - pointer.current.x,
                        ),
                      ),
                    );
                }}
                onPointerUp={() => {
                  setDrag(Math.round(drag / 100) * 100);
                  pointer.current = null;
                }}
                onPointerCancel={() => {
                  pointer.current = null;
                  setDrag(Math.round(drag / 100) * 100);
                }}
                onKeyDown={(e) => {
                  if (e.key.startsWith('Arrow')) {
                    e.preventDefault();
                    setDrag((v) =>
                      Math.max(
                        0,
                        Math.min(
                          200,
                          v + (e.key === 'ArrowRight' ? 100 : -100),
                        ),
                      ),
                    );
                  }
                }}
              >
                <span>↔</span>
              </button>
            </div>
            <p>Три точки фиксации / мышь или стрелки</p>
          </div>
        )}
        {id === 'swipe-deck' && (
          <>
            <div className="am-swipe-deck">
              <i />
              <i />
              <div
                style={{
                  transform: `translateX(${drag}px) rotate(${drag / 12}deg)`,
                }}
                onPointerDown={(e) => {
                  pointer.current = { x: e.clientX, start: 0 };
                  e.currentTarget.setPointerCapture(e.pointerId);
                }}
                onPointerMove={(e) => {
                  if (pointer.current)
                    setDrag(
                      Math.max(
                        -160,
                        Math.min(160, e.clientX - pointer.current.x),
                      ),
                    );
                }}
                onPointerUp={() => {
                  if (Math.abs(drag) > 70) slideNext();
                  else setDrag(0);
                  pointer.current = null;
                }}
                onPointerCancel={() => {
                  pointer.current = null;
                  setDrag(0);
                }}
              >
                <span>SELECTED IDEA / 0{slide + 1}</span>
                <b>{['Be curious.', 'Stay open.', 'Make room.'][slide]}</b>
                <small>← Пропустить / Сохранить →</small>
              </div>
            </div>
            <div className="am-arrows">
              <button
                aria-label="Пропустить карточку"
                onClick={() => slideNext(-1)}
              >
                <X size={18} />
              </button>
              <button
                aria-label="Сохранить карточку"
                onClick={() => slideNext()}
              >
                <Heart size={18} />
              </button>
            </div>
          </>
        )}
        {id === 'elastic-slider' && (
          <div className="am-elastic">
            <b>
              {value}
              <small>%</small>
            </b>
            <label>
              Intensity
              <input
                type="range"
                min="0"
                max="100"
                value={value}
                onChange={(e) => setValue(+e.target.value)}
              />
            </label>
            <div>
              <i
                style={{
                  transform: `scaleX(${0.2 + value / 100}) scaleY(${1.2 - value / 500})`,
                }}
              />
            </div>
          </div>
        )}
        {id === 'svg-route' && (
          <svg
            className="am-svg"
            viewBox="0 0 400 240"
            role="img"
            aria-label="Движение по кривой"
          >
            <path
              id={uid + '-route'}
              d="M30 160C30 20 200 15 210 90S370 235 375 70"
              fill="none"
              stroke="#98a789"
              strokeWidth="2"
              strokeDasharray="5 5"
            />
            <g>
              <path d="m-12-8 25 8-25 8 5-8Z" fill="#344a35" />
              {active ? (
                <animateMotion dur="4s" repeatCount="indefinite" rotate="auto">
                  <mpath href={'#' + uid + '-route'} />
                </animateMotion>
              ) : (
                <animateTransform
                  attributeName="transform"
                  type="translate"
                  to="210 90"
                  dur=".01s"
                  fill="freeze"
                />
              )}
            </g>
          </svg>
        )}
        {id === 'svg-morph' && (
          <>
            <svg
              className="am-svg"
              viewBox="0 0 400 240"
              aria-label="Морфинг восьмиугольника"
            >
              <polygon
                points={
                  open
                    ? '200,25 235,80 315,90 260,140 270,215 200,175 130,215 140,140'
                    : '200,35 265,60 295,120 265,180 200,205 135,180 105,120 135,60'
                }
                fill="#b0573c"
                className="am-morph-polygon"
              >
                {active && (
                  <animate
                    key={String(open)}
                    attributeName="points"
                    from={
                      open
                        ? '200,35 265,60 295,120 265,180 200,205 135,180 105,120 135,60'
                        : '200,25 235,80 315,90 260,140 270,215 200,175 130,215 140,140'
                    }
                    to={
                      open
                        ? '200,25 235,80 315,90 260,140 270,215 200,175 130,215 140,140'
                        : '200,35 265,60 295,120 265,180 200,205 135,180 105,120 135,60'
                    }
                    dur=".7s"
                    fill="freeze"
                  />
                )}
              </polygon>
            </svg>
            <button className="am-action" onClick={() => setOpen((v) => !v)}>
              Изменить контур <RotateCcw size={14} />
            </button>
          </>
        )}
        {id === 'gooey-menu' && (
          <>
            <svg width="0" height="0" aria-hidden="true">
              <defs>
                <filter id={uid + 'goo'}>
                  <feGaussianBlur
                    in="SourceGraphic"
                    stdDeviation="8"
                    result="blur"
                  />
                  <feColorMatrix
                    in="blur"
                    mode="matrix"
                    values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -8"
                  />
                </filter>
              </defs>
            </svg>
            <div
              className="am-goo"
              style={{ filter: `url(#${uid}goo)` }}
              aria-hidden="true"
            >
              {[-1, 0, 1].map((i) => (
                <i
                  key={i}
                  style={{ transform: `translateX(${open ? i * 65 : 0}px)` }}
                />
              ))}
            </div>
            <button
              className="am-goo-trigger"
              onClick={() => setOpen((v) => !v)}
              aria-expanded={open}
            >
              {open ? <X size={23} /> : <Plus size={23} />}
            </button>
          </>
        )}
        {id === 'particle-burst' && (
          <div className="am-burst">
            <div key={toasts}>
              {toasts > 0 &&
                Array.from({ length: 28 }, (_, i) => (
                  <i
                    key={i}
                    style={
                      {
                        '--dx': Math.cos(i * 2.399) * (55 + i * 2) + 'px',
                        '--dy': Math.sin(i * 2.399) * (55 + i * 2) + 'px',
                        '--spin': i * 33 + 'deg',
                        background: [
                          '#4f6147',
                          '#c67a48',
                          '#9faba0',
                          '#d8bd64',
                        ][i % 4],
                      } as CSSProperties
                    }
                  />
                ))}
            </div>
            <button onClick={() => setToasts((v) => v + 1)}>
              <Check size={24} />
            </button>
          </div>
        )}
        {['mesh-flow', 'aurora-flow'].includes(id) && (
          <div className="am-atmosphere">
            <i />
            <i />
            <i />
            <i />
            <span>
              {id === 'mesh-flow' ? 'COLOR IN MOTION' : 'AURORA / STUDY 02'}
            </span>
          </div>
        )}
        {id === 'grid-wave' && (
          <div className="am-wave-grid" key={toasts}>
            {Array.from({ length: 54 }, (_, i) => (
              <button
                key={i}
                aria-label={`Запустить волну из ячейки ${i + 1}`}
                onClick={() => {
                  setOrigin([i % 9, Math.floor(i / 9)]);
                  setToasts((v) => v + 1);
                }}
                style={{
                  animationDelay: `${Math.hypot((i % 9) - origin[0], Math.floor(i / 9) - origin[1]) * 45}ms`,
                }}
              />
            ))}
          </div>
        )}
        {['horizontal-story', 'scroll-zoom'].includes(id) && (
          <div
            className="am-scroll-container"
            tabIndex={0}
            onScroll={(e) => {
              const el = e.currentTarget;
              setProgress(el.scrollTop / (el.scrollHeight - el.clientHeight));
            }}
          >
            <div className="am-scroll-height">
              <div className="am-scroll-sticky">
                {id === 'horizontal-story' ? (
                  <div
                    className="am-horizontal-track"
                    style={{ transform: `translateX(${-progress * 66.6667}%)` }}
                  >
                    {['A NEW', 'POINT', 'OF VIEW'].map((t, i) => (
                      <div key={t}>
                        <span>CHAPTER 0{i + 1}</span>
                        <b>{t}</b>
                        <i />
                      </div>
                    ))}
                  </div>
                ) : (
                  <div
                    className="am-zoom-object"
                    style={{
                      transform: active
                        ? `scale(${0.65 + progress}) rotate(${-12 + progress * 24}deg)`
                        : 'none',
                    }}
                  >
                    <span>LOOK</span>
                    <b>CLOSER</b>
                    <i>◎</i>
                  </div>
                )}
              </div>
            </div>
          </div>
        )}
        {id === 'image-curtain' && (
          <div className="am-image-curtain">
            {[0, 1, 2, 3, 4, 5].map((i) => (
              <i
                key={i}
                style={{
                  backgroundPosition: `${i * 20}% center`,
                  animationDelay: i * 65 + 'ms',
                }}
              />
            ))}
          </div>
        )}
      </div>
      <div className="specimen-controls">
        <span>
          {['horizontal-story', 'scroll-zoom'].includes(id)
            ? 'Прокрути внутри сцены'
            : ['drag-snap', 'swipe-deck'].includes(id)
              ? 'Перетаскивай или используй кнопки'
              : 'Попробуй взаимодействие'}
        </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>
    </div>
  );
}
