<script setup lang="ts">
import {EventEnum} from "@/constant/enums";

const { t } = useI18n();
import dayjs from "dayjs";

// 店铺的营业时间（示例：周一到周五营业，周六周日不营业）
// 测试用的营业时间字符串
// MONDAY/TUESDAY/WEDNESDAY 09:00-18:00;THURSDAY/FRIDAY 08:00-09:00; // 周一到周五9点到18点，周四到周五8点到9点
// MONDAY/TUESDAY/WEDNESDAY 09:00-18:00;THURSDAY/FRIDAY 08:00-12:00;SATURDAY/SUNDAY 10:00-20:00 // 周六周日10点到20点
// MONDAY/TUESDAY/WEDNESDAY 09:00-16:00
// MONDAY 09:00-18:00;TUESDAY 09:00-10:00;WEDNESDAY 09:00-18:00;THURSDAY 09:00-18:00;FRIDAY 08:00-09:00
const storeBusinessHours = ref('');
// 是否仅选择日期（当进入页面传递了 storeBusinessHours 时开启）
const onlySelectDay = ref(false);

// 业务规则：只能预约周一 / 周四 / 周五
// JS 中：0-周日 1-周一 ... 4-周四 5-周五
const allowedWeekdays = [1, 4, 5];
const isAllowedDay = (date: Date): boolean => {
  const dayIndex = date.getDay();
  return allowedWeekdays.includes(dayIndex);
};

// 解析商家营业时间的接口
interface BusinessHours {
  days: string[]; // 营业的星期几
  startTime: string; // 开始时间 HH:mm
  endTime: string; // 结束时间 HH:mm
}

/**
 * 解析商家营业时间字符串
 * @param businessHoursStr 营业时间字符串，支持多种格式：
 *   - MONDAY/TUESDAY/WEDNESDAY 09:00-18:00;THURSDAY/FRIDAY/SATURDAY/SUNDAY 10:00-20:00
 *   - MONDAY/TUESDAY/WEDNESDAY 09:00-18:00
 *   - MONDAY 09:00-18:00;TUESDAY 09:00-10:00;WEDNESDAY 09:00-18:00
 * @returns 解析后的营业时间数组
 */
const parseBusinessHours = (businessHoursStr: string): BusinessHours[] => {
  if (!businessHoursStr) return [];

  const businessHours: BusinessHours[] = [];
  // 使用分号分割不同的营业时间段
  const segments = businessHoursStr.split(";");

  segments.forEach((segment) => {
    const trimmedSegment = segment.trim();
    if (!trimmedSegment) return;

    // 使用空格分割星期几和时间
    const parts = trimmedSegment.split(" ");
    if (parts.length !== 2) return;

    const dayStr = parts[0].trim().toUpperCase();
    const timeStr = parts[1];

    // 解析时间范围
    const timeRange = timeStr.split("-");
    if (timeRange.length !== 2) return;

    const startTime = timeRange[0].trim();
    const endTime = timeRange[1].trim();

    // 按斜杠分割星期几，支持 MONDAY/TUESDAY/WEDNESDAY 格式
    const days = dayStr
      .split("/")
      .map((day) => day.trim())
      .filter((day) => day);

    businessHours.push({
      days, // 支持多个星期几共享同一营业时间
      startTime,
      endTime,
    });
  });

  return businessHours;
};

/**
 * 获取指定日期的营业时间
 * @param date 日期
 * @returns 营业时间对象，如果不营业返回null
 */
const getBusinessHoursForDate = (date: Date): BusinessHours | null => {
  if (!storeBusinessHours.value) return null;

  const businessHours = parseBusinessHours(storeBusinessHours.value);

  // 获取星期几的英文名称（确保是大写）(不要国际化导致判断失效)
  const dayNames = [
    "SUNDAY",
    "MONDAY",
    "TUESDAY",
    "WEDNESDAY",
    "THURSDAY",
    "FRIDAY",
    "SATURDAY",
  ];
  const dayName = dayNames[date.getDay()];

  // 查找包含当前星期几的营业时间
  return businessHours.find((hours) => hours.days.includes(dayName)) || null;
};

/**
 * 检查日期是否营业
 * @param date 日期
 * @returns 是否营业
 */
const isDateOpen = (date: Date): boolean => {
  if (!storeBusinessHours.value) return true; // 如果没有营业时间限制，默认营业
  return getBusinessHoursForDate(date) !== null;
};

/**
 * 检查日期是否应该显示为可选择状态（营业且有可用时间段）
 * @param date 日期
 * @returns 是否可选择
 */
