import React, { useState, useRef, useEffect, useCallback } from 'react';
import { useAppStore } from '../store';
import { TextNote } from '../types';
import { AlignLeft, AlignCenter, AlignRight, Bold, Italic, Underline, List, ListOrdered, ChevronDown, Minus, Plus } from 'lucide-react';

const FONTS = [
  { label: 'System', value: 'system-ui, -apple-system, BlinkMacSystemFont, sans-serif' },
  { label: 'Arial', value: 'Arial, Helvetica, sans-serif' },
  { label: 'Georgia', value: 'Georgia, serif' },
  { label: 'Times', value: '"Times New Roman", Times, serif' },
  { label: 'Mono', value: 'Consolas, "Courier New", monospace' },
  { label: 'Comic', value: '"Comic Sans MS", cursive' },
];

export const TextNoteNode = ({ note }: { note: TextNote }) => {
  const { setTextNotes, zoom, isAnnotationMode, isClickThrough, selectedNodeIds, setSelectedNodeIds, updateSelectedNodes } = useAppStore();
  const [isDragging, setIsDragging] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [localText, setLocalText] = useState(note.text);
  const [isResizing, setIsResizing] = useState(false);
  const [fontMenuOpen, setFontMenuOpen] = useState(false);
  const [fmtBold, setFmtBold] = useState(false);
  const [fmtItalic, setFmtItalic] = useState(false);
  const [fmtUnderline, setFmtUnderline] = useState(false);
  const contentRef = useRef<HTMLDivElement>(null);
  const isSelected = selectedNodeIds.includes(note.id);

  // Manual double-click detection — works reliably with pointer capture
  const lastClickTime = useRef(0);
  const lastClickPos = useRef({ x: 0, y: 0 });
  const hasMoved = useRef(false);

  useEffect(() => {
    if (isEditing && contentRef.current) {
      contentRef.current.innerHTML = localText;
      contentRef.current.focus();
    }
  }, [isEditing]);

  const syncFmt = useCallback(() => {
    if (!isEditing) return;
    setTimeout(() => {
      try {
        setFmtBold(document.queryCommandState('bold'));
        setFmtItalic(document.queryCommandState('italic'));
        setFmtUnderline(document.queryCommandState('underline'));
      } catch {}
    }, 10);
  }, [isEditing]);

  const updateNote = (changes: Partial<TextNote>) => setTextNotes(prev => prev.map(n => n.id === note.id ? { ...n, ...changes } : n));

  const handlePointerDown = (e: React.PointerEvent) => {
    if (isClickThrough || isAnnotationMode) return;
    if (isEditing) { e.stopPropagation(); return; }
    e.stopPropagation();
    if (e.button !== 0) return;

    // Check for double-click: two clicks within 400ms and 5px
    const now = Date.now();
    const dx = Math.abs(e.clientX - lastClickPos.current.x);
    const dy = Math.abs(e.clientY - lastClickPos.current.y);
    const isDoubleClick = (now - lastClickTime.current < 400) && dx < 5 && dy < 5;
    lastClickTime.current = now;
    lastClickPos.current = { x: e.clientX, y: e.clientY };

    if (isDoubleClick) {
      // Enter edit mode immediately — don't start drag
      setIsEditing(true);
      return;
    }

    // Single click — select and prepare drag
    if (!isSelected) {
      const ids = note.groupId ? (() => { let r: string[] = []; setTextNotes(p => { r = p.filter(n => n.groupId === note.groupId).map(n => n.id); return p; }); return r; })() : [note.id];
      if (e.shiftKey) setSelectedNodeIds(s => [...new Set([...s, ...ids])]);
      else setSelectedNodeIds(ids);
    }
    hasMoved.current = false;
    setIsDragging(true);
    e.currentTarget.setPointerCapture(e.pointerId);
  };

  const handlePointerMove = (e: React.PointerEvent) => {
    if (isResizing) {
      e.stopPropagation();
      updateNote({ width: Math.max(120, note.width + e.movementX / zoom), height: Math.max(50, (note.height || 80) + e.movementY / zoom) });
    } else if (isDragging) {
      e.stopPropagation();
      hasMoved.current = true;
      updateSelectedNodes(e.movementX / zoom, e.movementY / zoom, note.id);
    }
  };

  const handlePointerUp = (e: React.PointerEvent) => {
    if (isResizing) setIsResizing(false);
    else if (isDragging) setIsDragging(false);
    try { e.currentTarget.releasePointerCapture(e.pointerId); } catch {}
  };

  const finishEditing = () => {
    setIsEditing(false); setFontMenuOpen(false);
    setFmtBold(false); setFmtItalic(false); setFmtUnderline(false);
    const t = contentRef.current?.innerHTML || '';
    setLocalText(t); updateNote({ text: t });
  };

  const handleBlur = (e: React.FocusEvent) => {
    const related = e.relatedTarget as HTMLElement | null;
    if (related?.closest?.('[data-tb]')) return;
    finishEditing();
  };

  const exec = (cmd: string) => { document.execCommand(cmd); contentRef.current?.focus(); syncFmt(); };

  const color = note.color || '#FFFFFF';
  const bgColor = note.bgColor || 'rgba(30,30,32,0.85)';
  const fontSize = note.fontSize || 14;
  const fontFamily = note.fontFamily || FONTS[0].value;
  const alignment = note.alignment || 'left';
  const fontLabel = FONTS.find(f => f.value === fontFamily)?.label || 'System';

  const act = 'bg-white/15 text-white';
  const idle = 'text-white/50 hover:bg-white/8 hover:text-white/90';

  return (
    <div className="absolute group" style={{ transform: `translate(${note.x}px, ${note.y}px)`, width: note.width, height: note.height || 'auto', zIndex: isEditing ? 200 : 20, pointerEvents: (isClickThrough || isAnnotationMode) ? 'none' : 'auto' }} onPointerDown={handlePointerDown} onPointerMove={handlePointerMove} onPointerUp={handlePointerUp} onContextMenu={e => e.preventDefault()}>

      {isEditing && (
        <div data-tb="" className="absolute bottom-full mb-2 left-1/2 -translate-x-1/2 inline-flex items-center h-9 bg-[#222224] border border-[#3A3A3E] rounded-[10px] shadow-2xl pointer-events-auto z-[300] select-none overflow-visible" onMouseDown={e => e.preventDefault()} onPointerDown={e => e.stopPropagation()}>

          {/* FONT PICKER */}
          <div className="relative h-full flex items-center border-r border-[#3A3A3E]">
            <button onMouseDown={e => { e.preventDefault(); e.stopPropagation(); setFontMenuOpen(v => !v); }} className="h-full px-3 flex items-center gap-1.5 text-[11px] text-white/80 hover:bg-white/5 rounded-l-[10px] transition-colors">
              <span className="max-w-[60px] truncate font-medium">{fontLabel}</span>
              <ChevronDown size={10} className="opacity-40" />
            </button>
            {fontMenuOpen && (
              <div className="absolute top-full mt-1 left-0 w-[140px] bg-[#222224] border border-[#3A3A3E] rounded-lg shadow-2xl z-[400] py-1">
                {FONTS.map(f => (
                  <button key={f.label} onMouseDown={e => { e.preventDefault(); e.stopPropagation(); updateNote({ fontFamily: f.value }); setFontMenuOpen(false); setTimeout(() => contentRef.current?.focus(), 0); }} className={`w-full text-left px-3 py-1.5 text-[12px] transition-colors ${fontFamily === f.value ? act : 'text-white/70 hover:bg-white/8'}`} style={{ fontFamily: f.value }}>{f.label}</button>
                ))}
              </div>
            )}
          </div>

          {/* FONT SIZE */}
          <div className="flex items-center h-full px-1 border-r border-[#3A3A3E]">
            <button onMouseDown={e => { e.preventDefault(); updateNote({ fontSize: Math.max(10, fontSize - 2) }); }} className="w-6 h-6 flex items-center justify-center rounded text-white/40 hover:text-white hover:bg-white/8"><Minus size={12} /></button>
            <span className="text-[11px] text-white/80 w-6 text-center font-mono tabular-nums select-none">{fontSize}</span>
            <button onMouseDown={e => { e.preventDefault(); updateNote({ fontSize: Math.min(72, fontSize + 2) }); }} className="w-6 h-6 flex items-center justify-center rounded text-white/40 hover:text-white hover:bg-white/8"><Plus size={12} /></button>
          </div>

          {/* B I U */}
          <div className="flex items-center h-full px-0.5 border-r border-[#3A3A3E]">
            <button onMouseDown={e => { e.preventDefault(); exec('bold'); }} className={`w-7 h-7 flex items-center justify-center rounded-md transition-colors ${fmtBold ? act : idle}`}><Bold size={14} /></button>
            <button onMouseDown={e => { e.preventDefault(); exec('italic'); }} className={`w-7 h-7 flex items-center justify-center rounded-md transition-colors ${fmtItalic ? act : idle}`}><Italic size={14} /></button>
            <button onMouseDown={e => { e.preventDefault(); exec('underline'); }} className={`w-7 h-7 flex items-center justify-center rounded-md transition-colors ${fmtUnderline ? act : idle}`}><Underline size={14} /></button>
          </div>

          {/* LISTS */}
          <div className="flex items-center h-full px-0.5 border-r border-[#3A3A3E]">
            <button onMouseDown={e => { e.preventDefault(); exec('insertUnorderedList'); }} className={`w-7 h-7 flex items-center justify-center rounded-md ${idle}`}><List size={14} /></button>
            <button onMouseDown={e => { e.preventDefault(); exec('insertOrderedList'); }} className={`w-7 h-7 flex items-center justify-center rounded-md ${idle}`}><ListOrdered size={14} /></button>
          </div>

          {/* ALIGNMENT */}
          <div className="flex items-center h-full px-0.5 border-r border-[#3A3A3E]">
            <button onMouseDown={e => { e.preventDefault(); updateNote({ alignment: 'left' }); }} className={`w-7 h-7 flex items-center justify-center rounded-md transition-colors ${alignment === 'left' ? act : idle}`}><AlignLeft size={14} /></button>
            <button onMouseDown={e => { e.preventDefault(); updateNote({ alignment: 'center' }); }} className={`w-7 h-7 flex items-center justify-center rounded-md transition-colors ${alignment === 'center' ? act : idle}`}><AlignCenter size={14} /></button>
            <button onMouseDown={e => { e.preventDefault(); updateNote({ alignment: 'right' }); }} className={`w-7 h-7 flex items-center justify-center rounded-md transition-colors ${alignment === 'right' ? act : idle}`}><AlignRight size={14} /></button>
          </div>

          {/* COLOR */}
          <div className="flex items-center h-full px-2 gap-1.5">
            {['#FFFFFF','#FFD60A','#FF453A','#30D158','#0A84FF'].map(c => (
              <button key={c} onMouseDown={e => { e.preventDefault(); updateNote({ color: c }); }} className={`w-3.5 h-3.5 rounded-full transition-transform ${color === c ? 'scale-125 ring-[1.5px] ring-white ring-offset-1 ring-offset-[#222224]' : 'opacity-50 hover:opacity-100 hover:scale-110'}`} style={{ backgroundColor: c }} />
            ))}
          </div>
        </div>
      )}

      {/* NOTE BODY */}
      <div className={`p-4 rounded-xl shadow-xl h-full transition-shadow ${isEditing ? 'ring-2 ring-white/20' : isSelected ? 'ring-1 ring-white/20' : 'hover:ring-1 hover:ring-white/8'}`} style={{ backgroundColor: isEditing ? '#141416' : bgColor }}>
        {isEditing ? (
          <div ref={contentRef} className="w-full h-full bg-transparent outline-none overflow-y-auto min-h-[40px]" style={{ color, fontSize: `${fontSize}px`, fontFamily, textAlign: alignment, lineHeight: 1.6, wordBreak: 'break-word' }} contentEditable suppressContentEditableWarning onBlur={handleBlur} onKeyDown={e => { e.stopPropagation(); if (e.key === 'Escape') finishEditing(); }} onKeyUp={syncFmt} onClick={syncFmt} onPointerDown={e => e.stopPropagation()} />
        ) : (
          <div className="select-none break-words h-full overflow-hidden" style={{ color, fontSize: `${fontSize}px`, fontFamily, textAlign: alignment, lineHeight: 1.6, wordBreak: 'break-word' }} dangerouslySetInnerHTML={{ __html: localText || '<span style="opacity:0.3;font-style:italic">Double-click to edit</span>' }} />
        )}

        {!isEditing && <button className="absolute -top-2 -right-2 w-5 h-5 bg-[#FF453A] text-white rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity shadow-lg z-30 text-[10px]" onClick={e => { e.stopPropagation(); setTextNotes(prev => prev.filter(n => n.id !== note.id)); }} onPointerDown={e => e.stopPropagation()}>×</button>}

        <div className={`absolute bottom-1 right-1 w-3 h-3 cursor-nwse-resize opacity-0 ${isEditing || isSelected ? 'opacity-40' : 'group-hover:opacity-40'} transition-opacity z-30`} onPointerDown={e => { e.stopPropagation(); setIsResizing(true); (e.target as HTMLElement).setPointerCapture(e.pointerId); }} onPointerUp={handlePointerUp} onPointerMove={handlePointerMove}>
          <svg width="10" height="10" viewBox="0 0 10 10"><path d="M9 1L1 9M9 4L4 9M9 7L7 9" stroke="white" strokeWidth="1.2" strokeLinecap="round" opacity="0.5" /></svg>
        </div>
      </div>
    </div>
  );
};
