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

interface ButtonLinkProps {
  text?: string;
  href?: string;
  target?: '_self' | '_blank';
  style?: CSSProperties;
  /** Background color applied on `:hover` via a scoped `<style>` block
   *  (editor preview does not show hover state -- only the published
   *  export). Blank means "no hover background override". */
  hoverBg?: string;
  /** Text color applied on `:hover`, same scoped `<style>` block. */
  hoverColor?: string;
  animation?: string;
  animationDelay?: string;
  hideOnDesktop?: boolean;
  hideOnTablet?: boolean;
  hideOnMobile?: boolean;
}

export const ButtonLink: UserComponent<ButtonLinkProps> = ({
  text = 'Click Me',
  href = '#',
  target = '_self',
  style = {},
  hoverBg = '',
  hoverColor = '',
}) => {
  const {
    connectors: { connect, drag },
    selected,
  } = useNode((node) => ({
    selected: node.events.selected,
  }));

  const [hovered, setHovered] = React.useState(false);

  return (
    <a
      ref={(ref: HTMLAnchorElement | null) => { if (ref) connect(drag(ref)); }}
      href={href}
      target={target}
      onClick={(e) => {
        // Prevent navigation inside editor
        e.preventDefault();
      }}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{
        display: 'inline-block',
        textDecoration: 'none',
        cursor: 'pointer',
        outline: selected ? '2px solid #3b82f6' : 'none',
        ...style,
        ...(hovered && hoverBg ? { backgroundColor: hoverBg } : {}),
        ...(hovered && hoverColor ? { color: hoverColor } : {}),
      }}
    >
      {text}
    </a>
  );
};

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

ButtonLink.craft = {
  displayName: 'Button',
  props: {
    text: 'Click Me',
    href: '#',
    target: '_self',
    hoverBg: '',
    hoverColor: '',
    style: {
      backgroundColor: '#3b82f6',
      color: '#ffffff',
      padding: '12px 24px',
      borderRadius: '8px',
      fontWeight: '600',
      fontSize: '16px',
      border: 'none',
      marginTop: '', marginRight: '', marginBottom: '', marginLeft: '',
      boxShadow: 'none',
      opacity: '1',
    },
    animation: '',
    animationDelay: '0',
    hideOnDesktop: false,
    hideOnTablet: false,
    hideOnMobile: false,
  },
  rules: {
    canDrag: () => true,
    canMoveIn: () => false,
    canMoveOut: () => true,
  },
};

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

(ButtonLink as any).toHtml = (props: ButtonLinkProps, _childrenHtml: string, nodeId?: string) => {
  const styleStr = cssPropsToString({
    display: 'inline-block',
    textDecoration: 'none',
    ...props.style,
  });
  const escapedText = escapeHtml(props.text || '');
  const targetAttr = props.target === '_blank' ? ' target="_blank" rel="noopener noreferrer"' : '';

  // Scoped hover style -- same pattern as Navbar/Menu: a deterministic,
  // per-node class (via scopeId) avoids two ButtonLink instances on the
  // same page colliding on a shared `.btn-link:hover` rule. hoverBg/
  // hoverColor are sanitized through cssValue -- they land inside a
  // `<style>` element, the worst-case XSS sink (an unescaped `<`/`>` or
  // `{`/`}` could close the rule/element and open a `<script>`).
  const hoverBg = cssValue(props.hoverBg);
  const hoverColor = cssValue(props.hoverColor);
  let hoverCss = '';
  let cls = '';
  if (hoverBg || hoverColor) {
    const scope = scopeId(nodeId, (props.href || '') + (props.text || ''), 'btn');
    cls = ` class="${scope}"`;
    const decls = [
      hoverBg ? `background-color:${hoverBg}` : '',
      hoverColor ? `color:${hoverColor}` : '',
    ].filter(Boolean).join(';');
    hoverCss = `<style>.${scope}:hover{${decls}}</style>`;
  }

  return {
    html: `${hoverCss}<a href="${escapeAttr(safeUrl(props.href || '#'))}"${targetAttr}${cls}${styleStr ? ` style="${styleStr}"` : ''}>${escapedText}</a>`,
  };
};
