<template>
  <div class="group-tree-item">
    <div
      :class="['group-item-content', { selected: isSelected, 'has-children': hasChildren }]"
      :style="{ paddingLeft: `${16 + level * 24}px` }"
      @click="handleSelect"
    >
      <!-- 展开/折叠按钮 -->
      <div v-if="hasChildren" class="toggle-icon" @click.stop="handleToggle">
        <IconChevronDown v-if="isExpanded" :size="16" :stroke-width="2" />
        <IconChevronRight v-else :size="16" :stroke-width="2" />
      </div>
      <div v-else class="toggle-placeholder" />

      <!-- 设备图标 -->
      <div class="device-icon" :style="iconStyle">
        <component :is="iconComponent" :size="18" :stroke-width="1.5" />
      </div>

      <!-- 设备信息 -->
      <div class="device-info">
        <div class="device-name">
          {{ nodeData?.label || group.name }}
          <span v-if="nodeData?.status === 'error'" class="status-dot status-error" />
          <span v-else-if="nodeData?.status === 'warning'" class="status-dot status-warning" />
        </div>
        <div class="device-meta">
          <span v-if="nodeData?.ip" class="ip-address">{{ nodeData.ip }}</span>
          <span v-if="nodeData?.alerts && nodeData?.alerts > 0" class="alert-indicator">{{ nodeData.alerts }} 告警</span>
        </div>
      </div>

      <!-- 子节点数量 -->
      <div v-if="hasChildren" class="children-count">
        {{ group.children?.length || 0 }}
      </div>
    </div>

    <!-- 子分组 -->
    <div v-if="hasChildren && isExpanded" class="children-container">
      <group-tree-item
        v-for="child in group.children"
        :key="child.id"
        :group="child"
        :level="level + 1"
        :selected-group="selectedGroup"
        :expanded-groups="expandedGroups"
        :nodes="nodes"
        @select="$emit('select', $event)"
        @toggle="$emit('toggle', $event)"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { Node } from '@vue-flow/core'
import { DEVICE_TYPE_CONFIG } from '../config'
import type { TopoGroup, NodeData, DeviceType } from '../types'
import { IconChevronDown, IconChevronRight, IconServer } from '@tabler/icons-vue'

interface Props {
  group: TopoGroup
  level: number
  selectedGroup: string | null
  expandedGroups: Set<string>
  nodes: Node[]
}

interface Emits {
  (e: 'select', groupId: string): void
  (e: 'toggle', groupId: string): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const nodeData = computed(() => {
  const node = props.nodes.find((n) => n.id === props.group.nodeId)
  return (node?.data as NodeData) || null
})

const hasChildren = computed(() => {
  return props.group.children && props.group.children.length > 0
})

const isExpanded = computed(() => {
  return props.expandedGroups.has(props.group.id)
})

const isSelected = computed(() => {
  return props.selectedGroup === props.group.id
})

const deviceConfig = computed(() => {
  if (!nodeData.value) return null
  return DEVICE_TYPE_CONFIG[nodeData.value.type as DeviceType]
})

const iconComponent = computed(() => {
  return deviceConfig.value?.icon || IconServer
})

const iconStyle = computed(() => {
  const color = deviceConfig.value?.color || '#6B7280'
  return {
    background: `linear-gradient(135deg, ${color}15 0%, ${color}20 100%)`,
    color: color,
  }
})

const handleSelect = () => {
  emit('select', props.group.id)
}

const handleToggle = () => {
  if (hasChildren.value) {
    emit('toggle', props.group.id)
  }
}
</script>

<style scoped lang="less">
.group-tree-item {
  .group-item-content {
    display: flex;
    align-items: center;
    padding: 10px 12px;
    cursor: pointer;
    transition: all 0.2s ease;
    border-radius: 6px;
    margin: 2px 8px;
    position: relative;

    &:hover {
      background: var(--color-fill-2);
    }

    &.selected {
      background: var(--color-primary-light-1);
      border-left: 3px solid rgb(var(--primary-6));
      margin-left: 5px;
    }

    &.has-children {
      padding-right: 8px;
    }
  }

  .toggle-icon {
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    cursor: pointer;
    color: var(--color-text-3);
    border-radius: 4px;
    transition: all 0.2s;

    &:hover {
      background: var(--color-fill-3);
      color: var(--color-text-1);
    }
  }

  .toggle-placeholder {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
  }

  .device-icon {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 12px;
    flex-shrink: 0;
    transition: all 0.2s;
  }

  .device-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }

  .device-name {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text-1);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.4;
  }

  .status-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex-shrink: 0;

    &.status-error {
      background: #ef4444;
      box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.2);
    }

    &.status-warning {
      background: #f59e0b;
      box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.2);
    }
  }

  .device-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 11px;
    color: var(--color-text-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .ip-address {
    font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
    color: var(--color-text-3);
  }

  .alert-indicator {
    color: #ef4444;
    font-weight: 500;
    padding: 1px 4px;
    background: rgba(239, 68, 68, 0.1);
    border-radius: 3px;
  }

  .children-count {
    font-size: 11px;
    color: var(--color-text-3);
    background: var(--color-fill-2);
    padding: 2px 6px;
    border-radius: 4px;
    flex-shrink: 0;
  }

  .children-container {
    border-top: 1px solid var(--color-border-1);
    margin-top: 4px;
  }
}
</style>
