<template>
  <div
    class="widget"
    :class="{
      selected: selected,
      'widget-label': isLabel,
      'widget-button': isButton,
      'widget-led': isLed,
      'widget-icon': isIcon
    }"
    :style="computedStyle"
    @mousedown.stop="!isTabPage && $emit('drag-start', { id: widget.id, event: $event })"
    @touchstart.stop="!isTabPage && $emit('drag-start', { id: widget.id, event: $event })"
    @click.stop="$emit('select')"
  >
    <!-- Recursive Children -->
    <!-- Special handling for TabView to render structure -->
    <template v-if="isTabView">
        <div class="tabview-container" :class="'pos-'+tabPosition" :style="tabViewStyle">
            <div class="tab-buttons" :style="tabBtnsStyle">
                <div 
                    v-for="(child, idx) in children" 
                    :key="child.id"
                    class="tab-btn"
                    :class="{ active: activePageId === child.id }"
                    @click.stop="activeTabIndex = idx; store.selectedWidgetId = child.id"
                >
                    {{ child.text }}
                </div>
            </div>
            <div class="tab-content">
                <WidgetElement 
                    v-for="child in children" 
                    :key="child.id" 
                    :widget="child"
                    :scale="scale"
                    :selected="store.selectedWidgetId === child.id"
                    :style="{ display: activePageId === child.id ? 'block' : 'none' }"
                    @select="store.selectedWidgetId = child.id"
                    @drag-start="$emit('drag-start', $event)"
                    @resize-start="$emit('resize-start', $event)"
                />
            </div>
        </div>
    </template>
    
    <!-- Standard Recursive Children (for Buttons, Pages, etc) -->
    <template v-else>
        <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)"
        />
    </template>

    <!-- Icon-only Widget -->
    <template v-if="isIcon">
      <span class="material-symbols-outlined icon-display" :style="iconOnlyStyle">
        {{ iconChar }}
      </span>
    </template>

    <!-- Label/Button with Icon -->
    <template v-else-if="hasIcon">
      <div class="widget-content" :style="contentStyle">
        <span
          v-if="iconPosition === 0 || iconPosition === 2"
          class="material-symbols-outlined widget-icon"
          :style="iconStyle"
        >{{ iconChar }}</span>
        <span class="widget-text">{{ widget.text }}</span>
        <span
          v-if="iconPosition === 1 || iconPosition === 3"
          class="material-symbols-outlined widget-icon"
          :style="iconStyle"
        >{{ iconChar }}</span>
      </div>
    </template>

    <!-- Standard (no icon) -->
    <template v-else>
      <span v-if="!isTabView && !isTabPage">{{ widget.text }}</span>
    </template>

    <!-- Resize Handle (at end to be on top) -->
    <div
        v-if="selected"
        class="resize-handle"
        @mousedown.stop="$emit('resize-start', { id: widget.id, event: $event })"
        @touchstart.stop="$emit('resize-start', { id: widget.id, event: $event })"
    ></div>
  </div>
</template>

<script setup>
import { computed } from 'vue';
import { useEditorStore } from '../stores/editor';
import { WIDGET_TYPES, fontSizes, ICON_POSITIONS } from '../constants';
import { clamp, hexToRgba } from '../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 children = computed(() => {
    if (!store.activeScreen) return [];
    return store.activeScreen.widgets.filter(w => w.parentId === props.widget.id);
});

const isLabel = computed(() => props.widget.type === WIDGET_TYPES.LABEL);
const isButton = computed(() => props.widget.type === WIDGET_TYPES.BUTTON);
const isLed = computed(() => props.widget.type === WIDGET_TYPES.LED);
const isIcon = computed(() => props.widget.type === WIDGET_TYPES.ICON);
const isTabView = computed(() => props.widget.type === WIDGET_TYPES.TABVIEW);
const isTabPage = computed(() => props.widget.type === WIDGET_TYPES.TABPAGE);

const tabPosition = computed(() => props.widget.iconPosition || 0); // 0=Top, 1=Bottom...
const tabHeight = computed(() => (props.widget.iconSize || 5) * 10);

// Find active tab index (client-side state only, maybe store in widget temporarily?)
// For designer simplicity: show all tabs content stacked, or just first one?
// Better: mimic LVGL. We need state. Let's use a local ref or just show the selected one in tree?
// To keep it simple: Show the active tab based on which child is selected or default to first.
import { ref } from 'vue';
const activeTabIndex = ref(0);

const activePageId = computed(() => {
    // If a child page is selected, make it active
    const selectedChild = children.value.find(c => store.selectedWidgetId === c.id);
    if (selectedChild) return selectedChild.id;
    
    // If a widget inside a page is selected
    if (store.selectedWidget && store.selectedWidget.parentId !== -1) {
        // Find ancestor page
        let curr = store.selectedWidget;
        while (curr && curr.parentId !== -1 && curr.parentId !== props.widget.id) {
             curr = store.activeScreen.widgets.find(w => w.id === curr.parentId);
        }
        if (curr && curr.parentId === props.widget.id) return curr.id;
    }

    if (children.value.length > 0) return children.value[activeTabIndex.value]?.id;
    return -1;
});

const hasIcon = computed(() => {
    return (isLabel.value || isButton.value) && props.widget.iconCodepoint > 0;
});

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

