import React, { useRef, useState, useEffect, useCallback } from 'react';
import type { EditorStore } from '../../store/editorStore';
import { CanvasNode } from './CanvasNode';
import { SectionPicker } from './SectionPicker';
import { TemplatePicker } from './TemplatePicker';
import { ContextMenu, type ContextMenuState } from './ContextMenu';
import { CommandPalette } from './CommandPalette';

interface Props {
  store: EditorStore;
}

const BREAKPOINT_WIDTHS = {
  desktop: '100%',
  tablet:  '768px',
  mobile:  '390px',
};

// ── Quick Insert Bar ─────────────────────────────────────────────────────────

const QUICK_ITEMS = [
  { type: 'section',   label: 'Section',   icon: '⊞' },
  { type: 'container', label: 'Container', icon: '□' },
  { type: 'heading',   label: 'Heading',   icon: 'H' },
  { type: 'text',      label: 'Text',      icon: '¶' },
  { type: 'image',     label: 'Image',     icon: '⬚' },
  { type: 'button',    label: 'Button',    icon: '⬜' },
  { type: 'icon',      label: 'Icon',      icon: '★' },
];

const DEFAULT_NODES: Record<string, Partial<Parameters<EditorStore['addElement']>[1]>> = {
  heading:   { type: 'heading',   content: { text: 'New Heading', tag: 'h2' }, styles: { fontSize: '32px', fontWeight: '700', color: '#1a1a1a' } },
  text:      { type: 'text',      content: { html: '' }, styles: { fontSize: '16px', color: '#444', lineHeight: '1.7' } },
  button:    { type: 'button',    content: { text: 'Click Here', url: '#' }, styles: { display: 'inline-block', backgroundColor: '#1a1a1a', color: '#ffffff', paddingTop: '14px', paddingBottom: '14px', paddingLeft: '32px', paddingRight: '32px', borderRadius: '8px', fontWeight: '600', fontSize: '16px', textDecoration: 'none', textAlign: 'center' } },
  image:     { type: 'image',     content: { url: '', alt: '' }, styles: { width: '100%' } },
  icon:      { type: 'icon',      content: { icon: 'star', size: '48px', color: '#1a1a1a', align: 'center' } },
  container: { type: 'container', settings: { columns: 1 }, children: [], styles: {} },
};

function QuickInsertBar({ store }: { store: EditorStore }) {
  const handleAdd = (type: string) => {
    if (type === 'section') { store.addSection(); return; }
    const node = DEFAULT_NODES[type] ?? { type };
    store.addElementInNewSection(undefined, node);
  };

  return (
    <div className="jalpi-quick-insert">
      <span className="jalpi-quick-insert__label">QUICK INSERT</span>
      <div className="jalpi-quick-insert__items">
        {QUICK_ITEMS.map((item) => (
          <button
            key={item.type}
            className="jalpi-quick-insert__btn"
            onClick={() => handleAdd(item.type)}
            title={`Add ${item.label}`}
          >
            <span className="jalpi-quick-insert__icon">{item.icon}</span>
            <span className="jalpi-quick-insert__text">{item.label}</span>
          </button>
        ))}
      </div>
    </div>
  );
}

// ── Canvas ───────────────────────────────────────────────────────────────────

