import React, { useEffect, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';

export interface RefPopupPos {
  x: number;
  y: number;
  id: string;
  type: 'abbrev' | 'footnote';
  vol: number;
  page: number;
}

interface Props {
  pos: RefPopupPos | null;
  onClose: () => void;
  onJump?: (id: string) => void;
}

const MIN_W = 240;
const MAX_W = 600;
const INIT_W = 320;

const ReferencePopup: React.FC<Props> = ({ pos, onClose, onJump }) => {
  const popupRef = useRef<HTMLDivElement>(null);

  const [content, setContent] = React.useState<string | null>(null);
  const [isLoading, setIsLoading] = React.useState(false);
  const [popupFontSize, setPopupFontSize] = React.useState(15);
  const [popupWidth, setPopupWidth] = React.useState(INIT_W);
  const [popupHeight, setPopupHeight] = React.useState<number | null>(null);
  const [visible, setVisible] = React.useState(false);

  // ── Position state (top-left of popup) ──
  const [posX, setPosX] = React.useState(0);
  const [posY, setPosY] = React.useState(0);
  const [showArrow, setShowArrow] = React.useState(false);
  const [arrowShift, setArrowShift] = React.useState(0);
  const [flipUp, setFlipUp] = React.useState(false);

  // ── Drag state ──
  const dragging = useRef(false);
  const dragStart = useRef({ x: 0, y: 0, px: 0, py: 0 });

  // ── Resize state ──
  const resizing = useRef(false);
  const resizeStart = useRef({ x: 0, y: 0, w: INIT_W, h: 0 });

  // ── Initial positioning when pos changes ──
  useEffect(() => {
    if (!pos) {
      setVisible(false);
      setContent(null);
      return;
    }

    setPopupWidth(INIT_W);
    setPopupHeight(null);

    // Fetch content
    const fetchRef = async () => {
      setIsLoading(true);
      try {
        const response = await fetch(
          `/api/reference/lookup?vol=${pos.vol}&page=${pos.page}&type=${pos.type}&id=${encodeURIComponent(pos.id)}`
        );
        const data = await response.json();
        setContent(data.content);
      } catch (err) {
        console.error("Failed to fetch reference:", err);
        setContent("เกิดข้อผิดพลาดในการโหลดข้อมูล");
      } finally {
        setIsLoading(false);
      }
    };
    fetchRef();

    // Calculate initial position (top-left of popup, not centered)
    requestAnimationFrame(() => {
      const viewW = window.innerWidth;
      const viewH = window.innerHeight;
      const halfW = INIT_W / 2;
      const EDGE = 12;

      // Start: sup center → convert to top-left
      let left = pos.x - halfW;
      let top = pos.y + 6; // 6px below sup
      let flip = false;

      // Horizontal clamp
      if (left < EDGE) left = EDGE;
      else if (left + INIT_W > viewW - EDGE) left = viewW - INIT_W - EDGE;

      // Arrow horizontal shift
      const centerX = left + INIT_W / 2;
      let aShift = pos.x - centerX;

      // Vertical flip if near bottom
      const estH = 260;
      if (pos.y + estH + 20 > viewH) {
        flip = true;
        top = pos.y - 6 - estH;
        if (top < EDGE) top = EDGE;
      }

      setPosX(left);
      setPosY(top);
      setArrowShift(aShift);
      setFlipUp(flip);
      setShowArrow(true);
      setVisible(true);

      // Fine-tune after render
      setTimeout(() => {
        if (popupRef.current) {
          const actualH = popupRef.current.offsetHeight;
          if (flip && pos.y - actualH - 6 < EDGE) {
            setPosY(EDGE);
            setFlipUp(false);
          } else if (!flip && pos.y + actualH + 20 > viewH) {
            setPosY(Math.max(EDGE, viewH - actualH - 10));
            setFlipUp(true);
          }
        }
      }, 60);
    });
  }, [pos]);

  // ── Drag handler ──
  const onDragStart = React.useCallback((e: React.MouseEvent) => {
    e.preventDefault();
    dragging.current = true;
    dragStart.current = { x: e.clientX, y: e.clientY, px: posX, py: posY };
    setShowArrow(false);
    const onMove = (ev: MouseEvent) => {
      if (!dragging.current) return;
      setPosX(dragStart.current.px + (ev.clientX - dragStart.current.x));
      setPosY(dragStart.current.py + (ev.clientY - dragStart.current.y));
    };
    const onUp = () => { dragging.current = false; };
    document.addEventListener('mousemove', onMove);
    document.addEventListener('mouseup', onUp, { once: true });
  }, [posX, posY]);

  // ── Resize handler ──
  const onResizeStart = React.useCallback((e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    resizing.current = true;
    resizeStart.current = { x: e.clientX, y: e.clientY, w: popupWidth, h: popupHeight || 300 };
    const onMove = (ev: MouseEvent) => {
      if (!resizing.current) return;
      const newW = Math.max(MIN_W, Math.min(MAX_W, resizeStart.current.w + (ev.clientX - resizeStart.current.x)));
      const newH = Math.max(150, resizeStart.current.h + (ev.clientY - resizeStart.current.y));
      setPopupWidth(newW);
      setPopupHeight(newH);
    };
    const onUp = () => { resizing.current = false; };
    document.addEventListener('mousemove', onMove);
    document.addEventListener('mouseup', onUp, { once: true });
  }, [popupWidth, popupHeight]);

  // ── Click outside ──
  useEffect(() => {
    const onMouseDown = (e: MouseEvent | TouchEvent) => {
      const target = e.target as HTMLElement;
      if (target.tagName?.toLowerCase() === 'sup' &&
          (target.classList.contains('abbrev-ref') || target.classList.contains('footnote-ref'))) return;
      if (popupRef.current && !popupRef.current.contains(e.target as Node)) onClose();
    };
    document.addEventListener('mousedown', onMouseDown);
    document.addEventListener('touchstart', onMouseDown);
    return () => {
      document.removeEventListener('mousedown', onMouseDown);
      document.removeEventListener('touchstart', onMouseDown);
    };
  }, [onClose]);

  return (
    <AnimatePresence>
      {pos && (
        <motion.div
          ref={popupRef}
          key="ref-popup"
          initial={{ opacity: 0, scale: 0.95 }}
          animate={{
            opacity: visible ? 1 : 0,
            scale: visible ? 1 : 0.95,
          }}
          exit={{ opacity: 0, scale: 0.95 }}
          transition={{ duration: 0.12, ease: 'easeOut' }}
          style={{
            position: 'fixed',
            left: posX,
            top: posY,
            zIndex: 9998,
            width: popupWidth,
            height: popupHeight || 'auto',
            maxHeight: popupHeight ? 'none' : (flipUp ? '50vh' : 'calc(100vh - 120px)'),
          }}
          className="rounded-2xl shadow-[0_20px_50px_rgba(0,0,0,0.5)] bg-[#1a1a2e]/95 backdrop-blur-xl border border-white/10 text-[#e8e4da] overflow-hidden flex flex-col"
        >
          {/* Gradient top bar */}
          <div className="h-1 bg-gradient-to-r from-[#c8860a]/0 via-[#c8860a] to-[#c8860a]/0 shrink-0" />

          <div className="p-4 flex flex-col flex-1 min-h-0">
            {/* Header — drag handle */}
            <div
              onMouseDown={onDragStart}
              className="flex items-center justify-between mb-3 pb-2 border-b border-white/5 shrink-0 cursor-grab active:cursor-grabbing select-none"
            >
              <div className="flex items-center gap-2 min-w-0">
                {/* Drag indicator */}
                <svg className="w-3.5 h-3.5 text-white/15 shrink-0" viewBox="0 0 24 24" fill="currentColor">
                  <circle cx="9" cy="5" r="1.5"/><circle cx="15" cy="5" r="1.5"/>
                  <circle cx="9" cy="12" r="1.5"/><circle cx="15" cy="12" r="1.5"/>
                  <circle cx="9" cy="19" r="1.5"/><circle cx="15" cy="19" r="1.5"/>
                </svg>
                <span className="bg-[#c8860a] text-[#1a1a2e] text-xs font-bold px-1.5 py-0.5 rounded shrink-0">
                  {pos.id}
                </span>
                <span className="text-xs font-medium text-white/50 tracking-wide uppercase truncate">
                  {pos.type === 'abbrev' ? 'คำย่อ' : 'เชิงอรรถ'}
                </span>
              </div>
              <div className="flex items-center gap-1 shrink-0">
                <button onClick={() => setPopupFontSize(s => Math.max(s - 2, 11))}
                  className="text-white/30 hover:text-white/70 transition-colors p-0.5" title="ย่อ">
                  <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18 10h-4m-4 0H6" />
                  </svg>
                </button>
                <button onClick={() => setPopupFontSize(15)}
                  className="text-[9px] text-white/20 hover:text-white/50 transition-colors font-mono w-3.5 text-center" title="รีเซ็ต">
                  A
                </button>
                <button onClick={() => setPopupFontSize(s => Math.min(s + 2, 28))}
                  className="text-white/30 hover:text-white/70 transition-colors p-0.5" title="ขยาย">
                  <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
                  </svg>
                </button>
                <button onClick={onClose}
                  className="text-white/30 hover:text-white/70 transition-colors ml-1">
                  <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                  </svg>
                </button>
              </div>
            </div>

            {/* Content */}
            <div className="overflow-y-auto custom-scrollbar pr-1 flex-1 min-h-0">
              {isLoading ? (
                <div className="space-y-3 py-1">
                  <div className="h-3 bg-white/10 rounded-full w-full animate-pulse" />
                  <div className="h-3 bg-white/10 rounded-full w-5/6 animate-pulse" />
                  <div className="h-3 bg-white/10 rounded-full w-4/6 animate-pulse" />
                </div>
              ) : (
                <div className="leading-relaxed font-light text-white/90"
                  style={{ fontSize: `${popupFontSize}px` }}>
                  {content || (
                    <span className="text-white/40 italic">ไม่พบข้อมูลอ้างอิง</span>
                  )}
                </div>
              )}
            </div>

            {pos.type === 'abbrev' && !isLoading && (
              <div className="mt-3 pt-2 border-t border-white/5 flex items-center gap-1.5 shrink-0">
                <div className="w-1.5 h-1.5 rounded-full bg-[#c8860a] animate-pulse" />
                <span className="text-[10px] text-white/30 uppercase tracking-tighter">AI ขยายความ</span>
              </div>
            )}
            {pos.type === 'footnote' && !isLoading && onJump && (
              <div className="mt-4 pt-3 border-t border-white/5 shrink-0">
                <button onClick={() => onJump(pos.id)}
                  className="w-full py-2 px-3 rounded-xl bg-white/5 hover:bg-white/10 text-[#c8860a] text-xs font-bold transition-all flex items-center justify-center gap-2 group">
                  <svg className="w-3.5 h-3.5 transform group-hover:translate-y-0.5 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 14l-7 7m0 0l-7-7m7 7V3" />
                  </svg>
                  ดูเนื้อหาเต็มด้านล่าง
                </button>
              </div>
            )}
          </div>

          {/* Resize handle */}
          <div onMouseDown={onResizeStart}
            className="absolute bottom-0 right-0 w-5 h-5 cursor-se-resize group">
            <svg className="w-full h-full text-white/20 group-hover:text-[#c8860a] transition-colors"
              viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}
              strokeLinecap="round" strokeLinejoin="round">
              <path d="M21 15v4a2 2 0 01-2 2h-4" />
              <path d="M21 3v4a2 2 0 01-2 2h-4" />
            </svg>
          </div>

          {/* Tail arrow — hidden after manual drag */}
          {showArrow && (
            flipUp ? (
              <div className="pointer-events-none absolute left-1/2 -bottom-[5px] w-2.5 h-2.5 bg-[#1a1a2e] border-r border-b border-white/10 -rotate-45"
                style={{ marginLeft: arrowShift }} />
            ) : (
              <div className="pointer-events-none absolute left-1/2 -top-[5px] w-2.5 h-2.5 bg-[#1a1a2e] border-l border-t border-white/10 rotate-45"
                style={{ marginLeft: arrowShift }} />
            )
          )}
        </motion.div>
      )}
    </AnimatePresence>
  );
};

export default ReferencePopup;
