import React, { CSSProperties, useState } from 'react';
import { useNode, UserComponent } from '@craftjs/core';
import { cssPropsToString } from '../../utils/style-helpers';
import { usePages } from '../../state/PageContext';
import { escapeHtml, escapeAttr } from '../../utils/escape';

/* ---------- Types ---------- */

interface MenuLink {
  text: string;
  href: string;
  isExternal?: boolean;
  isCta?: boolean;
}

interface MenuProps {
  links?: MenuLink[];
  alignment?: 'left' | 'center' | 'right';
  linkColor?: string;
  linkHoverColor?: string;
  ctaBgColor?: string;
  ctaTextColor?: string;
  gap?: string;
  orientation?: 'horizontal' | 'vertical';
  fontSize?: string;
  style?: CSSProperties;
}

/* ---------- Defaults ---------- */

const defaultLinks: MenuLink[] = [
  { text: 'Home', href: '/' },
  { text: 'About', href: '#about' },
  { text: 'Services', href: '#services' },
  { text: 'Contact', href: '#contact', isCta: true },
];

/* ---------- Component ---------- */

export const Menu: UserComponent<MenuProps> = ({
  links = defaultLinks,
  alignment = 'right',
  linkColor = '#3f3f46',
  linkHoverColor = '#3b82f6',
  ctaBgColor = '#3b82f6',
  ctaTextColor = '#ffffff',
  gap = '24px',
  orientation = 'horizontal',
  fontSize = '14px',
  style = {},
}) => {
  const {
    connectors: { connect, drag },
  } = useNode();

  const [hoveredLink, setHoveredLink] = useState<number | null>(null);

  const justifyMap = { left: 'flex-start', center: 'center', right: 'flex-end' };

  return (
    <nav
      ref={(ref: HTMLElement | null): void => { if (ref) connect(drag(ref)); }}
      style={{
        display: 'flex',
        flexDirection: orientation === 'vertical' ? 'column' : 'row',
        alignItems: orientation === 'vertical' ? (alignment === 'center' ? 'center' : alignment === 'right' ? 'flex-end' : 'flex-start') : 'center',
        justifyContent: orientation === 'horizontal' ? justifyMap[alignment] : undefined,
        gap,
        flexWrap: 'wrap',
        ...style,
      }}
    >
      {links.map((link, i) => (
        <a
          key={i}
          href={link.href}
          target={link.isExternal ? '_blank' : undefined}
          rel={link.isExternal ? 'noopener noreferrer' : undefined}
          onClick={(e) => e.preventDefault()}
          onMouseEnter={() => setHoveredLink(i)}
          onMouseLeave={() => setHoveredLink(null)}
          style={{
            textDecoration: 'none',
            fontSize,
            fontWeight: link.isCta ? '600' : '400',
            color: link.isCta
              ? ctaTextColor
              : (hoveredLink === i ? linkHoverColor : linkColor),
            backgroundColor: link.isCta ? ctaBgColor : 'transparent',
            padding: link.isCta ? '8px 20px' : '0',
            borderRadius: link.isCta ? '6px' : '0',
            transition: 'color 0.15s, background-color 0.15s',
            ...(link.isCta && hoveredLink === i ? { filter: 'brightness(1.1)' } : {}),
          }}
        >
          {link.text}
        </a>
      ))}
    </nav>
  );
};

/* ---------- Settings panel ---------- */

