<template>
  <uni-popup
    ref="popup"
    type="bottom"
    :safe-area="false"
    @maskClick="handleMaskClick"
  >
    <!-- 弹窗主体 -->
    <view class="calendar-popup" @tap.stop>
      <!-- 头部区域 -->
      <view class="calendar-header">
        <view class="header-content">
          <text class="header-title">日历选择</text>
          <text class="header-subtitle"
            >选择住宿日期，以下价格为单晚参考价</text
          >
        </view>
        <view class="header-close" @tap="handleClose">
          <uni-icons type="closeempty" size="20" color="#8c8c8c"></uni-icons>
        </view>
      </view>

      <!-- 周标题行 - 固定显示 -->
      <view class="week-header">
        <text class="week-day" v-for="day in weekDays" :key="day">
          {{ day }}
        </text>
      </view>

      <!-- 日历主体区域 -->
      <view class="calendar-body">
        <!-- 全年月份显示区域 -->
        <view class="year-container">
          <view
            class="month-section"
            v-for="monthData in yearMonthsGrid"
            :key="monthData.key"
          >
            <text class="month-title">{{ monthData.title }}</text>
            <view class="date-grid">
              <view
                class="date-cell"
                v-for="(dateInfo, index) in monthData.grid"
                :key="index"
                :class="getDateCellClass(dateInfo)"
                @tap="handleDateClick(dateInfo)"
              >
                <template v-if="dateInfo">
                  <text class="date-label" v-if="dateInfo.label">
                    {{ dateInfo.label }}
                  </text>
                  <text class="date-number">{{ dateInfo.day }}</text>
                  <text class="date-price" v-if="dateInfo.price"
                    >¥{{ dateInfo.price }}</text
                  >
                </template>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>
  </uni-popup>
</template>

<script setup>
import {
  ref,
  reactive,
  computed,
  watch,
  onMounted,
  onBeforeUnmount,
} from "vue";

// 定义组件名称
defineOptions({
  name: "Calendar",
});

// uni-popup组件引用
const popup = ref(null);

// 定义Props
const props = defineProps({
  // 弹窗显示控制
  visible: {
    type: Boolean,
    default: false,
    required: true,
  },

  // 价格数据数组
  priceData: {
    type: Array,
    default: () => [
      {date: '', price: '-', stock: '0'}
    ],
  },

  // 默认选中日期
  defaultValue: {
    type: [String, Array],
    default: "",
  },

  // 选择模式
  mode: {
    type: String,
    default: "single",
    validator: (value) => ["single", "range"].includes(value),
  },

  // 最小可选日期
  minDate: {
    type: String,
    default: () => new Date().toISOString().split("T")[0],
  },

  // 最大可选日期
  maxDate: {
    type: String,
    default: "",
  },

  // 禁用日期数组
  disabledDates: {
    type: Array,
    default: () => [],
  },

  // 自定义标签
  customLabels: {
    type: Object,
    default: () => ({}),
  },
});

// 定义Emits
const emit = defineEmits([
  "close",
  "select",
  "range-select",
  "date-click",
  "month-change",
]);

// 响应式数据
const weekDays = ref(["一", "二", "三", "四", "五", "六", "日"]);
const selectedDates = ref([]);
const currentYear = ref(new Date().getFullYear());
const isRangeSelecting = ref(false);
const rangeStart = ref(null);
const rangeEnd = ref(null);
const clickTimer = ref(null);

// 计算属性
// 生成从当前月份到明年同月份的日历数据
const yearMonthsGrid = computed(() => {
  const months = [];
  const now = new Date();
  const currentYear = now.getFullYear();
  const startMonth = now.getMonth() + 1; // 从当前月份开始（getMonth()返回0-11，需要+1）
  const totalMonths = 13; // 显示13个月（当前月份到明年同月份）

  for (let i = 0; i < totalMonths; i++) {
    const month = ((startMonth - 1 + i) % 12) + 1;
    const year = currentYear + Math.floor((startMonth - 1 + i) / 12);

    months.push({
      key: `${year}-${month}`,
      title: `${year}年${month}月`,
      year: year,
      month: month,
      grid: generateCalendarGrid(year, month),
    });
  }

  return months;
});

// 方法定义
// 处理遮罩点击
const handleMaskClick = () => {
  handleClose();
};

// 处理关闭
const handleClose = () => {
  if (popup.value) {
    popup.value.close();
  }
  emit("close");
};

// 获取月份天数
const getDaysInMonth = (year, month) => {
  return new Date(year, month, 0).getDate();
};

// 获取月份第一天是星期几 (0=周日, 1=周一...)
const getFirstDayOfMonth = (year, month) => {
  const day = new Date(year, month - 1, 1).getDay();
  return day === 0 ? 6 : day - 1; // 转换为周一开始 (0=周一, 6=周日)
};

// 获取指定日期的价格
const getPriceForDate = (dateStr) => {
  if (!props.priceData || !Array.isArray(props.priceData)) {
    return null;
  }
  
  const priceItem = props.priceData.find(item => item.date === dateStr);
  return priceItem ? priceItem.price : null;
};

// 生成日历网格数据
const generateCalendarGrid = (year, month) => {
  const daysInMonth = getDaysInMonth(year, month);
  const firstDay = getFirstDayOfMonth(year, month);
  const grid = [];

  // 填充空白格子
  for (let i = 0; i < firstDay; i++) {
    grid.push(null);
  }

  // 填充日期
  for (let day = 1; day <= daysInMonth; day++) {
    const dateStr = `${year}-${String(month).padStart(2, "0")}-${String(
      day
    ).padStart(2, "0")}`;
    grid.push({
      date: dateStr,
      day: day,
      price: getPriceForDate(dateStr),
      disabled: isDateDisabled(dateStr),
      selected: isDateSelected(dateStr),
      inRange: isDateInRange(dateStr),
      label: getDateLabel(dateStr),
    });
  }

  return grid;
};

