<template>
  <uni-popup ref="popup" type="bottom" :safe-area="false">
    <view class="time-picker-container" :style="{ marginBottom: bottomOffset + 'rpx' }">
      <view class="picker-header">
        <text class="title">期望取件时间</text>
        <view class="close-btn" @click="close">
          <zui-svg-icon icon="general-close" :width="18" :height="18" color="#666" />
        </view>
      </view>

      <picker-view v-if="visible" class="picker-view" :indicator-style="indicatorStyle" :value="pickerValue" @change="handleChange" :immediate-change="true">
        <picker-view-column>
          <view class="picker-item" v-for="(item, index) in days" :key="index">{{ item.label }}</view>
        </picker-view-column>
        <picker-view-column>
          <view class="picker-item" v-for="(item, index) in hours" :key="index">{{ item.label }}</view>
        </picker-view-column>
        <picker-view-column>
          <view class="picker-item" v-for="(item, index) in minutes" :key="index">{{ item.label }}</view>
        </picker-view-column>
      </picker-view>

      <view class="confirm-button-wrapper">
        <button class="confirm-btn" @click="handleConfirm">确认</button>
      </view>
    </view>
  </uni-popup>
</template>

<script>
import dayjs from 'dayjs';

const minutes = [0, 10, 20, 30, 40, 50];