const MenuSettings: React.FC = () => {
  const { actions: { setProp }, props } = useNode((node) => ({
    props: node.data.props as MenuProps,
  }));

  const { pages } = usePages();
  const links = props.links || defaultLinks;

  /* Drag state for reordering */
  const [dragIdx, setDragIdx] = useState<number | null>(null);
  const [dragOverIdx, setDragOverIdx] = useState<number | null>(null);

  /* ---- Link management ---- */

  const updateLink = (index: number, field: keyof MenuLink, value: string | boolean) => {
    setProp((p: MenuProps) => {
      const updated = [...(p.links || defaultLinks)];
      updated[index] = { ...updated[index], [field]: value };
      p.links = updated;
    });
  };

  const addLink = (link?: Partial<MenuLink>) => {
    setProp((p: MenuProps) => {
      p.links = [...(p.links || defaultLinks), { text: 'Link', href: '#', ...link }];
    });
  };

  const removeLink = (index: number) => {
    setProp((p: MenuProps) => {
      const updated = [...(p.links || defaultLinks)];
      updated.splice(index, 1);
      p.links = updated;
    });
  };

  const moveLink = (fromIdx: number, toIdx: number) => {
    if (fromIdx === toIdx) return;
    setProp((p: MenuProps) => {
      const updated = [...(p.links || defaultLinks)];
      const [moved] = updated.splice(fromIdx, 1);
      updated.splice(toIdx, 0, moved);
      p.links = updated;
    });
  };

  /* ---- Shared styles ---- */
  const labelStyle: CSSProperties = { fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 4 };
  const inputStyle: CSSProperties = {
    width: '100%', padding: '3px 6px', background: '#27272a', color: '#e4e4e7',
    border: '1px solid #3f3f46', borderRadius: 4, fontSize: 11,
  };
  const sectionStyle: CSSProperties = {
    borderBottom: '1px solid #27272a', paddingBottom: 12,
  };
  const btnSmall: CSSProperties = {
    padding: '2px 6px', fontSize: 11, background: '#27272a', color: '#a1a1aa',
    border: '1px solid #3f3f46', borderRadius: 4, cursor: 'pointer',
  };
  const btnActive: CSSProperties = {
    ...btnSmall, background: '#3b82f6', color: '#fff', borderColor: '#3b82f6',
  };

  const textColorPresets = ['#1f2937', '#374151', '#3f3f46', '#6b7280', '#ffffff', '#e4e4e7', '#a1a1aa', '#3b82f6'];
  const gapPresets = ['8px', '16px', '24px', '32px', '40px'];

  return (
    <div style={{ padding: '12px', display: 'flex', flexDirection: 'column', gap: '14px' }}>

      {/* ===== Style Section ===== */}
      <div style={sectionStyle}>
        <label style={{ ...labelStyle, fontWeight: 600, fontSize: 12, marginBottom: 8 }}>Menu Style</label>

        {/* Link color */}
        <div style={{ marginBottom: 8 }}>
          <label style={labelStyle}>Link Color</label>
          <div style={{ display: 'flex', gap: 3, flexWrap: 'wrap', alignItems: 'center' }}>
            {textColorPresets.map((c) => (
              <button
                key={c}
                onClick={() => setProp((p: MenuProps) => { p.linkColor = c; })}
                style={{
                  width: 22, height: 22, borderRadius: 4, border: '1px solid #3f3f46',
                  backgroundColor: c, cursor: 'pointer',
                  outline: props.linkColor === c ? '2px solid #3b82f6' : 'none',
                  outlineOffset: 1,
                }}
              />
            ))}
            <input
              type="color"
              value={props.linkColor || '#3f3f46'}
              onChange={(e) => setProp((p: MenuProps) => { p.linkColor = e.target.value; })}
              style={{ width: 22, height: 22, padding: 0, border: '1px solid #3f3f46', borderRadius: 3, cursor: 'pointer', background: 'none' }}
              title="Custom color"
            />
          </div>
        </div>

        {/* Hover color */}
        <div style={{ marginBottom: 8 }}>
          <label style={labelStyle}>Hover Color</label>
          <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
            <input
              type="color"
              value={props.linkHoverColor || '#3b82f6'}
              onChange={(e) => setProp((p: MenuProps) => { p.linkHoverColor = e.target.value; })}
              style={{ width: 28, height: 24, padding: 0, border: '1px solid #3f3f46', borderRadius: 3, cursor: 'pointer', background: 'none' }}
            />
            <span style={{ fontSize: 10, color: '#71717a' }}>{props.linkHoverColor || '#3b82f6'}</span>
          </div>
        </div>

        {/* CTA button colors */}
        <div style={{ marginBottom: 8 }}>
          <label style={labelStyle}>CTA Button</label>
          <div style={{ display: 'flex', gap: 8 }}>
            <div>
              <span style={{ fontSize: 9, color: '#71717a' }}>BG</span>
              <input
                type="color"
                value={props.ctaBgColor || '#3b82f6'}
                onChange={(e) => setProp((p: MenuProps) => { p.ctaBgColor = e.target.value; })}
                style={{ display: 'block', width: 28, height: 20, padding: 0, border: '1px solid #3f3f46', borderRadius: 3, cursor: 'pointer', background: 'none' }}
              />
            </div>
            <div>
              <span style={{ fontSize: 9, color: '#71717a' }}>Text</span>
              <input
                type="color"
                value={props.ctaTextColor || '#ffffff'}
                onChange={(e) => setProp((p: MenuProps) => { p.ctaTextColor = e.target.value; })}
                style={{ display: 'block', width: 28, height: 20, padding: 0, border: '1px solid #3f3f46', borderRadius: 3, cursor: 'pointer', background: 'none' }}
              />
            </div>
          </div>
        </div>

        {/* Font size */}
        <div style={{ marginBottom: 8 }}>
          <label style={labelStyle}>Font Size</label>
          <input
            type="text"
            value={props.fontSize || '14px'}
            onChange={(e) => setProp((p: MenuProps) => { p.fontSize = e.target.value; })}
            placeholder="14px"
            style={inputStyle}
          />
        </div>

        {/* Alignment */}
        <div style={{ marginBottom: 8 }}>
          <label style={labelStyle}>Alignment</label>
          <div style={{ display: 'flex', gap: 4 }}>
            {(['left', 'center', 'right'] as const).map((a) => (
              <button
                key={a}
                onClick={() => setProp((p: MenuProps) => { p.alignment = a; })}
                style={(props.alignment || 'right') === a ? btnActive : btnSmall}
              >
                {a.charAt(0).toUpperCase() + a.slice(1)}
              </button>
            ))}
          </div>
        </div>

        {/* Orientation */}
        <div style={{ marginBottom: 8 }}>
          <label style={labelStyle}>Orientation</label>
          <div style={{ display: 'flex', gap: 4 }}>
            {(['horizontal', 'vertical'] as const).map((o) => (
              <button
                key={o}
                onClick={() => setProp((p: MenuProps) => { p.orientation = o; })}
                style={(props.orientation || 'horizontal') === o ? btnActive : btnSmall}
              >
                {o.charAt(0).toUpperCase() + o.slice(1)}
              </button>
            ))}
          </div>
        </div>

        {/* Gap */}
        <div>
          <label style={labelStyle}>Gap</label>
          <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
            {gapPresets.map((g) => (
              <button
                key={g}
                onClick={() => setProp((p: MenuProps) => { p.gap = g; })}
                style={(props.gap || '24px') === g ? btnActive : btnSmall}
              >
                {g}
              </button>
            ))}
          </div>
        </div>
      </div>

      {/* ===== Links Section ===== */}
      <div>
        <label style={{ ...labelStyle, fontWeight: 600, fontSize: 12, marginBottom: 8 }}>Links</label>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {links.map((link, i) => (
            <div
              key={i}
              draggable
              onDragStart={() => setDragIdx(i)}
              onDragOver={(e) => { e.preventDefault(); setDragOverIdx(i); }}
              onDragEnd={() => {
                if (dragIdx !== null && dragOverIdx !== null) {
                  moveLink(dragIdx, dragOverIdx);
                }
                setDragIdx(null);
                setDragOverIdx(null);
              }}
              style={{
                background: dragOverIdx === i && dragIdx !== null && dragIdx !== i ? '#1e293b' : '#1e1e22',
                borderRadius: 6,
                padding: 8,
                display: 'flex',
                flexDirection: 'column',
                gap: 4,
                border: dragOverIdx === i && dragIdx !== null && dragIdx !== i ? '1px solid #3b82f6' : '1px solid transparent',
                transition: 'background 0.1s, border-color 0.1s',
              }}
            >
              {/* Row 1: drag handle + text + delete */}
              <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
                <span
                  style={{ cursor: 'grab', color: '#52525b', fontSize: 12, padding: '0 2px', userSelect: 'none', flexShrink: 0 }}
                  title="Drag to reorder"
                >
                  <i className="fa fa-bars" />
                </span>
                <input
                  type="text"
                  value={link.text}
                  onChange={(e) => updateLink(i, 'text', e.target.value)}
                  placeholder="Text"
                  style={{ ...inputStyle, flex: 1 }}
                />
                <button
                  onClick={() => removeLink(i)}
                  style={{ padding: '2px 6px', fontSize: 11, background: '#ef4444', color: '#fff', border: 'none', borderRadius: 4, cursor: 'pointer', flexShrink: 0 }}
                  title="Delete link"
                >
                  <i className="fa fa-trash" />
                </button>
              </div>

              {/* Row 2: URL */}
              <input
                type="text"
                value={link.href}
                onChange={(e) => updateLink(i, 'href', e.target.value)}
                placeholder="URL (e.g. /about or https://...)"
                style={inputStyle}
              />

              {/* Row 3: checkboxes */}
              <div style={{ display: 'flex', gap: 8 }}>
                <label style={{ fontSize: 10, color: '#a1a1aa', display: 'flex', alignItems: 'center', gap: 3, cursor: 'pointer' }}>
                  <input type="checkbox" checked={!!link.isExternal} onChange={(e) => updateLink(i, 'isExternal', e.target.checked)} />
                  External
                </label>
                <label style={{ fontSize: 10, color: '#a1a1aa', display: 'flex', alignItems: 'center', gap: 3, cursor: 'pointer' }}>
                  <input type="checkbox" checked={!!link.isCta} onChange={(e) => updateLink(i, 'isCta', e.target.checked)} />
                  CTA
                </label>
              </div>
            </div>
          ))}
        </div>

        {/* Add link button */}
        <button
          onClick={() => addLink()}
          style={{ marginTop: 6, width: '100%', padding: '6px', fontSize: 11, background: '#27272a', color: '#e4e4e7', border: '1px solid #3f3f46', borderRadius: 4, cursor: 'pointer' }}
        >
          + Add Link
        </button>

        {/* Add page dropdown */}
        <select
          onChange={(e) => {
            const page = pages.find(p => p.id === e.target.value);
            if (page) {
              addLink({
                text: page.name,
                href: page.slug === 'index' ? '/' : page.slug,
                isExternal: false,
                isCta: false,
              });
            }
            e.target.value = '';
          }}
          value=""
          style={{
            marginTop: 4, width: '100%', padding: '6px', fontSize: 11,
            background: '#1e293b', color: '#93c5fd',
            border: '1px solid #334155', borderRadius: 4, cursor: 'pointer',
          }}
        >
          <option value="">+ Add Page...</option>
          {pages.map(p => (
            <option key={p.id} value={p.id}>
              {p.name} ({p.slug === 'index' ? '/' : p.slug})
            </option>
          ))}
        </select>
      </div>
    </div>
  );
};

