<template>
  <view>
    <view @click="openPicker" class="flex items-center bg-white font-bold text-base h-100 w-full">
      <view class="w-168 ml-4 leading-[100rpx]">{{ title }}</view>
      <view class="mr-4 text-right w-[518rpx] h-100 leading-[100rpx]">
        {{ timeFormat(value, 'yyyy-mm-dd h:M') }}
      </view>
    </view>

    <up-popup :show="show" @close="closePicker" mode="bottom" bgColor="transparent" round="32rpx">
      <view class="w-750 bg-white">
        <view class="flex justify-between items-center px-4 py-3 text-lg">
          <text class="text-gray-500" @click="closePicker">取消</text>
          <text class="font-bold">{{ title }}</text>
          <text class="text-blue-500" @click="confirmSelection">确定</text>
        </view>

        <picker-view
          :value="pickerIndex"
          class="h-250px"
          indicator-style="height:50px"
          @change="onPickerChange"
          :immediate-change="true"
        >
          <picker-view-column>
            <view v-for="year in years" :key="year" class="text-center text-lg leading-10"
              >{{ year }}年</view
            >
          </picker-view-column>
          <picker-view-column>
            <view v-for="month in months" :key="month" class="text-center text-lg leading-10"
              >{{ month }}月</view
            >
          </picker-view-column>
          <picker-view-column>
            <view v-for="day in days" :key="day" class="text-center text-lg leading-10"
              >{{ day }}日</view
            >
          </picker-view-column>
          <picker-view-column>
            <view v-for="hour in hours" :key="hour" class="text-center text-lg leading-10"
              >{{ hour }}时</view
            >
          </picker-view-column>
        </picker-view>
      </view>
    </up-popup>
  </view>
</template>