const isDateSelectable = (date: Date): boolean => {
  // 新增：限制只能预约周一 / 周四 / 周五
  if (!isAllowedDay(date)) {
    return false;
  }

  // 如果只选日期模式，营业即可选择
  if (onlySelectDay.value) {
    if (!storeBusinessHours.value) return true;
    return isDateOpen(date);
  }

  // 原逻辑：需要营业且有可用时间段
  if (!storeBusinessHours.value) return true; // 如果没有营业时间限制，默认可选择
  if (!isDateOpen(date)) return false;
  return hasAvailableTimeSlots(date);
};

// 生成未来的日期（显示所有日期，但标记营业状态）
const dateOptions = computed(() => {
  const dates: Date[] = [];
  const today = new Date();

  // 生成连续的5天日期（包括不营业的日期）
  for (let i = 0; i < 5; i++) {
    const date = new Date(today);
    date.setDate(today.getDate() + i);
    dates.push(date);
  }

  return dates;
});

// 状态管理 - 初始化为第一个营业日期
const selectedDate = ref<Date>();

// 检查指定时间是否在营业时间内
const isTimeInBusinessHours = (
  hour: number,
  minute: number,
  businessHours: BusinessHours
): boolean => {
  const timeStr = `${hour.toString().padStart(2, "0")}:${minute
    .toString()
    .padStart(2, "0")}`;
  return timeStr >= businessHours.startTime && timeStr <= businessHours.endTime;
};

// 检查指定日期是否有可用时间段
const hasAvailableTimeSlots = (date: Date): boolean => {
  const now = new Date();
  const currentHour = now.getHours();
  const currentMinute = now.getMinutes();

  // 获取指定日期的营业时间
  const businessHours = getBusinessHoursForDate(date);

  // 如果没有营业时间，返回false
  if (!businessHours) {
    return false;
  }

  // 解析营业时间的开始和结束时间
  const [startHour, startMinute] = businessHours.startTime
    .split(":")
    .map(Number);
  const [endHour, endMinute] = businessHours.endTime.split(":").map(Number);

  // 检查是否有可用时间段
  for (let hour = startHour; hour <= endHour; hour++) {
    for (let minute = 0; minute < 60; minute += 30) {
      // 检查时间段开始时间是否在营业时间内
      if (!isTimeInBusinessHours(hour, minute, businessHours)) {
        continue;
      }

      // 计算时间段结束时间
      let nextHour = hour;
      let nextMinute = minute + 30;
      if (nextMinute >= 60) {
        nextHour++;
        nextMinute = 0;
      }

      // 检查时间段结束时间是否超出营业时间
      if (!isTimeInBusinessHours(nextHour, nextMinute, businessHours)) {
        if (
          nextHour > endHour ||
          (nextHour === endHour && nextMinute > endMinute)
        ) {
          nextHour = endHour;
          nextMinute = endMinute;
        }
      }

      // 避免生成开始时间和结束时间相同的无效时间段
      if (hour === nextHour && minute === nextMinute) {
        continue;
      }

      // 如果是今天，过滤掉已经过去的时间
      if (date.toDateString() === now.toDateString()) {
        if (
          hour < currentHour ||
          (hour === currentHour && minute <= currentMinute)
        ) {
          continue;
        }
      }

      // 如果能到这里，说明有可用时间段
      return true;
    }
  }

  return false;
};

// 初始化选中日期为第一个有可用时间段的营业日期
const initializeSelectedDate = () => {
  if (onlySelectDay.value) {
    // 仅选日期模式：选择第一个“允许预约且营业”的日期（或第一个允许的日期）
    const firstOpen = dateOptions.value.find(
      (d) => isAllowedDay(d) && isDateOpen(d)
    );
    const firstAllowed = firstOpen || dateOptions.value.find((d) => isAllowedDay(d));
    selectedDate.value = firstAllowed || dateOptions.value[0];
    nextTick(() => updateScrollPosition());
    return;
  }

  // 非仅选日期模式：保留原逻辑
  for (const date of dateOptions.value) {
    if (isDateSelectable(date)) {
      selectedDate.value = date;
      nextTick(() => {
        updateScrollPosition();
      });
      return;
    }
  }

  const today = new Date();
  const nextBusinessDate = findNextBusinessDate(today);
  if (nextBusinessDate) {
    selectedDate.value = nextBusinessDate;
    nextTick(() => {
      updateScrollPosition();
      uni.showToast({
        title: t('pages.address.reservationTime.currentTimeExpired'),
        icon: "none",
        duration: 2000,
      });
    });
  } else {
    selectedDate.value = dateOptions.value[0];
    nextTick(() => {
      updateScrollPosition();
    });
  }
};

