<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')"
  >
    <!-- Bubble Style -->
    <template v-if="widget.cardStyle !== 1">
      <!-- Central Bubble -->
      <div class="absolute rounded-full flex flex-col items-center justify-center" :style="roomCardBubbleStyle">
        <span v-if="widget.iconCodepoint" class="material-symbols-outlined" :style="roomCardIconStyle">
          {{ iconChar }}
        </span>
        <span v-if="roomCardParts.name" class="leading-tight font-semibold" :style="roomCardNameStyle">{{ roomCardParts.name }}</span>
        <span v-if="roomCardParts.format" class="leading-tight opacity-70" :style="roomCardTempStyle">{{ roomCardParts.format }}</span>
      </div>
      <!-- Sub-Buttons (circular orbit) -->
      <div
        v-for="(sb, idx) in roomCardSubButtons"
        :key="idx"
        class="absolute rounded-full flex items-center justify-center shadow-md"
        :style="getSubButtonStyle(sb, idx)"
      >
        <span v-if="sb.icon" class="material-symbols-outlined" :style="getSubButtonIconStyle(sb)">
          {{ String.fromCodePoint(sb.icon) }}
        </span>
      </div>
    </template>

    <!-- Tile Style -->
    <template v-else>
      <div class="absolute inset-0 overflow-hidden" :style="roomCardTileContainerStyle">
        <!-- Room name (top-left) -->
        <div class="absolute" :style="{ left: '16px', top: '12px', color: widget.textColor, fontSize: fontSizes[widget.fontSize || 2] + 'px', fontWeight: 600 }">
          {{ roomCardParts.name }}
        </div>
        <!-- Text Lines -->
        <div class="absolute flex flex-col gap-1" :style="textLinesContainerStyle">
          <span v-for="(line, idx) in textLines" :key="idx" class="flex items-center gap-1" :style="getTextLineStyle(line)">
            <span v-if="line.icon" class="material-symbols-outlined" :style="{ fontSize: getTextLineIconSize(line) + 'px' }">{{ String.fromCodePoint(line.icon) }}</span>
            <span>{{ line.text || '--' }}</span>
          </span>
        </div>
        <!-- Large decorative icon (configurable position) -->
        <span v-if="widget.iconCodepoint" class="material-symbols-outlined absolute opacity-20" :style="decorIconStyle">
          {{ iconChar }}
        </span>
      </div>
      <!-- Sub-Buttons (right side, vertical) -->
      <div
        v-for="(sb, idx) in roomCardSubButtons"
        :key="idx"
        class="absolute rounded-full flex items-center justify-center shadow-md"
        :style="getSubButtonStyleTile(sb, idx)"
      >
        <span v-if="sb.icon" class="material-symbols-outlined" :style="getSubButtonIconStyle(sb)">
          {{ String.fromCodePoint(sb.icon) }}
        </span>
      </div>
    </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 } from 'vue';
import { fontSizes, iconFontSizes } from '../../../constants';
import { getBaseStyle, getBorderStyle, clamp, hexToRgba } from '../shared/utils';

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 iconChar = computed(() => {
  const cp = props.widget.iconCodepoint || 0xe88a;
  return String.fromCodePoint(cp);
});

const roomCardParts = computed(() => {
  if (!props.widget.text) return { name: '', format: '' };
  const parts = props.widget.text.split('\n');
  return {
    name: parts[0] || '',
    format: props.widget.cardStyle === 1 ? '' : (parts[1] || '')
  };
});

const roomCardSubButtons = computed(() => props.widget.subButtons || []);
const textLines = computed(() => props.widget.textLines || []);

const textLinesContainerStyle = computed(() => {
  const s = props.scale;
  // Calculate top based on room name position + font size + padding
  const roomNameTop = 12;
  const roomNameFontSize = fontSizes[props.widget.fontSize || 2] || 22;
  const padding = 10;
  const top = (roomNameTop + roomNameFontSize + padding) * s;
  return {
    left: (16 * s) + 'px',
    top: top + 'px',
    color: props.widget.textColor
  };
});

function getTextLineStyle(line) {
  const s = props.scale;
  const sizeIdx = line.fontSize ?? 1;
  return {
    fontSize: (fontSizes[sizeIdx] * s) + 'px'
  };
}

function getTextLineIconSize(line) {
  const s = props.scale;
  const sizeIdx = line.fontSize ?? 1;
  return fontSizes[sizeIdx] * s;
}

const roomCardTileContainerStyle = computed(() => {
  const alpha = (props.widget.bgOpacity ?? 255) / 255;
  return {
    backgroundColor: hexToRgba(props.widget.bgColor || '#333333', alpha),
    borderRadius: (props.widget.radius || 16) + 'px',
  };
});

const decorIconStyle = computed(() => {
  const s = props.scale;
  const w = props.widget;
  const x = (w.iconPositionX !== undefined && w.iconPositionX !== 0) ? w.iconPositionX * s : -20 * s;
  const y = (w.iconPositionY !== undefined && w.iconPositionY !== 0) ? w.iconPositionY * s : (w.h - 120) * s;
  const sizeIdx = w.iconSize >= 6 ? w.iconSize : 8;
  const fontSize = iconFontSizes[sizeIdx] || 96;

  return {
    left: x + 'px',
    top: y + 'px',
    fontSize: (fontSize * s) + 'px',
    color: w.textColor,
  };
});

