<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('');
// 是否仅选择日期（当前需求：只选哪一天配送，不选具体时间段）
const onlySelectDay = ref(true);

// 业务规则：只能预约周一 / 周四 / 周五
// 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);
};

// 生成未来 7 天：设计稿为「本周」5 个圆 +「下周」2 个圆
const dateOptions = computed(() => {
  const dates: Date[] = [];
  const today = new Date();

  for (let i = 0; i < 7; i++) {
    const date = new Date(today);
    date.setDate(today.getDate() + i);
    dates.push(date);
  }

  return dates;
});

const thisWeekDates = computed(() => dateOptions.value.slice(0, 5));
const nextWeekDates = computed(() => dateOptions.value.slice(5, 7));

// 状态管理 - 初始化为第一个营业日期
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];
    return;
  }

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

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

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

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

/** 圆圈内上行：星期（与全局 dayjs 语言一致） */
const formatWeekdayCircle = (date: Date) => dayjs(date).format("dddd");

/** 圆圈内下行：MM/DD；不可选时显示文案 */
const formatCircleSubLine = (date: Date) => {
  if (!isDateSelectable(date)) {
    return t("pages.address.reservationTime.notAvailable");
  }
  return dayjs(date).format("MM/DD");
};

/**
 * 检查时间是否在营业时间内
 * @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 isDateSelected = (date: Date) =>
  !!selectedDate.value && dayjs(selectedDate.value).isSame(dayjs(date), "day");

// 提交预约
const submitReservation = () => {
  const dateVal = selectedDate.value;
  if (!dateVal) {
    return;
  }

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

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

  if (onlySelectDay.value) {
    // 仅选日期：优先使用营业时间范围；若无营业时间限制，则使用当天起止
    const bh = getBusinessHoursForDate(dateVal);
    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: dateVal,
    timeSlot: onlySelectDay.value ? '' : selectedTimeSlot.value,
    startTime: startTime.valueOf(),
    endTime: endTime.valueOf(),
  });

  uni.$emit(EventEnum.CHOOSE_APPOINTMENT_TIME, {
    date: dateVal,
    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="reservation-time-page min-h-screen pb-180rpx">
    <navbar
      :title="t('pages.address.reservationTime.pageTitle')"
      circle-back
      custom-class="reservation-time-navbar"
    />
    <view class="reservation-time-body px-40rpx pt-40rpx">
      <view class="date-section">
        <text class="section-label">{{ t("pages.address.reservationTime.thisWeek") }}</text>
        <view class="date-row">
          <view
            v-for="(item, index) in thisWeekDates"
            :key="index"
            class="date-circle"
            :class="{
              'date-circle--selected': isDateSelected(item),
              'date-circle--disabled': !isDateSelectable(item),
            }"
            @click="selectDate(item)"
          >
            <text class="date-circle__weekday">{{ formatWeekdayCircle(item) }}</text>
            <text class="date-circle__sub">{{ formatCircleSubLine(item) }}</text>
          </view>
        </view>
      </view>
      <view v-if="nextWeekDates.length" class="date-section date-section--next">
        <text class="section-label">{{ t("pages.address.reservationTime.nextWeek") }}</text>
        <view class="date-row">
          <view
            v-for="(item, index) in nextWeekDates"
            :key="index"
            class="date-circle"
            :class="{
              'date-circle--selected': isDateSelected(item),
              'date-circle--disabled': !isDateSelectable(item),
            }"
            @click="selectDate(item)"
          >
            <text class="date-circle__weekday">{{ formatWeekdayCircle(item) }}</text>
            <text class="date-circle__sub">{{ formatCircleSubLine(item) }}</text>
          </view>
        </view>
      </view>
    </view>
    <!-- 时间段选择区域：在仅选日期模式下隐藏 -->
    <view v-if="!onlySelectDay" class="pb-138rpx mx-40rpx bg-white rounded-24rpx overflow-hidden mt-24rpx">
      <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 scoped lang="scss">
.reservation-time-body {
  box-sizing: border-box;
}

.date-section {
  margin-bottom: 48rpx;

  &--next {
    margin-bottom: 0;
  }
}

.section-label {
  display: block;
  font-size: 32rpx;
  line-height: 44rpx;
  color: #111;
  font-weight: 500;
  margin-bottom: 24rpx;
}

.date-row {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 20rpx;
  justify-content: flex-start;
}

.date-circle {
  width: 118rpx;
  height: 118rpx;
  border-radius: 50%;
  background-color: #fff;
  box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.06);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-sizing: border-box;
}

.date-circle__weekday {
  font-size: 26rpx;
  line-height: 32rpx;
  color: #111;
  font-weight: 500;
}

.date-circle__sub {
  font-size: 22rpx;
  line-height: 28rpx;
  margin-top: 6rpx;
  color: #111;
  opacity: 0.88;
}

.date-circle--selected {
  background-color: #111;
  box-shadow: none;

  .date-circle__weekday,
  .date-circle__sub {
    color: #fff;
    opacity: 1;
  }
}

.date-circle--disabled {
  opacity: 0.45;
}

.date-circle--disabled.date-circle--selected {
  opacity: 1;
}
</style>

<style lang="scss">
page {
  background-color: #f7f7f9;
}

.reservation-time-page :deep(.reservation-time-navbar.wd-navbar) {
  background-color: #f7f7f9 !important;
}
</style>