// 监听dateOptions变化，初始化选中日期
watch(
  dateOptions,
  () => {
    if (!selectedDate.value) {
      initializeSelectedDate();
    }
  },
  { immediate: true }
);

// 监听营业时间字符串变化，重新初始化选中日期
watch(
  storeBusinessHours,
  () => {
    if (storeBusinessHours.value) {
      initializeSelectedDate();
    }
  },
  { immediate: true }
);
const selectedTimeSlot = ref<string>("");

// 横向滚动距离
const scrollLeft = ref<number>(0);

// 计算并设置横向滚动距离
const updateScrollPosition = () => {
  if (!selectedDate.value) return;
  
  // 找到选中日期在 dateOptions 中的索引
  const selectedIndex = dateOptions.value.findIndex(date => 
    dayjs(date).isSame(dayjs(selectedDate.value), 'day')
  );
  
  if (selectedIndex === -1) return;
  
  // 每个日期卡片的宽度：240rpx + 28rpx 间距 = 268rpx
  // 但第一个卡片没有左边距，所以需要特殊处理
  const cardWidth = 240; // rpx
  const cardMargin = 28; // rpx
  
  // 计算滚动距离，让选中的卡片尽量居中显示
  let scrollDistance = 0;
  if (selectedIndex > 0) {
    // 第一个卡片没有左边距，从第二个开始每个卡片占用 240 + 28 = 268rpx
    scrollDistance = selectedIndex * (cardWidth + cardMargin);
    
    // 减去一些距离让选中项更居中（可根据屏幕宽度调整）
    scrollDistance = Math.max(0, scrollDistance - 100);
  }
  
  scrollLeft.value = scrollDistance;
};

// 格式化日期显示
const formatDateDisplay = (date: Date) => {
  const today = dayjs();
  const targetDate = dayjs(date);

  if (targetDate.isSame(today, "day")) {
    return "Today";
  } else if (targetDate.isSame(today.add(1, "day"), "day")) {
    return "Tomorrow";
  } else {
    // 返回星期几
    return targetDate.format("dddd");
  }
};

// 格式化日期为月份和日期（不包含年份），不可选择日期显示"不营业"
const formatDateOnly = (date: Date) => {
  if (!isDateSelectable(date)) {
    return t('pages.address.reservationTime.notAvailable')
  }
  return dayjs(date).format('MMMM D')
};

/**
 * 检查时间是否在营业时间内
 * @param hour 小时
 * @param minute 分钟
 * @param businessHours 营业时间对象
 * @returns 是否在营业时间内
 */

// 生成时间段选项（根据商家营业时间过滤）
const timeSlots = computed(() => {
  const slots: string[] = [];
  const now = new Date();
  const currentHour = now.getHours();
  const currentMinute = now.getMinutes();

  // 如果还没有选中日期，返回空数组
  if (!selectedDate.value) {
    return slots;
  }

  // 获取选中日期的营业时间
  const businessHours = getBusinessHoursForDate(selectedDate.value);

  // 如果没有营业时间限制，使用原有逻辑（0-24小时）
  if (!businessHours) {
    for (let hour = 0; hour < 24; hour++) {
      for (let minute = 0; minute < 60; minute += 30) {
        // 如果是今天，过滤掉已经过去的时间
        if (selectedDate.value.toDateString() === now.toDateString()) {
          if (
            hour < currentHour ||
            (hour === currentHour && minute <= currentMinute)
          ) {
            continue;
          }
        }

        const startHour = hour.toString().padStart(2, "0");
        const startMinute = minute.toString().padStart(2, "0");
        const endHour =
          minute === 30
            ? (hour + 1).toString().padStart(2, "0")
            : hour.toString().padStart(2, "0");
        const endMinute = minute === 30 ? "00" : "30";

        const timeSlot = `${startHour}:${startMinute} - ${endHour}:${endMinute}`;
        slots.push(timeSlot);
      }
    }
    return slots;
  }

  // 解析营业时间的开始和结束时间
  const [startHour, startMinute] = businessHours.startTime
    .split(":")
    .map(Number);
  const [endHour, endMinute] = businessHours.endTime.split(":").map(Number);

  // 生成营业时间内的时间段
  for (let hour = startHour; hour <= endHour; hour++) {
    for (let minute = 0; minute < 60; minute += 30) {
      // 检查时间段开始时间是否在营业时间内
      if (!isTimeInBusinessHours(hour, minute, businessHours)) {
        continue;
      }

      // 计算时间段结束时间
      let nextHour = hour;
      let nextMinute = minute + 30;
      if (nextMinute >= 60) {
        nextHour++;
        nextMinute = 0;
      }

      // 检查时间段结束时间是否超出营业时间
      if (!isTimeInBusinessHours(nextHour, nextMinute, businessHours)) {
        // 如果结束时间超出营业时间，但开始时间在营业时间内，则调整结束时间为营业结束时间
        if (
          nextHour > endHour ||
          (nextHour === endHour && nextMinute > endMinute)
        ) {
          nextHour = endHour;
          nextMinute = endMinute;
        }
      }

      // 避免生成开始时间和结束时间相同的无效时间段（如 18:00 - 18:00）
      if (hour === nextHour && minute === nextMinute) {
        continue;
      }

      // 如果是今天，过滤掉已经过去的时间
      if (selectedDate.value.toDateString() === now.toDateString()) {
        if (
          hour < currentHour ||
          (hour === currentHour && minute <= currentMinute)
        ) {
          continue;
        }
      }

      const startHourStr = hour.toString().padStart(2, "0");
      const startMinuteStr = minute.toString().padStart(2, "0");
      const endHourStr = nextHour.toString().padStart(2, "0");
      const endMinuteStr = nextMinute.toString().padStart(2, "0");

      const timeSlot = `${startHourStr}:${startMinuteStr} - ${endHourStr}:${endMinuteStr}`;
      slots.push(timeSlot);
    }
  }

  return slots;
});