export function Canvas({ store }: Props) {
  const { state } = store;
  const canvasRef = useRef<HTMLDivElement>(null);
  const [contextMenu,        setContextMenu]        = useState<ContextMenuState | null>(null);
  const [cmdOpen,            setCmdOpen]            = useState(false);
  const [templatePickerOpen, setTemplatePickerOpen] = useState(false);
  // Stable ref so the keyboard effect never re-registers on every render
  const storeRef = useRef(store);
  storeRef.current = store;

  const handleCanvasClick = (e: React.MouseEvent) => {
    if (e.target === canvasRef.current) {
      store.selectNode(null);
    }
    setContextMenu(null);
  };

  // Right-click on any canvas node
  const handleCanvasContextMenu = useCallback((e: React.MouseEvent) => {
    const target = (e.target as Element).closest('[data-node-id]') as HTMLElement | null;
    if (target?.dataset.nodeId) {
      e.preventDefault();
      e.stopPropagation();
      store.selectNode(target.dataset.nodeId);
      setContextMenu({ x: e.clientX, y: e.clientY, nodeId: target.dataset.nodeId });
    }
  }, [store]);

  // Stable callback for opening the template picker — passed to sticky footer
  const openTemplates = useCallback(() => setTemplatePickerOpen(true), []);

  // Open command palette via custom event dispatched by useShortcuts
  // Escape also closes local overlay state (context menu, palette)
  useEffect(() => {
    const onOpenCmd = () => setCmdOpen((o) => !o);
    const onEscape  = (e: KeyboardEvent) => {
      if (e.key === 'Escape') { setContextMenu(null); setCmdOpen(false); }
    };
    window.addEventListener('cb:openCmd' as any, onOpenCmd);
    document.addEventListener('keydown', onEscape);
    return () => {
      window.removeEventListener('cb:openCmd' as any, onOpenCmd);
      document.removeEventListener('keydown', onEscape);
    };
  }, []);

  // Scroll selected element into view after add/select
  useEffect(() => {
    if (!state.selectedId) return;
    const el = document.querySelector(`[data-node-id="${state.selectedId}"]`) as HTMLElement | null;
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
  }, [state.selectedId]);

  const frameWidth = BREAKPOINT_WIDTHS[state.breakpoint];
  const scale      = state.zoom / 100;

  return (
    <>
      <div className="jalpi-canvas-wrapper">
        <div
          className="jalpi-canvas-scroll"
          onClick={handleCanvasClick}
          onContextMenu={handleCanvasContextMenu}
        >
          <div
            ref={canvasRef}
            className={`jalpi-canvas jalpi-canvas--${state.breakpoint}`}
            style={{
              width:           frameWidth,
              transform:       `scale(${scale})`,
              transformOrigin: 'top center',
            }}
            data-jalpi-canvas="true"
          >
            {state.pageData.sections.length === 0 ? (
              <EmptyCanvas store={store} onImportTemplate={() => setTemplatePickerOpen(true)} />
            ) : (
              state.pageData.sections.map((section) => (
                <div key={section.id} className="jalpi-section-group">
                  <CanvasNode node={section} store={store} isRoot />
                </div>
              ))
            )}
          </div>
        </div>
        {/* Sticky "+ Add Section" bar — always visible at the canvas bottom */}
        {state.pageData.sections.length > 0 && (
          <CanvasStickyFooter store={store} onOpenTemplates={openTemplates} />
        )}
      </div>

      {contextMenu && (
        <ContextMenu
          menu={contextMenu}
          store={store}
          onClose={() => setContextMenu(null)}
        />
      )}

      {cmdOpen && (
        <CommandPalette
          store={store}
          onClose={() => setCmdOpen(false)}
        />
      )}

      {templatePickerOpen && (
        <TemplatePicker
          store={store}
          onClose={() => setTemplatePickerOpen(false)}
        />
      )}
    </>
  );
}

const JALPI_PAGE_MARKER = '__jalpi_page__';

function toast(msg: string) {
  window.dispatchEvent(new CustomEvent('cb:toast', { detail: msg }));
}

/** Copy text to clipboard — works on HTTP (non-secure) via execCommand fallback */
function copyToClipboard(text: string): boolean {
  if (navigator.clipboard && window.isSecureContext) {
    navigator.clipboard.writeText(text).catch(() => {/* ignore */});
    return true;
  }
  const ta = document.createElement('textarea');
  ta.value = text;
  ta.style.cssText = 'position:fixed;top:-9999px;left:-9999px;opacity:0;';
  document.body.appendChild(ta);
  ta.focus();
  ta.select();
  const ok = document.execCommand('copy');
  document.body.removeChild(ta);
  return ok;
}

