import { useCallback, useRef, useState } from 'react';
import type { KeyboardEvent, PointerEvent } from 'react';
import { IconCompareArrows } from './icons';
import './compare-slider.css';

/*
 * Before/After 비교 슬라이더 (design.md S5 — 시공 전 빈 홀 ↔ 시공 후 렌더).
 * 근거: docs/analysis/reroomai-source.md §5(C) — reroomai `CompareSlider` 패턴 이식.
 *  - clip-path: inset(0 {100-pos}% 0 0) 로 After 레이어를 클립 → 리사이즈에도 픽셀 정렬 유지.
 *  - 포인터 캡처(setPointerCapture)로 프레임 밖 드래그도 추적.
 *  - 키보드(방향키 ±1, Shift 큰 스텝 ±10, Home/End) + ARIA slider 접근성.
 * ★ After가 AI 생성 이미지이면 워터마크·고지는 상위(AiImage/afterOverlay)에서 상시 노출.
 */
interface CompareSliderProps {
  beforeSrc: string;
  afterSrc: string;
  beforeAlt?: string;
  afterAlt?: string;
  beforeLabel?: string;
  afterLabel?: string;
  /** After 레이어 위에 상시 겹칠 노드(워터마크·AI 라벨 등). */
  afterOverlay?: React.ReactNode;
  /** 초기 위치(0~100). 기본 50. */
  initial?: number;
}

export function CompareSlider({
  beforeSrc,
  afterSrc,
  beforeAlt = '시공 전',
  afterAlt = '시공 후 (AI 생성 예상 이미지)',
  beforeLabel = '시공 전',
  afterLabel = '시공 후',
  afterOverlay,
  initial = 50,
}: CompareSliderProps) {
  const [pos, setPos] = useState(() => Math.min(100, Math.max(0, initial)));
  const frameRef = useRef<HTMLDivElement>(null);
  const draggingRef = useRef(false);

  const updateFromClientX = useCallback((clientX: number) => {
    const frame = frameRef.current;
    if (!frame) return;
    const rect = frame.getBoundingClientRect();
    const ratio = (clientX - rect.left) / rect.width;
    setPos(Math.min(100, Math.max(0, ratio * 100)));
  }, []);

  const onPointerDown = useCallback(
    (e: PointerEvent<HTMLButtonElement>) => {
      draggingRef.current = true;
      e.currentTarget.setPointerCapture(e.pointerId);
      updateFromClientX(e.clientX);
    },
    [updateFromClientX],
  );

  const onPointerMove = useCallback(
    (e: PointerEvent<HTMLButtonElement>) => {
      if (!draggingRef.current) return;
      updateFromClientX(e.clientX);
    },
    [updateFromClientX],
  );

  const onPointerUp = useCallback((e: PointerEvent<HTMLButtonElement>) => {
    draggingRef.current = false;
    if (e.currentTarget.hasPointerCapture(e.pointerId)) {
      e.currentTarget.releasePointerCapture(e.pointerId);
    }
  }, []);

  const onKeyDown = useCallback((e: KeyboardEvent<HTMLButtonElement>) => {
    const big = e.shiftKey ? 10 : 1;
    if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {
      e.preventDefault();
      setPos((p) => Math.max(0, p - big));
    } else if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {
      e.preventDefault();
      setPos((p) => Math.min(100, p + big));
    } else if (e.key === 'Home') {
      e.preventDefault();
      setPos(0);
    } else if (e.key === 'End') {
      e.preventDefault();
      setPos(100);
    }
  }, []);

  return (
    <div className="kx-compare" ref={frameRef}>
      {/* Before (하단, 전체) */}
      <img className="kx-compare__img" src={beforeSrc} alt={beforeAlt} draggable={false} />

      {/* After (상단, 좌측부터 pos% 만큼 노출) */}
      <div
        className="kx-compare__after"
        style={{ clipPath: `inset(0 ${100 - pos}% 0 0)` }}
        aria-hidden={pos === 0}
      >
        <img className="kx-compare__img" src={afterSrc} alt={afterAlt} draggable={false} />
        {afterOverlay}
      </div>

      <span className="kx-compare__label kx-compare__label--before" aria-hidden="true">
        {beforeLabel}
      </span>
      <span className="kx-compare__label kx-compare__label--after" aria-hidden="true">
        {afterLabel}
      </span>

      {/* 핸들 = ARIA slider */}
      <button
        type="button"
        className="kx-compare__handle"
        style={{ left: `${pos}%` }}
        role="slider"
        aria-label={`${beforeLabel} 대 ${afterLabel} 비교 슬라이더`}
        aria-valuemin={0}
        aria-valuemax={100}
        aria-valuenow={Math.round(pos)}
        aria-valuetext={`${afterLabel} ${Math.round(pos)}% 노출`}
        onPointerDown={onPointerDown}
        onPointerMove={onPointerMove}
        onPointerUp={onPointerUp}
        onKeyDown={onKeyDown}
      >
        <span className="kx-compare__handle-grip" aria-hidden="true">
          <IconCompareArrows size={18} />
        </span>
      </button>
    </div>
  );
}