// 监听时间段变化，如果当前选中日期没有可用时间段，自动选择下一个营业日期
watch(timeSlots, (newSlots) => {
  if (onlySelectDay.value) return; // 仅选日期模式不需要处理时间段
  if (selectedDate.value && newSlots.length === 0) {
    // 当前选中日期没有可用时间段，寻找下一个营业日期
    const nextBusinessDate = findNextBusinessDate(selectedDate.value);
    if (nextBusinessDate) {
      selectedDate.value = nextBusinessDate;
      selectedTimeSlot.value = ""; // 清空已选择的时间段
      uni.showToast({
        title: t('pages.address.reservationTime.noAvailableTime'),
        icon: "none",
        duration: 2000,
      });
    }
  }
});

// 寻找下一个有可用时间段的营业日期
const findNextBusinessDate = (currentDate: Date): Date | null => {
  const maxDays = 30; // 最多向前查找30天
  for (let i = 1; i <= maxDays; i++) {
    const nextDate = new Date(currentDate);
    nextDate.setDate(currentDate.getDate() + i);

    // 检查是否在dateOptions范围内
    const isInRange = dateOptions.value.some((date) =>
      dayjs(date).isSame(dayjs(nextDate), "day")
    );

    if (
      isInRange &&
      isAllowedDay(nextDate) &&
      isDateOpen(nextDate) &&
      hasAvailableTimeSlots(nextDate)
    ) {
      return nextDate;
    }
  }
  return null;
};

// 选择日期
const selectDate = (date: Date) => {
  // 检查日期是否可选择，如果不可选择则不允许选择
  if (!isDateSelectable(date)) {
    uni.showToast({
      title: t('pages.address.reservationTime.dateNotSelectable'),
      icon: "none",
    });
    return;
  }

  selectedDate.value = date;
  // 选择新日期后，清空已选择的时间段
  selectedTimeSlot.value = "";
};

// 选择时间段
const selectTimeSlot = (timeSlot: string) => {
  selectedTimeSlot.value = timeSlot;
};