const iconPosition = computed(() => props.widget.iconPosition || 0);

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: 'center',
        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 = fontSizes[sizeIdx] || 18;
    return {
        fontSize: `${size * s}px`,
        color: props.widget.textColor
    };
});

const iconOnlyStyle = 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 computedStyle = computed(() => {
    const w = props.widget;
    const s = props.scale;

    const style = {
        left: `${w.x * s}px`,
        top: `${w.y * s}px`,
        width: `${w.w * s}px`,
        height: `${w.h * s}px`,
        fontSize: `${(fontSizes[w.fontSize] || 14) * s}px`,
        color: w.textColor,
        position: 'absolute',
        zIndex: 1,
        cursor: 'move',
        userSelect: 'none',
        touchAction: 'none'
    };

    if (isIcon.value) {
        // Icon widget
        style.display = 'flex';
        style.alignItems = 'center';
        style.justifyContent = 'center';
        if (w.bgOpacity > 0) {
            const alpha = clamp(w.bgOpacity / 255, 0, 1).toFixed(2);
            style.background = hexToRgba(w.bgColor, alpha);
        }
        if (w.radius > 0) {
            style.borderRadius = `${w.radius * s}px`;
        }
    } else if (isLabel.value) {
        if (w.bgOpacity > 0) {
            const alpha = clamp(w.bgOpacity / 255, 0, 1).toFixed(2);
            style.background = hexToRgba(w.bgColor, alpha);
        }
        if (hasIcon.value) {
            style.display = 'flex';
            style.alignItems = 'center';
        }
    } else if (isButton.value) {
        style.background = w.bgColor;
        style.borderRadius = `${w.radius * s}px`;
        style.display = 'flex';
        style.alignItems = 'center';
        style.justifyContent = 'center';
        style.fontWeight = '600';

        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;
            style.boxShadow = `${sx}px ${sy}px ${blur}px ${spread}px ${w.shadow.color}`;
        }
    } else if (isLed.value) {
        style.borderRadius = '999px';

        const brightness = clamp((w.bgOpacity ?? 255) / 255, 0, 1);
        const glowColor = (w.shadow && w.shadow.color) ? w.shadow.color : w.bgColor;
        const highlight = clamp(brightness + 0.25, 0, 1);
        const core = clamp(brightness, 0, 1);
        const edge = clamp(brightness * 0.5, 0, 1);

        style.background = `radial-gradient(circle at 30% 30%, ${hexToRgba(w.bgColor, highlight)} 0%, ${hexToRgba(w.bgColor, core)} 45%, ${hexToRgba(w.bgColor, edge)} 70%, rgba(0,0,0,0.4) 100%)`;

        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.4 + brightness * 0.6, 0, 1);
            style.boxShadow = `${sx}px ${sy}px ${blur}px ${spread}px ${hexToRgba(glowColor, glowAlpha)}`;
        } else {
            style.boxShadow = 'inset 0 0 0 1px rgba(255,255,255,0.12)';
        }
    } else if (isTabView.value) {
        style.background = w.bgColor;
        style.borderRadius = `${w.radius * s}px`;
        // No flex here, we handle internal layout manually
    } else if (isTabPage.value) {
        style.position = 'relative'; // Relative to content area
        style.width = '100%';
        style.height = '100%';
        style.left = '0';
        style.top = '0';
    }

    return style;
});

const tabViewStyle = computed(() => {
    return {
        display: 'flex',
        flexDirection: tabPosition.value === 0 || tabPosition.value === 1 ? 'column' : 'row',
        height: '100%',
        width: '100%'
    };
});

const tabBtnsStyle = computed(() => {
    const s = props.scale;
    const h = tabHeight.value * s;
    const isVert = tabPosition.value === 0 || tabPosition.value === 1;
    
    return {
        [isVert ? 'height' : 'width']: `${h}px`,
        order: tabPosition.value === 1 || tabPosition.value === 3 ? 2 : 0, // Bottom/Right
        display: 'flex',
        flexDirection: isVert ? 'row' : 'column',
        background: 'rgba(0,0,0,0.2)',
        overflow: 'hidden'
    };
});
</script>

<style scoped>
.widget-content {
    display: flex;
    align-items: center;
    justify-content: center;
}

.widget-icon {
    flex-shrink: 0;
}

.widget-text {
    flex-shrink: 0;
}

.icon-display {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* TabView Styles */
.tabview-container {
    overflow: hidden;
}

.tab-content {
    flex: 1;
    position: relative;
    overflow: hidden;
}

.tab-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4px;
    cursor: pointer;
    font-size: 12px;
    border-right: 1px solid rgba(255,255,255,0.1);
    border-bottom: 1px solid rgba(255,255,255,0.1);
    user-select: none;
}

.tab-btn.active {
    background: rgba(255,255,255,0.1);
    font-weight: bold;
    border-bottom: 2px solid var(--accent);
}

.pos-2 .tab-btn, .pos-3 .tab-btn {
    border-right: none;
    border-bottom: 1px solid rgba(255,255,255,0.1);
}
.pos-2 .tab-btn.active, .pos-3 .tab-btn.active {
    border-bottom: none;
    border-right: 2px solid var(--accent);
}
</style>
