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

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

interface MenuLink {
  text: string;
  href: string;
  isExternal?: boolean;
  isCta?: boolean;
  /** Adds the `download` attribute to the exported anchor (F3: links to files). */
  download?: 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;
  hideOnDesktop?: boolean;
  hideOnTablet?: boolean;
  hideOnMobile?: boolean;
  animation?: string;
  animationDelay?: string;
}

/* ---------- 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}
          download={link.download || 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>
  );
};

/* ---------- 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: {},
    hideOnDesktop: false,
    hideOnTablet: false,
    hideOnMobile: false,
    animation: 'none',
    animationDelay: '0',
  } as MenuProps,
  rules: {
    canDrag: () => true,
    canMoveIn: () => false,
    canMoveOut: () => true,
  },
};

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

(Menu as any).toHtml = (props: MenuProps, _childrenHtml: string, nodeId?: string) => {
  // Sanitized once here -- linkCol/hoverCol/ctaBg/ctaText/gap/fSize are raw
  // string-interpolation sinks below (hoverCol goes into a <style> block,
  // the worst case: </style> breakout -> arbitrary <script>), see
  // task-cssxss-brief.md.
  const linkCol = cssValue(props.linkColor) || '#3f3f46';
  const hoverCol = cssValue(props.linkHoverColor) || '#3b82f6';
  const ctaBg = cssValue(props.ctaBgColor) || '#3b82f6';
  const ctaText = cssValue(props.ctaTextColor) || '#ffffff';
  const gap = cssValue(props.gap) || '24px';
  const orientation = props.orientation || 'horizontal';
  const alignment = props.alignment || 'right';
  const fSize = cssValue(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;

  // Scope for the hover CSS classes below. Deterministic AND unique: scoped
  // on the Craft node id so two Menu instances with identical/default links
  // don't collide on the same `.menu-link`/`.menu-cta` class names (which
  // would let one instance's hover styling bleed into the other's).
  const scope = scopeId(nodeId, JSON.stringify(links) + orientation + alignment, 'menu');

  const linksHtml = links.map((link) => {
    const target = link.isExternal ? ' target="_blank" rel="noopener noreferrer"' : '';
    const downloadAttr = link.download ? ' download' : '';
    const cls = link.isCta ? `${scope}-cta` : `${scope}-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(safeUrl(link.href || '#'))}" class="${cls}"${target}${downloadAttr}${linkStyle ? ` style="${linkStyle}"` : ''}>${escapeHtml(link.text)}</a>`;
  }).join('\n    ');

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

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