// 提交预约
const submitReservation = () => {
  // 非仅选日期模式，需要选择时间段
  if (!onlySelectDay.value) {
    if (!selectedTimeSlot.value) {
      uni.showToast({
        title: t('pages.address.reservationTime.selectTimeSlot'),
        icon: "none",
      });
      return;
    }
  }

  // 计算开始/结束时间
  const selectedDateDayjs = dayjs(selectedDate.value);
  let startTime: dayjs.Dayjs;
  let endTime: dayjs.Dayjs;

  if (onlySelectDay.value) {
    // 仅选日期：优先使用营业时间范围；若无营业时间限制，则使用当天起止
    const bh = getBusinessHoursForDate(selectedDate.value);
    if (bh) {
      const [startHour, startMinute] = bh.startTime.split(':').map(Number);
      const [endHour, endMinute] = bh.endTime.split(':').map(Number);
      startTime = selectedDateDayjs
        .hour(startHour)
        .minute(startMinute)
        .second(0)
        .millisecond(0);
      endTime = selectedDateDayjs
        .hour(endHour)
        .minute(endMinute)
        .second(0)
        .millisecond(0);
    } else {
      startTime = selectedDateDayjs.startOf('day');
      endTime = selectedDateDayjs.endOf('day');
    }
  } else {
    // 选择了时间段：解析并生成起止时间
    const [startTimeStr, endTimeStr] = selectedTimeSlot.value.split(' - ');
    const [startHour, startMinute] = startTimeStr.split(':').map(Number);
    const [endHour, endMinute] = endTimeStr.split(':').map(Number);
    startTime = selectedDateDayjs
      .hour(startHour)
      .minute(startMinute)
      .second(0)
      .millisecond(0);
    endTime = selectedDateDayjs
      .hour(endHour)
      .minute(endMinute)
      .second(0)
      .millisecond(0);
  }

  console.log("预约信息:", {
    date: selectedDate.value,
    timeSlot: onlySelectDay.value ? '' : selectedTimeSlot.value,
    startTime: startTime.valueOf(),
    endTime: endTime.valueOf(),
  });

  uni.$emit(EventEnum.CHOOSE_APPOINTMENT_TIME, {
    date: selectedDate.value,
    timeSlot: onlySelectDay.value ? '' : selectedTimeSlot.value,
    startTime: startTime.valueOf(),
    endTime: endTime.valueOf(),
  });

  uni.showToast({
    title: t('pages.address.reservationTime.reservationSuccess'),
    icon: "none",
  });

  uni.navigateBack();
};

const storeId = ref(null);

// 页面加载时处理参数
onLoad((options: any) => {
  if (options.storeId) {
    storeId.value = options.storeId;
  }
  if (options.storeBusinessHours) {
    storeBusinessHours.value = options.storeBusinessHours;
    // 如果传递了该参数，进入仅选日期模式
    onlySelectDay.value = true;
  }
  // 无论是否传参，统一初始化选中日期，避免首屏未选导致不显示时间段
  nextTick(() => {
    initializeSelectedDate();
  });
});
</script>

<template>
  <view class="">
    <navbar />
    <view class="mt-20rpx px-30rpx text-46rpx lh-46rpx text-#333 font-bold">
      {{ t("pages.address.appTime") }}
    </view>
    <view class="px-30rpx pt-52rpx pb-50rpx w-screen bg-white">
      <scroll-view class="w-full whitespace-nowrap" scroll-x="true" :scroll-left="scrollLeft">
        <template v-for="(item, index) in dateOptions" :key="index">
          <view
              @click="selectDate(item)"
              :class="[
                index === 0 ? '' : 'ml-28rpx',
                selectedDate && dayjs(selectedDate).isSame(dayjs(item), 'day')
                  ? 'border-#333'
                  : 'border-#D8D8D8',
                !isDateSelectable(item)
                  ? 'opacity-50 cursor-not-allowed'
                  : 'cursor-pointer',
              ]"
              class="inline-block border-solid border-1px w-240rpx h-140rpx rounded-20rpx px-32rpx py-36rpx"
          >
            <view
                :class="!isDateSelectable(item) ? 'text-#999' : 'text-#333'"
                class="text-28rpx lh-28rpx mb-12rpx"
            >
              {{ formatDateDisplay(item) }}
            </view>
            <view
                :class="!isDateSelectable(item) ? 'text-#CCC' : 'text-#7D7D7D'"
                class="text-28rpx"
            >
              {{ formatDateOnly(item) }}
            </view>
          </view>
        </template>
      </scroll-view>
    </view>
    <!-- 时间段选择区域：在仅选日期模式下隐藏 -->
    <view v-if="!onlySelectDay" class="pb-138rpx">
      <view
        v-for="(timeSlot, index) in timeSlots"
        :key="index"
        class="h-108rpx flex-center-sb px-30rpx"
        :class="[
          index === 0 ? '' : 'border-top',
          timeSlots.length - 1 === index ? 'border-bottom' : '',
        ]"
        @click="selectTimeSlot(timeSlot)"
      >
        <text class="text-32rpx font-regular">{{ timeSlot }}</text>
        <!-- 单选按钮 -->
        <image
          :src="
            selectedTimeSlot === timeSlot
              ? '/static/images/chef/133.png'
              : '/static/images/chef/134.png'
          "
          class="w-48rpx h-48rpx shrink-0"
          mode="aspectFit"
        />
      </view>
    </view>

    <fixed-bottom-large-btn
      class="z-100"
      fixed
      :text="`${t('common.submit')}`"
      @click="submitReservation"
    />
  </view>
</template>

<style>
page {
  background-color: #fff;
}
</style>
