<template>
  <div class="text-board-wrapper" :class="{ selected }"
    :style="{ width: '100%', height: '100%', position: 'relative' }">
    <div class="text-board" :style="textStyle">{{ text }}</div>
    <template v-if="selected">
      <div v-for="dir in ['tr', 'tl', 'br', 'bl']" :key="dir" class="resize-handle" :class="dir"
        @mousedown.stop="onResizeMouseDown($event, dir)"></div>
    </template>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue';
const emit = defineEmits(['resize']);
interface Props {
  text?: string;
  color?: string;
  fontSize?: string | number;
  fontWeight?: string | number;
  align?: 'left' | 'center' | 'right';
  width?: number;
  height?: number;
  selected?: boolean;
}
const props = defineProps<Props>();
const selected = computed(() => !!props.selected);
const textStyle = computed(() => ({
  color: props.color || '#222',
  fontSize: typeof props.fontSize === 'number' ? props.fontSize + 'px' : props.fontSize || '24px',
  fontWeight: props.fontWeight || 'normal',
  textAlign: props.align || 'center',
  width: '100%',
  height: '100%',
  display: 'flex',
  alignItems: 'center',
  justifyContent: props.align === 'left' ? 'flex-start' : props.align === 'right' ? 'flex-end' : 'center',
  userSelect: 'none',
}));

function onResizeMouseDown(e: MouseEvent, dir: string) {
  e.stopPropagation();
  const startX = e.clientX,
    startY = e.clientY;
  const startWidth = Number(props.width) || 200;
  const startHeight = Number(props.height) || 40;
  function onMove(ev: MouseEvent) {
    let newWidth = startWidth,
      newHeight = startHeight;
    if (dir.includes('r')) newWidth += ev.clientX - startX;
    if (dir.includes('l')) newWidth -= ev.clientX - startX;
    if (dir.includes('b')) newHeight += ev.clientY - startY;
    if (dir.includes('t')) newHeight -= ev.clientY - startY;
    emit('resize', { width: Math.max(20, newWidth), height: Math.max(20, newHeight) });
  }
  function onUp() {
    document.removeEventListener('mousemove', onMove);
    document.removeEventListener('mouseup', onUp);
  }
  document.addEventListener('mousemove', onMove);
  document.addEventListener('mouseup', onUp);
}
const text = computed(() => props.text || '双击编辑文本');
</script>

<style scoped>
.text-board-wrapper.selected {
  outline: 2px dashed #409eff;
  outline-offset: 0;
}

.resize-handle {
  width: 8px;
  height: 8px;
  background: #fff;
  border: 1.5px solid #409eff;
  border-radius: 50%;
  position: absolute;
  z-index: 2;
}

.resize-handle.tr {
  top: -4px;
  right: -4px;
  cursor: ne-resize;
}

.resize-handle.tl {
  top: -4px;
  left: -4px;
  cursor: nw-resize;
}

.resize-handle.br {
  bottom: -4px;
  right: -4px;
  cursor: se-resize;
}

.resize-handle.bl {
  bottom: -4px;
  left: -4px;
  cursor: sw-resize;
}

.text-board {
  width: 100%;
  height: 100%;
  background: transparent;
  outline: none;
  cursor: text;
  user-select: text;
}
</style>
