<template>
  <div class="pickup-time-cascader">
    <el-cascader
        ref="cascaderRef"
        v-model="selectedValue"
        :options="cascaderOptions"
        :props="cascaderProps"
        :show-all-levels="false"
        :placeholder="placeholder"
        :clearable="clearable"
        :filterable="filterable"
        :disabled="disabled"
        :size="size"
        @change="handleChange"
        @visible-change="handleVisibleChange"
        @expand-change="handleExpandChange"
    >
      <template #default="{ node, data }">
        <div class="cascader-item" :class="{'is-date': !data.timeLabel, 'is-time': data.timeLabel}">
          <span class="item-label">{{ data.label }}</span>
          <span v-if="data.tag" class="item-tag" :class="data.tagClass">
            {{ data.tag }}
          </span>
          <span v-if="data.recommend" class="item-recommend">推荐</span>
          <span v-if="data.night" class="item-night">夜间</span>
        </div>
      </template>

      <template #empty>
        <div class="empty-content">
          <span class="empty-text">无可用时间段</span>
        </div>
      </template>
    </el-cascader>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'

const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  },
  placeholder: {
    type: String,
    default: '请选择上门时间'
  },
  clearable: {
    type: Boolean,
    default: true
  },
  filterable: {
    type: Boolean,
    default: false
  },
  disabled: {
    type: Boolean,
    default: false
  },
  size: {
    type: String,
    default: 'large',
    validator: (value) => ['large', 'default', 'small'].includes(value)
  },
  // 显示天数
  days: {
    type: Number,
    default: 3
  },
  // 时间间隔（分钟）
  timeInterval: {
    type: Number,
    default: 60
  },
  // 开始时间
  startTime: {
    type: Number,
    default: 9
  },
  // 结束时间
  endTime: {
    type: Number,
    default: 21
  },
  // 当前时间（用于测试）
  currentTime: {
    type: Date,
    default: () => new Date()
  },
  // 是否自动选择推荐时间
  autoSelect: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['update:modelValue', 'change', 'select', 'clear'])

const selectedValue = ref([])
const cascaderRef = ref(null)
const currentTime = ref(new Date())
const timer = ref(null)

// 级联选择器配置
const cascaderProps = {
  expandTrigger: 'click',
  multiple: false,
  emitPath: true,
  value: 'value',
  label: 'label',
  children: 'children',
  disabled: 'disabled',
  checkStrictly: false,
  lazy: false
}

// 基础时间段配置
const baseTimeSlots = computed(() => {
  const slots = []
  const startHour = props.startTime
  const endHour = props.endTime
  const interval = props.timeInterval / 60 // 转换为小时

  for (let hour = startHour; hour < endHour; hour += interval) {
    const start = hour
    const end = hour + interval
    const startStr = start.toString().padStart(2, '0')
    const endStr = end.toString().padStart(2, '0')

    slots.push({
      start: start,
      end: end,
      label: `${startStr}:00-${endStr}:00`,
      value: `${startStr}:00-${endStr}:00`
    })
  }

  return slots
})

// 获取今天日期字符串
const todayDate = computed(() => {
  const today = new Date()
  return formatDate(today)
})

// 生成日期列表
const dateList = computed(() => {
  const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  const list = []
  const today = new Date()

  for (let i = 0; i < props.days; i++) {
    const date = new Date(today)
    date.setDate(date.getDate() + i)

    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()
    const week = days[date.getDay()]
    const dateStr = formatDate(date)

    let label = ''
    if (i === 0) {
      label = `今天 ${month}月${day}日 ${week}`
    } else if (i === 1) {
      label = `明天 ${month}月${day}日 ${week}`
    } else if (i === 2) {
      label = `后天 ${month}月${day}日 ${week}`
    } else {
      label = `${month}月${day}日 ${week}`
    }

    list.push({
      value: dateStr,
      label: label,
      year: year,
      month: month,
      day: day,
      week: week,
      isToday: i === 0,
      isTomorrow: i === 1,
      isDayAfterTomorrow: i === 2,
      fullLabel: `${month}月${day}日 ${week}`,
      displayDate: `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`
    })
  }

  return list
})

