<template>
  <view class="gantt-container">
    <!-- 顶部分组栏（维度选择） -->
    <dimension-panel :dimensionOptions="dimensionOptions" @switch="onSwitchDimension" class="gantt-dimension-panel" />
    <!-- 图例组件 -->
    <legend :groups="taskGroups" :dimensionName="getCurrentDimensionName" />
    <view class="gantt-body">
      <!-- 右侧横向滚动区 -->
      <scroll-view scroll-x class="gantt-scroll-x" @scroll="onScroll">
        <view class="gantt-right-area">
          <!-- 上方时间轴 -->
          <timeline-header :config="timelineConfig" class="gantt-timeline-header" />
          <!-- 下方任务条 -->
          <gantt-canvas :tasks="visibleTasks" :layout="taskLayout" @drag="onTaskDrag" @task-click="onTaskClick" class="gantt-canvas-area" >
            <template #task-bar="slotProps">
              <slot name="task-bar" v-bind="slotProps" />
            </template>
          </gantt-canvas>
        </view>
      </scroll-view>
    </view>
  </view>
</template>
<script>
import DataManager from '../core/DataManager'
import TimeCalculator from '../core/TimeCalculator'
import Interaction from '../core/Interaction'
import Layout from '../core/Layout'
import TimelineHeader from './TimelineHeader.vue'
import DimensionPanel from './DimensionPanel.vue'
import GanttCanvas from './GanttCanvas.vue'
import LegendCom from './Legend.vue'

export default {
  name: 'Gantt',
  components: { TimelineHeader, DimensionPanel, GanttCanvas, LegendCom },
  props: {
    tasks: {
      type: Array,
      required: true
    },
    config: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      dataManager: null,
      timeCalculator: null,
      interaction: null,
      layout: null,
      taskGroups: [],
      visibleTasks: [],
      taskLayout: [],
      timelineConfig: {},
      dimensionOptions: this.config.visibleDimensions || [],
      groupBy: this.config.groupBy // 新增响应式分组依据
    }
  },
  computed: {
    getCurrentDimensionName() {
      const dim = this.dimensionOptions.find(d => d.prop === this.groupBy)
      return dim ? dim.label || dim.name || dim.prop : ''
    }
  },
  created() {
    this.dataManager = new DataManager(this.tasks, this.config.visibleDimensions)
    this.timeCalculator = new TimeCalculator(this.config)
    this.interaction = new Interaction(this.dataManager, this.timeCalculator)
    this.layout = new Layout(this.tasks, this.config)
    this.refresh()
    this.dataManager.onChange(this.refresh)
  },
  methods: {
    refresh() {
      this.taskGroups = this.dataManager.groupByDimension(this.groupBy)
      this.visibleTasks = this.taskGroups.flatMap(g => g.tasks)
      this.layout = new Layout(this.visibleTasks, this.config)
      this.taskLayout = this.layout.computeTaskLayout()
      const ticks = this.timeCalculator.getTimelineTicks().map(tick => {
        return {
          ...tick,
          left: this.timeCalculator.dateToPixel(tick.date)
        }
      })
      this.timelineConfig = { ticks }
    },
    onSwitchDimension(dim) {
      this.groupBy = dim.prop
      this.refresh()
    },
    onTaskDrag({ taskId, deltaX }) {
      const task = this.tasks.find(t => t.id === taskId)
      if (!task) return
      const startPixel = this.timeCalculator.dateToPixel(task.start)
      const newPixel = startPixel + deltaX
      const newDate = this.timeCalculator.pixelToDate(newPixel)
      this.interaction.handleDragUpdate(taskId, newDate.toISOString().slice(0, 10))
    },
    onTaskClick(task) {
      this.$emit('task-click', task)
    },
    onScroll(e) {
      // 不做 scrollLeft 回写，避免抖动
    }
  }
}
</script>
<style scoped>
.gantt-container {
  width: 100%;
  background: #f5f6fa;
}
.gantt-body {
  display: flex;
  flex-direction: column;
  height: 500px;
}
.gantt-dimension-panel {
  width: 100%;
  border-right: none;
  background: #fafbfc;
  z-index: 2;
  margin-bottom: 0;
}
.gantt-scroll-x {
  flex: 1;
  overflow-x: auto;
  background: #fff;
}
.gantt-right-area {
  min-width: 800px;
}
.gantt-timeline-header {
  height: 32px;
  background: #f7f7f7;
  border-bottom: 1px solid #eee;
  position: sticky;
  top: 0;
  z-index: 1;
}
.gantt-canvas-area {
  min-height: 400px;
}
</style> 