// 判断日期是否禁用
const isDateDisabled = (dateStr) => {
  const date = new Date(dateStr);
  const minDate = new Date(props.minDate);
  const maxDate = props.maxDate ? new Date(props.maxDate) : null;

  if (date < minDate) return true;
  if (maxDate && date > maxDate) return true;
  if (props.disabledDates.includes(dateStr)) return true;

  return false;
};

// 判断日期是否选中
const isDateSelected = (dateStr) => {
  if (props.mode === "single") {
    return selectedDates.value.includes(dateStr);
  } else {
    return dateStr === rangeStart.value || dateStr === rangeEnd.value;
  }
};

// 判断日期是否在选择范围内
const isDateInRange = (dateStr) => {
  if (props.mode !== "range" || !rangeStart.value || !rangeEnd.value) {
    return false;
  }

  const date = new Date(dateStr);
  const start = new Date(rangeStart.value);
  const end = new Date(rangeEnd.value);

  return date > start && date < end;
};

// 获取日期标签
const getDateLabel = (dateStr) => {
  // 优先使用自定义标签
  if (props.customLabels[dateStr]) {
    return props.customLabels[dateStr];
  }

  // 为范围选择模式自动生成住/离标签
  if (props.mode === "range") {
    if (dateStr === rangeStart.value && dateStr === rangeEnd.value) {
      // 当入住和离店是同一天时，显示"住/离"
      return "住/离";
    }
    if (dateStr === rangeStart.value) {
      return "入住";
    }
    if (dateStr === rangeEnd.value) {
      return "离店";
    }
  }

  return "";
};

// 获取日期格子样式类
const getDateCellClass = (dateInfo) => {
  if (!dateInfo) return "date-cell-empty";

  const classes = ["date-cell-content"];

  if (dateInfo.disabled) classes.push("date-cell-disabled");
  if (dateInfo.selected) classes.push("date-cell-selected");
  if (dateInfo.inRange) classes.push("date-cell-in-range");

  return classes.join(" ");
};

// 处理日期点击
const handleDateClick = (dateInfo) => {
  if (!dateInfo || dateInfo.disabled) return;

  // 防抖处理
  if (clickTimer.value) {
    clearTimeout(clickTimer.value);
  }

  clickTimer.value = setTimeout(() => {
    if (props.mode === "single") {
      handleSingleSelect(dateInfo);
    } else if (props.mode === "range") {
      handleRangeSelection(dateInfo);
    }

    // 触发点击事件
    emit("date-click", {
      date: dateInfo.date,
      price: dateInfo.price,
      disabled: dateInfo.disabled,
      selected: dateInfo.selected,
    });
  }, 100);
};

// 处理单选
const handleSingleSelect = (dateInfo) => {
  selectedDates.value = [dateInfo.date];
  emit("select", {
    date: dateInfo.date,
    price: dateInfo.price,
    mode: "single",
  });
};

// 处理范围选择
const handleRangeSelection = (dateInfo) => {
  if (!rangeStart.value || (rangeStart.value && rangeEnd.value)) {
    // 开始新的范围选择
    rangeStart.value = dateInfo.date;
    rangeEnd.value = null;
    isRangeSelecting.value = true;
  } else {
    // 完成范围选择
    rangeEnd.value = dateInfo.date;
    isRangeSelecting.value = false;

    // 允许选择相同日期，但确保开始日期不大于结束日期
    if (new Date(rangeStart.value) > new Date(rangeEnd.value)) {
      [rangeStart.value, rangeEnd.value] = [rangeEnd.value, rangeStart.value];
    }

    // 检查日期跨度是否超过28天（相同日期跨度为0天，允许通过）
    const daysBetween = calculateDaysBetween(rangeStart.value, rangeEnd.value);
    if (daysBetween > 28) {
      // 使用uni.showToast显示错误提示
      uni.showToast({
        title: "预定时间不能超过28天",
        icon: "none",
        duration: 3000,
      });

      // 重置选择状态
      rangeStart.value = null;
      rangeEnd.value = null;
      isRangeSelecting.value = false;

      return;
    }

    emit("range-select", {
      startDate: rangeStart.value,
      endDate: rangeEnd.value,
      startPrice: getPriceForDate(rangeStart.value),
      endPrice: getPriceForDate(rangeEnd.value),
      totalDays: daysBetween,
    });
  }
};

// 计算两个日期之间的天数
const calculateDaysBetween = (startDate, endDate) => {
  const start = new Date(startDate);
  const end = new Date(endDate);
  const diffTime = Math.abs(end - start);
  return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
};

// 监听visible属性变化，控制uni-popup显示
watch(
  () => props.visible,
  (newVisible) => {
    if (newVisible) {
      popup.value?.open();
    } else {
      popup.value?.close();
    }
  },
  { immediate: true }
);

// 生命周期钩子
onMounted(() => {
  // 初始化选中状态
  if (props.defaultValue) {
    if (Array.isArray(props.defaultValue)) {
      rangeStart.value = props.defaultValue[0];
      rangeEnd.value = props.defaultValue[1];
    } else {
      selectedDates.value = [props.defaultValue];
    }
  }
});

onBeforeUnmount(() => {
  if (clickTimer.value) {
    clearTimeout(clickTimer.value);
  }
});
</script>

<style lang="scss" scoped>
// 引入样式文件
@import "./styles/index.scss";
</style>