// 推荐时间段（今天的一小时内）
const recommendTime = computed(() => {
  if (!dateList.value.length || !dateList.value[0].isToday) return null

  const now = currentTime.value
  const currentHour = now.getHours()
  const currentMinute = now.getMinutes()

  // 找到下一个可用的时间段
  for (const slot of baseTimeSlots.value) {
    if (slot.start > currentHour ||
        (slot.start === currentHour && currentMinute < 50)) {
      // 如果当前时间在 startTime 到 endTime 之间
      if (currentHour >= props.startTime && currentHour < props.endTime) {
        // 计算推荐时间段（当前时间+1小时）
        let startHour = currentHour
        let startMinute = Math.ceil(currentMinute / 10) * 10
        if (startMinute >= 60) {
          startHour += 1
          startMinute = 0
        }

        const endHour = startHour + 1
        const recommendation = `${formatTime(startHour, startMinute)}-${endHour.toString().padStart(2, '0')}:00`

        // 检查推荐时间是否在可用时间段内
        if (isTimeSlotAvailable(recommendation)) {
          return recommendation
        }
      }
      return slot.label
    }
  }

  return null
})

// 检查时间段是否可用
const isTimeSlotAvailable = (timeLabel) => {
  const timeMatch = timeLabel.match(/(\d{2}):(\d{2})-(\d{2}):(\d{2})/)
  if (!timeMatch) return false

  const startHour = parseInt(timeMatch[1])
  const startMinute = parseInt(timeMatch[2])

  // 检查是否在允许的时间范围内
  if (startHour < props.startTime || startHour >= props.endTime) {
    return false
  }

  return true
}

// 生成级联选择器选项
const cascaderOptions = computed(() => {
  const options = []

  dateList.value.forEach(date => {
    const dateOption = {
      value: date.value,
      label: date.label,
      date: date.value,
      dateLabel: date.label,
      isToday: date.isToday,
      children: [],
      disabled: false
    }

    // 生成时间选项
    const isToday = date.isToday
    const now = currentTime.value

    // 今天的时间段需要根据当前时间过滤
    if (isToday) {
      const currentHour = now.getHours()
      const currentMinute = now.getMinutes()

      // 添加推荐时间段（如果有）
      if (recommendTime.value && props.autoSelect) {
        dateOption.children.push({
          value: recommendTime.value,
          label: recommendTime.value,
          timeLabel: recommendTime.value,
          recommend: true,
          tag: '推荐',
          tagClass: 'tag-recommend',
          disabled: false,
          soon: false,
          night: isNightTime(recommendTime.value),
          startHour: getStartHour(recommendTime.value),
          endHour: getEndHour(recommendTime.value)
        })
      }

      // 添加其他时间段
      baseTimeSlots.value.forEach(slot => {
        const isDisabled = slot.end <= currentHour ||
            (slot.start === currentHour && currentMinute > 50)
        const isSoon = slot.start - currentHour <= 2 && slot.start > currentHour
        const isRecommend = slot.label === recommendTime.value

        if (!isDisabled || isRecommend) {
          dateOption.children.push({
            value: slot.label,
            label: slot.label,
            timeLabel: slot.label,
            recommend: isRecommend,
            tag: isSoon ? '约满' : (isRecommend ? '推荐' : ''),
            tagClass: isSoon ? 'tag-soon' : (isRecommend ? 'tag-recommend' : ''),
            disabled: isDisabled && !isRecommend,
            soon: isSoon,
            night: isNightTime(slot.label),
            startHour: slot.start,
            endHour: slot.end
          })
        }
      })
    } else {
      // 明天及以后显示所有时间段
      baseTimeSlots.value.forEach(slot => {
        dateOption.children.push({
          value: slot.label,
          label: slot.label,
          timeLabel: slot.label,
          recommend: false,
          tag: '',
          tagClass: '',
          disabled: false,
          soon: false,
          night: isNightTime(slot.label),
          startHour: slot.start,
          endHour: slot.end
        })
      })
    }

    // 如果没有可用的时间段，则禁用该日期
    if (dateOption.children.length === 0) {
      dateOption.disabled = true
      dateOption.label = `${dateOption.label} (无可选时间)`
    }

    options.push(dateOption)
  })

  return options
})

// 是否是夜间时间段
const isNightTime = (timeLabel) => {
  const match = timeLabel.match(/^(\d{2})/)
  if (match) {
    const hour = parseInt(match[1])
    return hour >= 18
  }
  return false
}

// 获取开始小时
const getStartHour = (timeLabel) => {
  const match = timeLabel.match(/^(\d{2})/)
  return match ? parseInt(match[1]) : 0
}

// 获取结束小时
const getEndHour = (timeLabel) => {
  const match = timeLabel.match(/-(\d{2})/)
  return match ? parseInt(match[1]) : 0
}