const getSubButtonStyleTile = (sb, idx) => {
  const s = props.scale;
  const btnSize = (props.widget.subButtonSize || 40) * s;
  const gap = 10 * s;
  const padding = 12 * s;

  return {
    width: btnSize + 'px',
    height: btnSize + 'px',
    right: padding + 'px',
    top: (padding + idx * (btnSize + gap)) + 'px',
    backgroundColor: sb.colorOff || '#666666',
  };
};

const roomCardBubbleStyle = computed(() => {
  const s = props.scale;
  const w = props.widget.w;
  const h = props.widget.h;
  const subBtnSize = (props.widget.subButtonSize || 40) * s;
  const padding = subBtnSize * 0.6;
  const bubbleSize = Math.min(w, h) * s - padding * 2;
  const left = (w * s - bubbleSize) / 2;
  const top = (h * s - bubbleSize) / 2;
  const alpha = clamp((props.widget.bgOpacity ?? 255) / 255, 0, 1);

  return {
    width: `${bubbleSize}px`,
    height: `${bubbleSize}px`,
    left: `${left}px`,
    top: `${top}px`,
    backgroundColor: hexToRgba(props.widget.bgColor, alpha),
    color: props.widget.textColor,
    border: ((props.widget.borderWidth || 0) > 0 && (props.widget.borderOpacity ?? 0) > 0)
      ? `${(props.widget.borderWidth || 0) * s}px solid ${hexToRgba(props.widget.borderColor || '#ffffff', clamp((props.widget.borderOpacity ?? 0) / 255, 0, 1))}`
      : 'none',
    boxShadow: props.widget.shadow?.enabled
      ? `${(props.widget.shadow.x || 0) * s}px ${(props.widget.shadow.y || 0) * s}px ${(props.widget.shadow.blur || 0) * s}px ${hexToRgba(props.widget.shadow.color || '#000000', 0.3)}`
      : '0 4px 12px rgba(0,0,0,0.15)'
  };
});

const roomCardIconStyle = computed(() => {
  const s = props.scale;
  const sizeIdx = props.widget.iconSize ?? 3;
  const size = fontSizes[sizeIdx] || 28;
  return {
    fontSize: `${size * s}px`,
    color: props.widget.textColor
  };
});

const roomCardNameStyle = computed(() => {
  const s = props.scale;
  const sizeIdx = props.widget.fontSize ?? 2;
  const size = fontSizes[sizeIdx] || 22;
  return {
    fontSize: `${size * s * 0.7}px`,
    color: props.widget.textColor
  };
});

const roomCardTempStyle = computed(() => {
  const s = props.scale;
  const sizeIdx = props.widget.fontSize ?? 2;
  const size = fontSizes[sizeIdx] || 22;
  return {
    fontSize: `${size * s * 0.55}px`,
    color: props.widget.textColor
  };
});

function getSubButtonStyle(sb, idx) {
  const s = props.scale;
  const w = props.widget.w;
  const h = props.widget.h;
  const subBtnSize = (props.widget.subButtonSize || 40) * s;
  const centerX = w * s / 2;
  const centerY = h * s / 2;
  const orbitRadius = (props.widget.subButtonDistance || 80) * s;
  const pos = sb.pos ?? idx;
  const angle = (pos * (Math.PI / 4)) - (Math.PI / 2);
  const x = centerX + orbitRadius * Math.cos(angle) - subBtnSize / 2;
  const y = centerY + orbitRadius * Math.sin(angle) - subBtnSize / 2;
  const bgColor = sb.colorOff || '#666666';

  return {
    width: `${subBtnSize}px`,
    height: `${subBtnSize}px`,
    left: `${x}px`,
    top: `${y}px`,
    backgroundColor: bgColor,
    border: `2px solid ${hexToRgba('#ffffff', 0.3)}`
  };
}

function getSubButtonIconStyle(sb) {
  const s = props.scale;
  const subBtnSize = (props.widget.subButtonSize || 40) * s;
  const iconSize = subBtnSize * 0.5;
  return {
    fontSize: `${iconSize}px`,
    color: '#ffffff'
  };
}

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

  const style = getBaseStyle(w, s);

  if (w.cardStyle === 1) {
    const alpha = clamp((w.bgOpacity ?? 255) / 255, 0, 1);
    style.background = hexToRgba(w.bgColor || '#333333', alpha);
    style.borderRadius = `${(w.radius || 16) * s}px`;
    style.overflow = 'hidden';
    if ((w.borderWidth || 0) > 0 && (w.borderOpacity ?? 0) > 0) {
      Object.assign(style, getBorderStyle(w, s));
    } else if (w.shadow && w.shadow.enabled) {
      style.border = `3px solid ${w.shadow.color || '#ff6b6b'}`;
    }
  } else {
    style.overflow = 'visible';
  }

  return style;
});
</script>