function CanvasStickyFooter({ store, onOpenTemplates }: { store: EditorStore; onOpenTemplates: () => void }) {
  const [open, setOpen]           = useState(false);
  const [ctxMenu, setCtxMenu]     = useState<{ x: number; y: number } | null>(null);
  const [copied, setCopied]       = useState(false);
  const [showPasteBox, setShowPasteBox] = useState(false);
  const [pasteText, setPasteText] = useState('');
  const triggerRef  = useRef<HTMLButtonElement>(null);
  const ctxMenuRef  = useRef<HTMLDivElement>(null);
  const pasteAreaRef = useRef<HTMLTextAreaElement>(null);

  // Close context menu when clicking outside
  useEffect(() => {
    if (!ctxMenu) return;
    const h = (e: MouseEvent) => {
      if (ctxMenuRef.current && !ctxMenuRef.current.contains(e.target as Node)) {
        setCtxMenu(null);
      }
    };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, [ctxMenu]);

  // Auto-focus paste textarea when shown
  useEffect(() => {
    if (showPasteBox) setTimeout(() => pasteAreaRef.current?.focus(), 50);
  }, [showPasteBox]);

  const handleCopyPage = useCallback(() => {
    const payload = JSON.stringify({ [JALPI_PAGE_MARKER]: true, ...store.state.pageData });
    const ok = copyToClipboard(payload);
    if (ok) {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
      toast('Page copied! Paste it on any other page or website.');
    } else {
      toast('Copy failed — please try again.');
    }
    setCtxMenu(null);
  }, [store]);

  const applyPaste = useCallback((text: string) => {
    try {
      const data = JSON.parse(text.trim());
      if (!data[JALPI_PAGE_MARKER]) {
        toast('Not valid Jalpi Page Builder page data.');
        return;
      }
      const { [JALPI_PAGE_MARKER]: _m, ...pageData } = data;
      store.loadPageData(pageData);
      toast('Page content pasted successfully!');
      setShowPasteBox(false);
      setPasteText('');
    } catch {
      toast('Invalid data — make sure you copied a Jalpi Page Builder page first.');
    }
  }, [store]);

  const handlePastePage = useCallback(async () => {
    setCtxMenu(null);
    // Try native clipboard API first (works on HTTPS / localhost)
    if (navigator.clipboard && window.isSecureContext) {
      try {
        const text = await navigator.clipboard.readText();
        applyPaste(text);
        return;
      } catch {/* fall through to manual box */}
    }
    // HTTP fallback: show a textarea so user can Ctrl+V manually
    setShowPasteBox(true);
  }, [applyPaste]);

  return (
    <div
      className="jalpi-canvas-sticky-footer"
      onContextMenu={(e) => {
        e.preventDefault();
        e.stopPropagation();
        setCtxMenu({ x: e.clientX, y: e.clientY });
      }}
    >
      <div className="jalpi-sab-trigger-wrap">
        <button
          ref={triggerRef}
          className={`jalpi-sab-trigger jalpi-sab-trigger--sticky${open ? ' is-active' : ''}`}
          title="Add a new section — right-click for page copy options"
          onClick={(e) => { e.stopPropagation(); setOpen((v) => !v); }}
        >
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
            <path d="M12 5v14M5 12h14"/>
          </svg>
          Add Section
        </button>
        {open && (
          <SectionPicker
            store={store}
            onClose={() => setOpen(false)}
            triggerRef={triggerRef}
            direction="up"
            onOpenTemplates={onOpenTemplates}
          />
        )}
      </div>

      {/* Right-click context menu */}
      {ctxMenu && (
        <div
          ref={ctxMenuRef}
          className="jalpi-page-ctx-menu"
          style={{ left: ctxMenu.x, top: ctxMenu.y, transform: 'translateY(-100%) translateY(-6px)' }}
          role="menu"
        >
          <div className="jalpi-page-ctx-menu__heading">Page Clipboard</div>
          <button
            className="jalpi-page-ctx-menu__item"
            role="menuitem"
            onClick={handleCopyPage}
          >
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
            </svg>
            {copied ? 'Copied!' : 'Copy All Content'}
          </button>
          <button
            className="jalpi-page-ctx-menu__item"
            role="menuitem"
            onClick={handlePastePage}
          >
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/>
              <rect x="8" y="2" width="8" height="4" rx="1" ry="1"/>
            </svg>
            Paste Page Content
          </button>
          <div className="jalpi-page-ctx-menu__hint">
            Copied pages work across pages and websites
          </div>
        </div>
      )}

      {/* Manual paste fallback (HTTP non-secure context) */}
      {showPasteBox && (
        <div className="jalpi-paste-overlay" onClick={() => setShowPasteBox(false)}>
          <div className="jalpi-paste-modal" onClick={(e) => e.stopPropagation()}>
            <div className="jalpi-paste-modal__header">
              <span>Paste Page Content</span>
              <button className="jalpi-paste-modal__close" onClick={() => setShowPasteBox(false)}>
                <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
              </button>
            </div>
            <p className="jalpi-paste-modal__hint">Press <kbd>Ctrl+V</kbd> to paste your copied page data, then click Apply.</p>
            <textarea
              ref={pasteAreaRef}
              className="jalpi-paste-modal__area"
              placeholder='Paste page JSON here (starts with {"__jalpi_page__":true,...})'
              value={pasteText}
              onChange={(e) => setPasteText(e.target.value)}
              rows={6}
            />
            <div className="jalpi-paste-modal__actions">
              <button className="jalpi-paste-modal__cancel" onClick={() => setShowPasteBox(false)}>Cancel</button>
              <button className="jalpi-paste-modal__apply" onClick={() => applyPaste(pasteText)} disabled={!pasteText.trim()}>Apply</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

const SectionActionBar = React.memo(function SectionActionBar({ store, sectionId, onOpenTemplates }: { store: EditorStore; sectionId: string; onOpenTemplates: () => void }) {
  const [open, setOpen] = useState(false);
  const triggerRef = useRef<HTMLButtonElement>(null);

  return (
    <div className="jalpi-section-action-bar">
      <div className="jalpi-sab-trigger-wrap">
        <button
          ref={triggerRef}
          className={`jalpi-sab-trigger${open ? ' is-active' : ''}`}
          title="Add section below"
          onClick={(e) => { e.stopPropagation(); setOpen((v) => !v); }}
        >
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
            <path d="M12 5v14M5 12h14"/>
          </svg>
          Add Section
        </button>
        {open && (
          <SectionPicker
            store={store}
            afterSectionId={sectionId}
            triggerRef={triggerRef}
            onClose={() => setOpen(false)}
            onOpenTemplates={onOpenTemplates}
          />
        )}
      </div>
    </div>
  );
// sectionId is stable for the lifetime of a section — never re-render
}, (prev, next) => prev.sectionId === next.sectionId && prev.onOpenTemplates === next.onOpenTemplates);

function EmptyCanvas({ store, onImportTemplate }: { store: EditorStore; onImportTemplate: () => void }) {
  const [sectionPickerOpen, setSectionPickerOpen] = useState(false);

  return (
    <div className="jalpi-canvas__empty">
      <div className="jalpi-canvas__empty-inner">

        {/* ── Illustration ── */}
        <div className="jalpi-canvas__empty-illo" aria-hidden="true">
          <svg width="220" height="166" viewBox="0 0 220 166" fill="none" xmlns="http://www.w3.org/2000/svg">
            <defs>
              <clipPath id="ec-page-clip">
                <rect x="40" y="20" width="136" height="118" rx="10"/>
              </clipPath>
            </defs>
            {/* Ambient glow */}
            <ellipse cx="110" cy="83" rx="88" ry="66" fill="rgba(124,58,237,0.045)"/>
            {/* Page shadow */}
            <rect x="42" y="23" width="136" height="118" rx="10" fill="rgba(15,23,42,0.06)"/>
            {/* Page body */}
            <rect x="40" y="20" width="136" height="118" rx="10" fill="#ffffff" stroke="#e5e7eb" strokeWidth="1.5"/>
            {/* Nav bar */}
            <rect x="40" y="20" width="136" height="22" fill="#f9fafb" clipPath="url(#ec-page-clip)"/>
            <circle cx="58" cy="31" r="5" fill="#e8e8e8"/>
            <rect x="150" y="25" width="19" height="11" rx="5.5" fill="#d0d0d0"/>
            {/* Hero block */}
            <rect x="52" y="52" width="112" height="44" rx="6" fill="#f0f0f0"/>
            <rect x="70" y="64" width="80" height="7" rx="3.5" fill="#bbbbbb"/>
            <rect x="78" y="76" width="60" height="5" rx="2.5" fill="#d0d0d0"/>
            {/* Two columns */}
            <rect x="52" y="104" width="50" height="22" rx="5" fill="#f9fafb" stroke="#ebebeb" strokeWidth="1"/>
            <rect x="110" y="104" width="50" height="22" rx="5" fill="#f9fafb" stroke="#ebebeb" strokeWidth="1"/>
            <rect x="59" y="110" width="30" height="4" rx="2" fill="#e5e7eb"/>
            <rect x="59" y="117" width="20" height="4" rx="2" fill="#f3f4f6"/>
            <rect x="117" y="110" width="30" height="4" rx="2" fill="#e5e7eb"/>
            <rect x="117" y="117" width="20" height="4" rx="2" fill="#f3f4f6"/>
            {/* Body text line */}
            <rect x="52" y="133" width="80" height="3" rx="1.5" fill="#e5e7eb"/>
            {/* 4-star sparkle — top right */}
            <path d="M175 15 L177 9 L179 15 L185 17 L179 19 L177 25 L175 19 L169 17 Z" fill="#1a1a1a" opacity="0.18"/>
            {/* 4-star sparkle — bottom left */}
            <path d="M36 130 L37.3 126 L38.6 130 L42 131.3 L38.6 132.6 L37.3 136 L36 132.6 L32.6 131.3 Z" fill="#1a1a1a" opacity="0.10"/>
            {/* Accent dots */}
            <circle cx="191" cy="88" r="4" fill="#888888" opacity="0.25"/>
            <circle cx="26" cy="56" r="2.5" fill="#1a1a1a" opacity="0.15"/>
            <circle cx="183" cy="139" r="2.5" fill="#cccccc" opacity="0.5"/>
          </svg>
        </div>

        {/* ── Copy ── */}
        <h2 className="jalpi-canvas__empty-title">Start building your page</h2>
        <p className="jalpi-canvas__empty-body">
          Add a section or import a template to get started.
        </p>

        {/* ── Actions ── */}
        <div className="jalpi-canvas__empty-actions">
          {/* Add Section — opens quick-add popover */}
          <div className="jalpi-sab-trigger-wrap">
            <button
              className={`jalpi-empty-btn${sectionPickerOpen ? ' is-active' : ''}`}
              onClick={() => setSectionPickerOpen((v) => !v)}
            >
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
                <path d="M12 5v14M5 12h14"/>
              </svg>
              Add Section
            </button>
            {sectionPickerOpen && (
              <SectionPicker
                store={store}
                onClose={() => setSectionPickerOpen(false)}
              />
            )}
          </div>

          {/* Template Library */}
          <button className="jalpi-empty-btn jalpi-empty-btn--outline" onClick={onImportTemplate}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
              <rect x="3" y="3" width="7" height="9" rx="1.5"/>
              <rect x="14" y="3" width="7" height="5" rx="1.5"/>
              <rect x="14" y="11" width="7" height="9" rx="1.5"/>
              <rect x="3" y="15" width="7" height="6" rx="1.5"/>
            </svg>
            Template Library
          </button>

        </div>

        {/* ── Keyboard hint ── */}
        <p className="jalpi-canvas__empty-hint">
          Press <kbd>⌘K</kbd> to open the command palette
        </p>

      </div>
    </div>
  );
}