// 处理选择变化
const handleChange = (value) => {
  if (!value || value.length === 0) {
    emit('update:modelValue', [])
    emit('change', null)
    emit('clear')
    return
  }

  const [date, time] = value
  const selectedDate = dateList.value.find(d => d.value === date)
  const selectedTime = findTimeOption(date, time)

  if (!selectedDate || !selectedTime) {
    return
  }

  const timeData = {
    date: date,
    time: time,
    dateLabel: selectedDate.label,
    timeLabel: time,
    fullLabel: formatDisplayText(selectedDate.label, time, selectedDate.isToday),
    timestamp: new Date(date).setHours(selectedTime.startHour || 0),
    isToday: selectedDate.isToday,
    isImmediate: time === recommendTime.value,
    isNight: selectedTime.night || false,
    isSoon: selectedTime.soon || false,
    displayText: formatDisplayText(selectedDate.label, time, selectedDate.isToday),
    startHour: selectedTime.startHour,
    endHour: selectedTime.endHour
  }

  emit('update:modelValue', value)
  emit('change', timeData)
  emit('select', timeData)
}

// 查找时间选项
const findTimeOption = (date, time) => {
  const dateOption = cascaderOptions.value.find(opt => opt.value === date)
  if (!dateOption || !dateOption.children) return null
  return dateOption.children.find(child => child.value === time)
}

// 处理弹窗显示/隐藏
const handleVisibleChange = (visible) => {
  if (visible) {
    // 更新当前时间
    currentTime.value = new Date()

    // 如果没有选中值，自动选择推荐或第一个可用选项
    if (selectedValue.value.length === 0 && props.autoSelect) {
      nextTick(() => {
        const defaultOption = getDefaultOption()
        if (defaultOption) {
          selectedValue.value = defaultOption
          handleChange(defaultOption)
        }
      })
    }
  }
}

// 处理菜单展开
const handleExpandChange = (activeLabels) => {
  // 可以在这里添加菜单展开时的逻辑
}

// 获取默认选项
const getDefaultOption = () => {
  if (!cascaderOptions.value.length) return null

  // 首先尝试今天的推荐时间段
  const todayOption = cascaderOptions.value[0]
  if (todayOption && todayOption.children && todayOption.children.length > 0) {
    // 优先选择推荐时间段
    const recommendOption = todayOption.children.find(child => child.recommend && !child.disabled)
    if (recommendOption) {
      return [todayOption.value, recommendOption.value]
    }

    // 否则选择第一个可用时间段
    const firstAvailable = todayOption.children.find(child => !child.disabled)
    if (firstAvailable) {
      return [todayOption.value, firstAvailable.value]
    }
  }

  // 尝试其他日期的第一个可用时间段
  for (let i = 1; i < cascaderOptions.value.length; i++) {
    const option = cascaderOptions.value[i]
    if (option.children && option.children.length > 0) {
      const firstAvailable = option.children.find(child => !child.disabled)
      if (firstAvailable) {
        return [option.value, firstAvailable.value]
      }
    }
  }

  return null
}

// 格式化显示文本
const formatDisplayText = (dateLabel, timeLabel, isToday) => {
  if (isToday && timeLabel === recommendTime.value) {
    return '一小时内'
  }
  return `${dateLabel} ${timeLabel}`
}

// 工具函数
const formatDate = (date) => {
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  return `${year}-${month}-${day}`
}

const formatTime = (hour, minute) => {
  return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
}

// 监听外部值变化
watch(() => props.modelValue, (newVal) => {
  if (JSON.stringify(newVal) !== JSON.stringify(selectedValue.value)) {
    selectedValue.value = newVal || []
  }
}, { immediate: true })

// 监听当前时间变化（每分钟更新一次）
watch(currentTime, () => {
  // 如果今天的时间选项已经过期，需要重新计算
  const todayOption = cascaderOptions.value[0]
  if (todayOption && todayOption.isToday) {
    // 这里可以添加逻辑来处理时间过期的选项
  }
})

// 初始化
onMounted(() => {
  // 定时更新当前时间（每分钟更新一次）
  timer.value = setInterval(() => {
    if (cascaderRef.value && cascaderRef.value.dropDownVisible) {
      currentTime.value = new Date()
    }
  }, 60000) // 每分钟更新一次
})

// 组件卸载时清除定时器
onUnmounted(() => {
  if (timer.value) {
    clearInterval(timer.value)
  }
})