<script setup>
  import { ref, watch, computed } from 'vue'
  import { timeFormat } from 'uview-plus'

  const props = defineProps({
    title: { type: String, default: '请选择时间' },
    value: { type: String, default: '' },
    minDate: { type: Number, required: true },
    maxDate: { type: Number, required: true }
  })

  const emit = defineEmits(['changeTime'])

  const openPicker = () => {
    show.value = true
    initPickerData(props.value)
  }

  const closePicker = () => {
    show.value = false
  }

  const parseDate = timestamp => {
    const date = new Date(timestamp)
    return {
      year: date.getFullYear(),
      month: date.getMonth() + 1,
      day: date.getDate(),
      hour: date.getHours()
    }
  }

  const minDateParsed = computed(() => parseDate(props.minDate))
  const maxDateParsed = computed(() => parseDate(props.maxDate))

  const show = ref(false)
  const years = ref([])
  const months = ref([])
  const days = ref([])
  const hours = ref([])
  const pickerIndex = ref([0, 0, 0, 0])
  const tempPickerValue = ref({
    year: 0,
    month: 0,
    day: 0,
    hour: 0
  })

  const generateYears = () => {
    const minYear = minDateParsed.value.year
    const maxYear = maxDateParsed.value.year
    return Array.from({ length: maxYear - minYear + 1 }, (_, i) => minYear + i)
  }

  const updateMonths = year => {
    let monthsList = []
    const minMonth = year === minDateParsed.value.year ? minDateParsed.value.month : 1
    const maxMonth = year === maxDateParsed.value.year ? maxDateParsed.value.month : 12

    for (let month = minMonth; month <= maxMonth; month++) {
      monthsList.push(month)
    }
    months.value = monthsList
    return monthsList
  }

  const updateDays = (year, month) => {
    const daysInMonth = new Date(year, month, 0).getDate()
    let minDay = 1
    let maxDay = daysInMonth

    if (year === minDateParsed.value.year && month === minDateParsed.value.month) {
      minDay = minDateParsed.value.day
    }

    if (year === maxDateParsed.value.year && month === maxDateParsed.value.month) {
      maxDay = maxDateParsed.value.day
    }

    maxDay = Math.min(maxDay, daysInMonth)

    if (minDay > maxDay) {
      days.value = [1]
      return [1]
    }

    const daysList = Array.from({ length: maxDay - minDay + 1 }, (_, i) => minDay + i)
    days.value = daysList
    return daysList
  }

  const updateHours = (year, month, day) => {
    let startHour = 0
    let endHour = 24

    if (
      year === minDateParsed.value.year &&
      month === minDateParsed.value.month &&
      day === minDateParsed.value.day
    ) {
      startHour = minDateParsed.value.hour
    }

    if (
      year === maxDateParsed.value.year &&
      month === maxDateParsed.value.month &&
      day === maxDateParsed.value.day
    ) {
      endHour = maxDateParsed.value.hour
    }

    const hoursList = Array.from({ length: endHour - startHour + 1 }, (_, i) => startHour + i)
    hours.value = hoursList
    return hoursList
  }

  const onPickerChange = event => {
    const [yearIndex, monthIndex, dayIndex, hourIndex] = event.detail.value
    const selectedYear = years.value[yearIndex]

    const updatedMonths = updateMonths(selectedYear)
    let selectedMonth = updatedMonths[Math.max(0, Math.min(monthIndex, updatedMonths.length - 1))]
    if (selectedYear === minDateParsed.value.year) {
      selectedMonth = Math.max(selectedMonth, minDateParsed.value.month)
    }

    const updatedDays = updateDays(selectedYear, selectedMonth)
    let selectedDay = updatedDays[Math.max(0, Math.min(dayIndex, updatedDays.length - 1))]
    if (selectedYear === minDateParsed.value.year && selectedMonth === minDateParsed.value.month) {
      selectedDay = Math.max(selectedDay, minDateParsed.value.day)
    }

    const updatedHours = updateHours(selectedYear, selectedMonth, selectedDay)
    let selectedHour = updatedHours[Math.max(0, Math.min(hourIndex, updatedHours.length - 1))]
    if (
      selectedYear === minDateParsed.value.year &&
      selectedMonth === minDateParsed.value.month &&
      selectedDay === minDateParsed.value.day
    ) {
      selectedHour = Math.max(selectedHour, minDateParsed.value.hour)
    }

    console.log(1111, selectedYear, selectedMonth, selectedDay, selectedHour)
    console.log(
      1111,
      yearIndex,
      updatedMonths.indexOf(selectedMonth),
      updatedDays.indexOf(selectedDay),
      updatedHours.indexOf(selectedHour)
    )

    tempPickerValue.value = {
      year: selectedYear,
      month: selectedMonth,
      day: selectedDay,
      hour: selectedHour
    }

    pickerIndex.value = [
      yearIndex,
      updatedMonths.indexOf(selectedMonth),
      updatedDays.indexOf(selectedDay),
      updatedHours.indexOf(selectedHour)
    ]
  }

  const initPickerData = timestamp => {
    if (!timestamp) {
      timestamp = props.minDate
    }

    const date = new Date(timestamp)
    let year = date.getFullYear()
    let month = date.getMonth() + 1
    let day = date.getDate()
    let hour = date.getHours()

    if (hour === 24) {
      hour = 0
      const nextDay = new Date(date)
      nextDay.setDate(date.getDate() + 1)
      year = nextDay.getFullYear()
      month = nextDay.getMonth() + 1
      day = nextDay.getDate()
    }

    if (year === minDateParsed.value.year) {
      month = Math.max(month, minDateParsed.value.month)
      if (month === minDateParsed.value.month) {
        day = Math.max(day, minDateParsed.value.day)
        if (day === minDateParsed.value.day) {
          hour = Math.max(hour, minDateParsed.value.hour)
        }
      }
    }

    years.value = generateYears()
    const updatedMonths = updateMonths(year)
    const updatedDays = updateDays(year, month)
    const updatedHours = updateHours(year, month, day)

    tempPickerValue.value = {
      year,
      month,
      day,
      hour
    }

    pickerIndex.value = [
      years.value.indexOf(year),
      updatedMonths.indexOf(month),
      updatedDays.indexOf(day),
      updatedHours.indexOf(hour)
    ]
  }

  watch(() => props.value, initPickerData, { immediate: true })

  const confirmSelection = () => {
    const { year, month, day, hour } = tempPickerValue.value

    const selectedDate = new Date(year, month - 1, day, hour, 0, 0, 0)
    emit('changeTime', selectedDate.getTime())
    show.value = false
  }
</script>
