import {
  ref,
  Ref,
  h,
  defineComponent,
  onMounted,
  onBeforeUnmount,
  PropType,
  watchEffect,
} from 'vue';
import { useInline } from '../inline';

export const SbContenteditable = defineComponent({
  name: 'sb-contenteditable',

  props: {
    inputRef: {
      type: (null as unknown) as PropType<Ref<HTMLElement|null>>,
      default: ref(null),
    },
    tag: { type: String, default: 'div' },

    value: { type: String, default: '' },

    onValueChange: {
      type: (null as unknown) as PropType<(value: string) => void>,
      default: (_:string) => {},
    },
  },

  setup(props) {
    const {
      registerClient,
      unregisterClient,
    } = useInline();
    const onKeyup = (event: KeyboardEvent) => {
      if (event.code !== 'Backspace' && event.code !== 'Delete') {
        return;
      }

      if (!props.inputRef.value) {
        return;
      }

      const textContent = props.inputRef.value.textContent;
      if (textContent === '') {
        props.inputRef.value.innerHTML = '';
      }
    };

    onMounted(() => {
      props.inputRef.value?.focus();
      registerClient(props.inputRef.value!);
    });

    watchEffect(() => {
      if (props.inputRef.value && props.inputRef.value.innerHTML != props.value) {
        props.inputRef.value.innerHTML = props.value;
      }
    });

    onBeforeUnmount(() => {
      unregisterClient(props.inputRef.value!);
    });

    return () => h(props.tag, {
      class: 'sb-contenteditable',
      contenteditable: 'true',
      ref: props.inputRef,
      onKeyup,
      onInput: () => {
        props.onValueChange(props.inputRef.value?.innerHTML || '');
      },
    });
  },
});
