<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="$emit('select')"
  >
    <!-- Children (for container buttons) -->
    <WidgetElement
      v-for="child in children"
      :key="child.id"
      :widget="child"
      :scale="scale"
      :selected="store.selectedWidgetId === child.id"
      @select="store.selectedWidgetId = child.id"
      @drag-start="$emit('drag-start', $event)"
      @resize-start="$emit('resize-start', $event)"
    />

    <!-- With Icon (not container) -->
    <template v-if="hasIcon && !isContainer">
      <div :style="contentStyle">
        <span
          v-if="iconPosition === 0 || iconPosition === 2"
          class="material-symbols-outlined flex-shrink-0"
          :style="iconStyle"
        >{{ iconChar }}</span>
        <span class="flex-shrink-0">{{ widget.text }}</span>
        <span
          v-if="iconPosition === 1 || iconPosition === 3"
          class="material-symbols-outlined flex-shrink-0"
          :style="iconStyle"
        >{{ iconChar }}</span>
      </div>
    </template>

    <!-- Without Icon (not container) -->
    <template v-else-if="!isContainer">
      <span>{{ widget.text }}</span>
    </template>

    <!-- 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, defineAsyncComponent } from 'vue';
import { useEditorStore } from '../../../stores/editor';
import { fontSizes, iconFontSizes, ICON_POSITIONS } from '../../../constants';
import { getBaseStyle, justifyForAlign, getShadowStyle, getBorderStyle, clamp, hexToRgba } from '../shared/utils';

// Lazy import to avoid circular dependency
const WidgetElement = defineAsyncComponent(() => import('../../WidgetElement.vue'));

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

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

const store = useEditorStore();

const children = computed(() => {
  if (!store.activeScreen) return [];
  return store.activeScreen.widgets.filter(w => w.parentId === props.widget.id);
});

const isContainer = computed(() => props.widget.isContainer);
const hasIcon = computed(() => props.widget.iconCodepoint > 0);
const iconChar = computed(() => String.fromCodePoint(props.widget.iconCodepoint || 0xe88a));
const iconPosition = computed(() => props.widget.iconPosition || 0);
const textAlign = computed(() => props.widget.textAlign ?? 1);

const isVerticalLayout = computed(() => {
  return iconPosition.value === ICON_POSITIONS.TOP || iconPosition.value === ICON_POSITIONS.BOTTOM;
});

const contentStyle = computed(() => {
  const s = props.scale;
  const gap = (props.widget.iconGap || 8) * s;
  return {
    display: 'flex',
    flexDirection: isVerticalLayout.value ? 'column' : 'row',
    alignItems: 'center',
    justifyContent: justifyForAlign(textAlign.value),
    gap: `${gap}px`,
    width: '100%',
    height: '100%'
  };
});

const iconStyle = computed(() => {
  const s = props.scale;
  const sizeIdx = props.widget.iconSize ?? props.widget.fontSize ?? 1;
  const size = iconFontSizes[sizeIdx] || 18;
  return {
    fontSize: `${size * s}px`,
    color: props.widget.textColor
  };
});

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

  const style = getBaseStyle(w, s);

  const alpha = clamp((w.bgOpacity ?? 255) / 255, 0, 1);
  style.background = hexToRgba(w.bgColor, alpha);
  style.borderRadius = `${w.radius * s}px`;
  style.display = 'flex';
  style.alignItems = 'center';
  style.justifyContent = justifyForAlign(textAlign.value);
  style.fontWeight = '600';

  Object.assign(style, getBorderStyle(w, s));
  Object.assign(style, getShadowStyle(w, s));

  return style;
});
</script>
