import React, { CSSProperties, useCallback, useRef, useEffect } from 'react';
import { useNode, UserComponent } from '@craftjs/core';
import { cssPropsToString } from '../../utils/style-helpers';
import { escapeHtml } from '../../utils/escape';

interface TextBlockProps {
  text?: string;
  style?: CSSProperties;
  cssId?: string;
  cssClass?: string;
  hideOnDesktop?: boolean;
  hideOnTablet?: boolean;
  hideOnMobile?: boolean;
  animation?: string;
  animationDelay?: string;
}

export const TextBlock: UserComponent<TextBlockProps> = ({
  text = 'Start typing here...',
  style = {},
}) => {
  const {
    connectors: { connect, drag },
    selected,
    actions: { setProp },
  } = useNode((node) => ({
    selected: node.events.selected,
  }));

  const elRef = useRef<HTMLParagraphElement | null>(null);
  const editedTextRef = useRef<string | null>(null);

  const commitText = useCallback(() => {
    if (elRef.current) {
      const newText = elRef.current.innerText;
      editedTextRef.current = newText;
      setProp((p: TextBlockProps) => { p.text = newText; });
    }
  }, [setProp]);

  const handleBlur = useCallback(() => { commitText(); }, [commitText]);

  useEffect(() => {
    if (!selected && editedTextRef.current !== null) {
      setProp((p: TextBlockProps) => { p.text = editedTextRef.current!; });
      editedTextRef.current = null;
    }
  }, [selected, setProp]);

  useEffect(() => {
    if (elRef.current && !selected && editedTextRef.current === null) {
      elRef.current.innerText = text || '';
    }
  }, [text, selected]);

  return (
    <p
      ref={(ref: HTMLParagraphElement | null) => {
        elRef.current = ref;
        if (ref) connect(drag(ref));
      }}
      contentEditable={selected}
      suppressContentEditableWarning
      onBlur={handleBlur}
      onInput={() => { if (elRef.current) editedTextRef.current = elRef.current.innerText; }}
      style={{
        outline: 'none',
        cursor: selected ? 'text' : 'pointer',
        minHeight: '1em',
        ...style,
      }}
    />
  );
};

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

TextBlock.craft = {
  displayName: 'Text',
  props: {
    text: 'Start typing here...',
    style: {
      fontSize: '16px',
      lineHeight: '1.6',
      color: '#3f3f46',
      letterSpacing: '',
      textTransform: '' as CSSProperties['textTransform'],
      fontStyle: '' as CSSProperties['fontStyle'],
      textDecoration: '',
      marginTop: '', marginRight: '', marginBottom: '', marginLeft: '',
      paddingTop: '', paddingRight: '', paddingBottom: '', paddingLeft: '',
      border: 'none',
      boxShadow: 'none',
      opacity: '1',
    },
    animation: '',
    animationDelay: '0',
    hideOnDesktop: false,
    hideOnTablet: false,
    hideOnMobile: false,
  },
  rules: {
    canDrag: () => true,
    canMoveIn: () => false,
    canMoveOut: () => true,
  },
};

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

(TextBlock as any).toHtml = (props: TextBlockProps, _childrenHtml: string) => {
  const styleStr = cssPropsToString(props.style);
  const escapedText = escapeHtml(props.text || '');
  return { html: `<p${styleStr ? ` style="${styleStr}"` : ''}>${escapedText}</p>` };
};