// 暴露方法
defineExpose({
  getSelectedTimeData: () => {
    if (selectedValue.value.length !== 2) return null
    const [date, time] = selectedValue.value
    const selectedDate = dateList.value.find(d => d.value === date)
    const selectedTime = findTimeOption(date, time)

    return {
      date: date,
      time: time,
      dateLabel: selectedDate?.label,
      timeLabel: time,
      fullLabel: formatDisplayText(selectedDate?.label, time, selectedDate?.isToday),
      timestamp: new Date(date).setHours(selectedTime?.startHour || 0),
      isToday: selectedDate?.isToday,
      isImmediate: time === recommendTime.value,
      isNight: selectedTime?.night || false,
      isSoon: selectedTime?.soon || false,
      startHour: selectedTime?.startHour,
      endHour: selectedTime?.endHour
    }
  },
  clearSelection: () => {
    selectedValue.value = []
    emit('update:modelValue', [])
    emit('change', null)
    emit('clear')
  },
  refreshTime: () => {
    currentTime.value = new Date()
  },
  setSelectedTime: (date, time) => {
    const dateExists = dateList.value.some(d => d.value === date)
    if (dateExists) {
      selectedValue.value = [date, time]
      handleChange([date, time])
      return true
    }
    return false
  }
})
</script>

<style scoped lang="scss">
.pickup-time-cascader {
  width: 100%;

  :deep(.el-cascader) {
    width: 100%;

    .el-input {
      width: 100%;

      .el-input__wrapper {
        width: 100%;
        box-sizing: border-box;

        &.is-focus {
          box-shadow: 0 0 0 1px var(--el-color-primary) inset;
        }
      }
    }
  }

  :deep(.el-cascader__dropdown) {
    max-height: 400px;
    overflow-y: auto;
    border-radius: 8px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);

    .el-cascader-panel {
      border: none;

      .el-cascader-menu {
        min-width: 200px;
        max-height: 400px;
        overflow-y: auto;

        &:first-child {
          min-width: 220px;
        }

        .el-cascader-node {
          height: auto;
          min-height: 40px;
          padding: 8px 12px;

          &:hover:not(.is-disabled) {
            background-color: #f5f7fa;
          }

          &.is-selectable {
            &.in-active-path,
            &.is-active {
              background-color: #f0f7ff;

              .cascader-item {
                .item-label {
                  color: var(--el-color-primary);
                  font-weight: 600;
                }
              }
            }
          }

          &.is-disabled {
            .cascader-item {
              .item-label {
                color: #c0c4cc;
              }
            }
          }

          .cascader-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            width: 100%;
            min-height: 32px;
            box-sizing: border-box;
            font-size: 14px;

            &.is-date {
              .item-label {
                font-weight: 500;
                color: #333;
              }

              &.is-today {
                .item-label {
                  color: #f2270c;
                }
              }
            }

            &.is-time {
              .item-label {
                color: #666;
              }
            }

            .item-label {
              flex: 1;
              text-align: left;
              overflow: hidden;
              text-overflow: ellipsis;
              white-space: nowrap;
            }

            .item-tag {
              font-size: 12px;
              padding: 2px 8px;
              border-radius: 10px;
              margin-left: 8px;
              font-weight: 500;

              &.tag-recommend {
                background-color: #fef2f0;
                color: #f2270c;
                border: 1px solid #f2270c;
              }

              &.tag-soon {
                background-color: #fff7e6;
                color: #ff9900;
                border: 1px solid #ff9900;
              }

              &.tag-night {
                background-color: #f0f5ff;
                color: #4a5cff;
                border: 1px solid #4a5cff;
              }
            }

            .item-recommend {
              font-size: 12px;
              color: #f2270c;
              font-weight: 500;
              margin-left: 8px;
              padding: 2px 6px;
              background-color: #fef2f0;
              border-radius: 4px;
            }

            .item-night {
              font-size: 12px;
              color: #4a5cff;
              font-weight: 500;
              margin-left: 8px;
              padding: 2px 6px;
              background-color: #f0f5ff;
              border-radius: 4px;
            }
          }
        }
      }
    }
  }

  .empty-content {
    padding: 20px;
    text-align: center;

    .empty-text {
      font-size: 14px;
      color: #999;
    }
  }
}

// 夜间时间段特殊样式
.night-time-option {
  :deep(.el-cascader-node) {
    .cascader-item {
      .item-label {
        color: #4a5cff !important;
      }
    }

    &.is-active {
      .cascader-item {
        .item-label {
          color: #4a5cff !important;
        }
      }
    }
  }
}

// 推荐时间段特殊样式
.recommend-time-option {
  :deep(.el-cascader-node) {
    .cascader-item {
      .item-label {
        color: #f2270c !important;
      }
    }

    &.is-active {
      .cascader-item {
        .item-label {
          color: #f2270c !important;
        }
      }
    }
  }
}
</style>