/* ---------- Craft config ---------- */

Menu.craft = {
  displayName: 'Menu',
  props: {
    links: defaultLinks,
    alignment: 'right',
    linkColor: '#3f3f46',
    linkHoverColor: '#3b82f6',
    ctaBgColor: '#3b82f6',
    ctaTextColor: '#ffffff',
    gap: '24px',
    orientation: 'horizontal',
    fontSize: '14px',
    style: {},
  } as MenuProps,
  rules: {
    canDrag: () => true,
    canMoveIn: () => false,
    canMoveOut: () => true,
  },
  related: {
    settings: MenuSettings,
  },
};

/* ---------- HTML export ---------- */

(Menu as any).toHtml = (props: MenuProps, _childrenHtml: string) => {
  const linkCol = props.linkColor || '#3f3f46';
  const hoverCol = props.linkHoverColor || '#3b82f6';
  const ctaBg = props.ctaBgColor || '#3b82f6';
  const ctaText = props.ctaTextColor || '#ffffff';
  const gap = props.gap || '24px';
  const orientation = props.orientation || 'horizontal';
  const alignment = props.alignment || 'right';
  const fSize = props.fontSize || '14px';

  const justifyMap: Record<string, string> = { left: 'flex-start', center: 'center', right: 'flex-end' };

  const navStyle = cssPropsToString({
    display: 'flex',
    flexDirection: orientation === 'vertical' ? 'column' : 'row',
    alignItems: orientation === 'vertical'
      ? (alignment === 'center' ? 'center' : alignment === 'right' ? 'flex-end' : 'flex-start')
      : 'center',
    justifyContent: orientation === 'horizontal' ? justifyMap[alignment] : undefined,
    gap,
    flexWrap: 'wrap',
    ...props.style,
  });

  const links = props.links || defaultLinks;

  // Unique ID suffix for scoped CSS
  const scopeId = `menu-${Math.random().toString(36).slice(2, 8)}`;

  const linksHtml = links.map((link) => {
    const target = link.isExternal ? ' target="_blank" rel="noopener noreferrer"' : '';
    const cls = link.isCta ? `${scopeId}-cta` : `${scopeId}-link`;
    const linkStyle = cssPropsToString({
      textDecoration: 'none',
      fontSize: fSize,
      fontWeight: link.isCta ? '600' : '400',
      color: link.isCta ? ctaText : linkCol,
      backgroundColor: link.isCta ? ctaBg : 'transparent',
      padding: link.isCta ? '8px 20px' : '0',
      borderRadius: link.isCta ? '6px' : '0',
      transition: 'color 0.15s, background-color 0.15s',
    });
    return `<a href="${escapeAttr(link.href)}" class="${cls}"${target}${linkStyle ? ` style="${linkStyle}"` : ''}>${escapeHtml(link.text)}</a>`;
  }).join('\n    ');

  const hoverCss = `<style>
  .${scopeId}-link:hover { color: ${hoverCol} !important; }
  .${scopeId}-cta:hover { filter: brightness(1.1); }
</style>`;

  return {
    html: `${hoverCss}
<nav${navStyle ? ` style="${navStyle}"` : ''}>
    ${linksHtml}
</nav>`,
  };
};