export default {
  name: 'TimePicker',
  props: {
    bottomOffset: {
      type: [Number, String],
      default: 0
    }
  },
  data() {
    return {
      visible: false, // 控制picker-view的渲染
      pickerValue: [0, 0, 0],
      tempPickerValue: [0, 0, 0], // 临时存储滚动过程中的值
      debounceTimer: null,
      days: [],
      hours: [],
      minutes: [],
      indicatorStyle: `height: 80rpx;`,
    };
  },
  created() {
    this.initTime();
  },
  methods: {
    open() {
      this.visible = true;
      this.initTime();
      this.$refs.popup.open();
    },

    close() {
      this.visible = false;
      this.$refs.popup.close();
    },

    initTime() {
      const now = dayjs(); // Use current time
      this.days = this.generateDays();

      const isToday = true;
      let availableHoursToday = this.generateHours(now, isToday);

      // If no hours available today, switch to tomorrow
      if (availableHoursToday.length <= 1) { // Only "立即"
        const tomorrow = dayjs().add(1, 'day').startOf('day');
        this.days = this.generateDays(); // Regenerate days if needed
        this.hours = this.generateHours(tomorrow, false);
        this.minutes = this.generateMinutes(tomorrow, false, this.hours[0].value);
        this.pickerValue = [1, 0, 0]; // Select "Tomorrow", first hour, first minute
        this.tempPickerValue = [1, 0, 0];
        return;
      }

      this.hours = availableHoursToday;

      // Default to "立即"
      const initialHourIndex = 0;
      const selectedHour = this.hours[initialHourIndex].value;
      this.minutes = this.generateMinutes(now, isToday, selectedHour);
      const initialMinuteIndex = 0;
      
      this.pickerValue = [0, initialHourIndex, initialMinuteIndex];
      this.tempPickerValue = [0, initialHourIndex, initialMinuteIndex];
    },

    generateDays() {
      return [
        { label: '今天', value: dayjs().format('YYYY-MM-DD') },
        { label: '明天', value: dayjs().add(1, 'day').format('YYYY-MM-DD') },
      ];
    },

    generateHours(now, isToday) {
      const hours = [];
      if (isToday) {
        hours.push({ label: '立即', value: -1 });

        let startHour = now.hour() + 1; // 当前小时的下一个小时
        // Find if any minutes are available in the current hour
        const firstAvailableMinute = minutes.find(m => m > now.minute());
        
        // If no minutes available in current hour, or if the last minute has passed, start from the next hour
        if (firstAvailableMinute === undefined) {
          startHour++;
        }
        
        for (let i = startHour; i <= 23; i++) {
          hours.push({ label: `${i}时`, value: i });
        }
      } else {
        for (let i = 0; i <= 23; i++) {
          hours.push({ label: `${i}时`, value: i });
        }
      }
      return hours;
    },

    generateMinutes(now, isToday, selectedHour) {
      if (selectedHour === -1) {
        return [{ label: '', value: -1 }];
      }
      
      let availableMinutes = minutes;
      
      if (isToday && selectedHour === now.hour()) {
        const currentMinute = now.minute();
        availableMinutes = minutes.filter(m => m > currentMinute);
      }
      
      return availableMinutes.map(m => ({ label: `${m}分`, value: m }));
    },

    handleChange(e) {
      const val = e.detail.value;
      this.tempPickerValue = val;
      
      if (this.debounceTimer) {
        clearTimeout(this.debounceTimer);
      }
      
      this.debounceTimer = setTimeout(() => {
        this.updatePickers(val);
      }, 100);
    },

    updatePickers(val, isSync = false) {
      const [dayIndex, hourIndex, minuteIndex] = val;
      const oldPickerValue = this.pickerValue;
      
      const now = dayjs();
      const isToday = dayIndex === 0;

      let newHours = this.hours;
      let newMinutes = this.minutes;
      
      let finalHourIndex = hourIndex;
      let finalMinuteIndex = minuteIndex;

      // Day changed
      if (oldPickerValue[0] !== dayIndex) {
        newHours = this.generateHours(now, isToday);
        // 修正越界，尽量保持用户的选择，而不是强制归零
        if (finalHourIndex >= newHours.length) {
            finalHourIndex = 0;
        }
      }
      
      // Calculate selected hour based on current indices
      const selectedHour = newHours[finalHourIndex] ? newHours[finalHourIndex].value : -1;

      // Always regenerate minutes to ensure correctness (e.g. today/tomorrow switch, or hour switch)
      // Optimization: we could check if generation parameters actually changed, but it's fast enough.
      newMinutes = this.generateMinutes(now, isToday, selectedHour);
      
      // 修正越界
      if (finalMinuteIndex >= newMinutes.length) {
          finalMinuteIndex = 0;
      }
      
      this.hours = newHours;
      this.minutes = newMinutes;
      this.debounceTimer = null;

      const newValue = [dayIndex, finalHourIndex, finalMinuteIndex];
      
      if (isSync) {
        this.pickerValue = newValue;
      } else {
        // Use setTimeout to avoid visual glitch on picker reset
        setTimeout(() => {
            this.pickerValue = newValue;
        }, 0);
      }
    },

    handleConfirm() {
      if (this.debounceTimer) {
        clearTimeout(this.debounceTimer);
        this.updatePickers(this.tempPickerValue, true);
      }
      
      const [dayIndex, hourIndex, minuteIndex] = this.pickerValue;
      const selectedDay = this.days[dayIndex];
      const selectedHour = this.hours[hourIndex];
      const selectedMinute = this.minutes[minuteIndex];

      let result = {};
      if (selectedHour && selectedHour.value === -1) {
        result = {
          label: '立即取件',
          value: dayjs().format('YYYY-MM-DD HH:mm'),
        };
      } else {
        const date = selectedDay.value;
        const hour = selectedHour?.value ?? 0;
        const minute = selectedMinute?.value ?? 0;
        const finalDate = dayjs(`${date} ${hour}:${minute}`).toDate();
        result = {
          label: dayjs(finalDate).format('YYYY-MM-DD HH:mm'),
          value: dayjs(finalDate).format('YYYY-MM-DD HH:mm'),
        };
      }

      this.$emit('confirm', result);
      this.close();
    },
  },
};
</script>

<style lang="scss" scoped>
.time-picker-container {
  background-color: #fff;
  border-top-left-radius: 24rpx;
  border-top-right-radius: 24rpx;
  height: 45vh;
  display: flex;
  flex-direction: column;
}
.picker-header {
  position: relative;
  text-align: center;
  padding: 30rpx;
  flex-shrink: 0;

  .title {
    font-size: 44rpx;
    font-weight: 500;
  }

  .close-btn {
    position: absolute;
    right: 30rpx;
    top: 50%;
    transform: translateY(-50%);
    padding: 10rpx;
  }
}
.picker-view {
  width: 100%;
  height: 100%;
}
.picker-item {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 42rpx;
}
.confirm-button-wrapper {
  padding: 20rpx 30rpx;
  padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
  flex-shrink: 0;
}
.confirm-btn {
  background: linear-gradient(to right, #409eff, #67c2ff);
  color: white;
  border-radius: 50rpx;
  font-size: 42rpx;
  height: 88rpx;
  line-height: 88rpx;
  border: none;
  &::after {
    border: none;
  }
}
</style>
