<template>
  <div
    class="z-[1] select-none touch-none"
    :class="selected ? 'outline outline-2 outline-accent outline-offset-2' : ''"
    :style="computedStyle"
    @mousedown.stop="$emit('drag-start', { id: widget.id, event: $event })"
    @touchstart.stop="$emit('drag-start', { id: widget.id, event: $event })"
    @click.stop="handleClick"
  >
    <div class="flex flex-col items-center justify-center w-full h-full text-center leading-tight">
      <span v-if="powerNodeParts.label" :style="powerNodeLabelStyle">{{ powerNodeParts.label }}</span>
      <span v-if="widget.iconCodepoint" class="material-symbols-outlined mt-1" :style="powerNodeIconStyle">
        {{ iconChar }}
      </span>
      <span v-if="powerNodeParts.value" class="mt-1" :style="powerNodeValueStyle">{{ powerNodeParts.value }}</span>
    </div>

    <!-- Resize Handle -->
    <div
      v-if="selected"
      class="absolute -right-1.5 -bottom-1.5 w-3.5 h-3.5 rounded-[4px] bg-accent border-[2px] border-[#1b1308] shadow-[0_4px_12px_rgba(0,0,0,0.35)] cursor-se-resize z-10"
      data-resize-handle
      @mousedown.stop="$emit('resize-start', { id: widget.id, event: $event })"
      @touchstart.stop="$emit('resize-start', { id: widget.id, event: $event })"
    >
      <span class="absolute right-[2px] bottom-[2px] w-[6px] h-[6px] border-r-2 border-b-2 border-[#1b1308a6] rounded-[2px]"></span>
    </div>
  </div>
</template>

<script setup>
import { computed } from 'vue';
import { useEditorStore } from '../../../stores/editor';
import { fontSizes } from '../../../constants';
import { getBaseStyle, getBorderStyle, clamp, hexToRgba, splitPowerNodeText } from '../shared/utils';

const props = defineProps({
  widget: { type: Object, required: true },
  scale: { type: Number, default: 1 },
  selected: { type: Boolean, default: false }
});

const emit = defineEmits(['select', 'drag-start', 'resize-start']);

const store = useEditorStore();

const iconChar = computed(() => {
  const cp = props.widget.iconCodepoint || 0xe88a;
  return String.fromCodePoint(cp);
});

const powerNodeParts = computed(() => splitPowerNodeText(props.widget.text));

const powerNodeValueSize = computed(() => {
  const sizeIdx = props.widget.fontSize ?? 2;
  const size = fontSizes[sizeIdx] || 22;
  return size * props.scale;
});

const powerNodeLabelSize = computed(() => {
  return Math.max(10 * props.scale, powerNodeValueSize.value * 0.55);
});

const powerNodeIconSize = computed(() => {
  const sizeIdx = props.widget.iconSize ?? props.widget.fontSize ?? 2;
  const size = fontSizes[sizeIdx] || 22;
  return size * props.scale;
});

const powerNodeIconStyle = computed(() => ({
  fontSize: `${powerNodeIconSize.value}px`,
  color: props.widget.textColor
}));

const powerNodeLabelStyle = computed(() => ({
  fontSize: `${powerNodeLabelSize.value}px`,
  color: hexToRgba(props.widget.textColor, 0.72)
}));

const powerNodeValueStyle = computed(() => ({
  fontSize: `${powerNodeValueSize.value}px`,
  color: props.widget.textColor,
  fontWeight: '600'
}));

const computedStyle = computed(() => {
  const w = props.widget;
  const s = props.scale;

  const style = getBaseStyle(w, s);

  const ringAlpha = clamp((w.bgOpacity ?? 255) / 255, 0, 1);
  const ring = Math.max(3, Math.round(Math.min(w.w, w.h) * 0.06 * s));

  style.display = 'flex';
  style.alignItems = 'center';
  style.justifyContent = 'center';
  style.borderRadius = '999px';
  style.background = hexToRgba('#ffffff', 0.96);
  if ((w.borderWidth || 0) > 0 && (w.borderOpacity ?? 0) > 0) {
    Object.assign(style, getBorderStyle(w, s));
  } else {
    style.border = `${ring}px solid ${hexToRgba(w.bgColor, ringAlpha)}`;
  }
  style.textAlign = 'center';

  if (w.shadow && w.shadow.enabled) {
    const sx = (w.shadow.x || 0) * s;
    const sy = (w.shadow.y || 0) * s;
    const blur = (w.shadow.blur || 0) * s;
    const spread = (w.shadow.spread || 0) * s;
    const glowAlpha = clamp(0.35 + ringAlpha * 0.5, 0, 1);
    style.boxShadow = `${sx}px ${sy}px ${blur}px ${spread}px ${hexToRgba(w.shadow.color || w.bgColor, glowAlpha)}`;
  } else {
    style.boxShadow = '0 8px 18px rgba(15, 23, 42, 0.12)';
  }

  if (store.powerLinkMode.active && store.powerLinkMode.powerflowId === w.parentId) {
    style.cursor = 'crosshair';
  }
  if (store.powerLinkMode.active && store.powerLinkMode.fromNodeId === w.id && store.powerLinkMode.powerflowId === w.parentId) {
    style.outline = `2px dashed ${hexToRgba('#4f8ad9', 0.9)}`;
    style.outlineOffset = '2px';
  }

  return style;
});

function handleClick() {
  if (store.powerLinkMode.active) {
    store.handlePowerNodeLink(props.widget.id, props.widget.parentId);
    return;
  }
  emit('select');
}
</script>
