<script setup>
import { computed, ref } from 'vue';
import { useRouter } from 'vue-router';

import dayjs from 'dayjs';

const props = defineProps({
  year: {
    type: Number,
    required: true,
  },
  weekNumber: {
    type: Number,
    required: true,
    alias: 'week-number',
  },
  daylist: {
    type: Array,
    required: true,
    alias: 'daylist',
  },
  overduedaylist: {
    type: Array,
    required: true,
    alias: 'overduedaylist',
  },
});
const now = new Date();
const year = now.getFullYear();
const month = (now.getMonth() + 1).toString().padStart(2, '0');
const day = now.getDate().toString().padStart(2, '0');
const today = `${year}-${month}-${day}`;
const weeklist = computed(() => {
  const daylists = [...props.daylist];
  return daylists
    .filter((item) => item.isOverdue !== '1')
    .map((item) => {
      let status = 'Authorizable';
      switch (item.status) {
        case 0: {
          status = ''; // 任务未开始或取消
          break;
        }
        case 1: {
          if (item?.endTime) {
            const endTime = new Date(item.endTime).getTime();
            const currentTime = Date.now();
            if (endTime <= currentTime) {
              status = 'overdue';
            } else if (
              endTime > currentTime &&
              endTime - currentTime <= 24 * 60 * 60 * 1000
            ) {
              status = 'Authorized';
            }
          }
          break;
        }
        case 2: {
          status = 'overdue';
          break;
        }
        case 3: {
          status = 'Authorized1';
          break;
        }
        default: {
          break;
        }
      }
      return {
        id: item.id,
        name: item.taskName,
        date: dayjs(new Date(item?.displayDate))
          .format('YYYY-MM-DD HH:mm:ss')
          .split(' ')[0],
        start: dayjs(new Date(item?.displayDate))
          .format('YYYY-MM-DD HH:mm:ss')
          .split(' ')[1],
        status,
      };
    });
});
const overduelist = computed(() => {
  const daylists = [...props.overduedaylist];
  return daylists.map((item) => ({
    id: item.id,
    name: item?.taskName,
    date: dayjs(new Date(item?.displayDate))
      .format('YYYY-MM-DD HH:mm:ss')
      .split(' ')[0],
    start: dayjs(new Date(item?.displayDate))
      .format('YYYY-MM-DD HH:mm:ss')
      .split(' ')[1],
    status: item?.isOverdue == '1' ? 'overdue' : '',
  }));
});
const tasks = computed(() => {
  return [...weeklist.value, ...overduelist.value];
});

const weekDays = computed(() => {
  const days = [];
  const firstDayOfYear = new Date(props.year, 0, 1);
  const firstDayOfWeek = firstDayOfYear.getDay();
  const diffToFirstMonday = firstDayOfWeek === 0 ? -6 : 1 - firstDayOfWeek;
  const firstMonday = new Date(firstDayOfYear);
  firstMonday.setDate(firstDayOfYear.getDate() + diffToFirstMonday);
  const targetMonday = new Date(firstMonday);
  targetMonday.setDate(firstMonday.getDate() + (props.weekNumber - 1) * 7);
  for (let i = 0; i < 7; i++) {
    const currentDate = new Date(targetMonday);
    currentDate.setDate(targetMonday.getDate() + i);
    const dateStr = currentDate.getDate().toString();
    const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
    const weekday = weekdays[currentDate.getDay()];
    const year = currentDate.getFullYear();
    const month = (currentDate.getMonth() + 1).toString().padStart(2, '0');
    const day = currentDate.getDate().toString().padStart(2, '0');
    const fullDate = `${year}-${month}-${day}`;
    days.push({
      date: dateStr,
      weekday,
      fullDate,
    });
  }
  return days;
});

// Hour slots for calendar (隐藏00:00，只显示08:00和16:00)
const hours = Array.from({ length: 3 }).map(
  (_, i) => `${((i + 1) * 8).toString().padStart(2, '0')}:00`,
); // 显示08:00、16:00和24:00三个时间段

// height per hour slot (px)
const hourHeight = 360;

// parse time 'HH:mm' -> minutes since 00:00
const parseMinutes = (timeStr) => {
  const [hh, mm] = timeStr.split(':').map(Number);
  return hh * 60 + mm;
};

// Get tasks for a specific day and arrange without overlapping
const getTasksForDay = (date) => {
  const dayFull = weekDays.value.find((d) => d.date === date)?.fullDate;
  if (!dayFull) return { timeSlots: {}, allTasks: [] };
  const list = tasks.value.filter((task) => task.date === dayFull);

  // 对任务进行排序，将overdue状态的任务放在最前面，然后按start时间排序
  const sortedList = [...list].sort((a, b) => {
    if (a.status === 'overdue' && b.status !== 'overdue') {
      return -1;
    }
    if (a.status !== 'overdue' && b.status === 'overdue') {
      return 1;
    }
    // 按start时间排序
    return parseMinutes(a.start) - parseMinutes(b.start);
  });

  // 按时间段分组任务
  const timeSlots = { '00:00': [], '08:00': [], '16:00': [] };
  const allTasks = [];
  const hourHeight = 360;

  sortedList.forEach((task) => {
    const startTime = parseMinutes(task.start);
    const hours = Math.floor(startTime / 60);
    let slotKey;

    // 确定任务属于哪个时间段 (08:00, 16:00, 24:00)
    if (hours < 8) {
      slotKey = '00:00';
    } else if (hours < 16) {
      slotKey = '08:00';
    } else {
      slotKey = '16:00';
    }

    timeSlots[slotKey].push(task);
  });

  // 计算每个时间段的起始位置
  const slotStartPositions = {
    '00:00': 0,
    '08:00': hourHeight,
    '16:00': hourHeight * 2,
  };

  // 为不同时间段设置不同的基础zIndex值
  // 前面的时间段应该有更高的zIndex，这样展开时不会被后面的时间段遮挡
  const baseZIndex = {
    '00:00': 30, // 最早的时间段，最高层级
    '08:00': 20, // 中间时间段，中层级
    '16:00': 10, // 最晚的时间段，最低层级
  };

  // 计算每个任务的位置
  Object.keys(timeSlots).forEach((slotKey) => {
    // 在每个时间段内，将overdue状态的任务放在最前面，然后按start时间排序
    const slotTasks = [...timeSlots[slotKey]].sort((a, b) => {
      // 将overdue状态的任务放在最前面
      if (a.status === 'overdue' && b.status !== 'overdue') {
        return -1;
      }
      if (a.status !== 'overdue' && b.status === 'overdue') {
        return 1;
      }
      // 相同状态下按start时间排序
      return parseMinutes(a.start) - parseMinutes(b.start);
    });
    const slotStart = slotStartPositions[slotKey];
    const slotZIndex = baseZIndex[slotKey];

    // 计算每个任务在时间段内的相对位置
    slotTasks.forEach((task, idx) => {
      // 基于任务在时间段内的索引计算垂直位置
      // 每个任务32px高度 + 4px间距
      const top = slotStart + idx * (32 + 4);
      const height = 32;

      allTasks.push({
        ...task,
        top,
        height,
        zIndex: slotZIndex + idx,
        slotKey,
        slotIndex: idx,
      });
    });
  });

  return { timeSlots, allTasks };
};
// Get task status class based on task properties
// const getTaskStatusClass = (task) => {
//   switch (task.status) {
//     case 'not-started': {
//       return 'not-started';
//     }
//     case 'completed': {
//       return 'completed';
//     }
//     case 'overdue': {
//       return 'overdue';
//     }
//     case 'processable': {
//       return 'processable';
//     }
//     default: {
//       return 'not-started';
//     }
//   }
// };

// 计算当前时间线的位置
const currentTimeLineStyle = computed(() => {
  const now = new Date();
  const hours = now.getHours();
  const minutes = now.getMinutes();
  const totalMinutes = hours * 60 + minutes;
  const top = (totalMinutes / (24 * 60)) * (hourHeight * 3); // 因为有3个小时槽
  return {
    top: `${top}px`,
  };
});

// 格式化当前时间标签
const currentTimeLabel = computed(() => {
  const now = new Date();
  const hours = now.getHours().toString().padStart(2, '0');
  const minutes = now.getMinutes().toString().padStart(2, '0');
  return `${hours}:${minutes}`;
});

// 状态对应颜色（匹配图片样式）
// const statusColor = (status) => {
//   switch (status) {
//     case 'overdue':
//       return '#FFE8E8'; // 淡红色
//     case 'completed':
//       return '#E6F3FF'; // 淡蓝色
//     case 'processable':
//       return '#F0F9E8'; // 淡绿色
//     case 'not-started':
//     case 'cancelled':
//     default:
//       return '#F5F5F5'; // 浅灰色
//   }
// };

// 跟踪每天每个时间段任务的展开状态
const expandedTimeSlots = ref({});

// 切换某天某个时间段任务的展开/折叠状态
const toggleExpand = (date, slotKey) => {
  const key = `${date}_${slotKey}`;
  expandedTimeSlots.value[key] = !expandedTimeSlots.value[key];
};

// 检查某天某个时间段任务是否展开
const isExpanded = (date, slotKey) => {
  const key = `${date}_${slotKey}`;
  return expandedTimeSlots.value[key] || false;
};

// 计算展开按钮的位置
const getExpandButtonPosition = (date, slotKey) => {
  const { timeSlots, allTasks } = getTasksForDay(date);
  const slotTasks = timeSlots[slotKey] || [];
  const slotStart = {
    '00:00': 0,
    '08:00': 360,
    '16:00': 720,
  }[slotKey];

  if (slotTasks.length === 0) return slotStart;

  if (
    isExpanded(weekDays.value.find((d) => d.date === date)?.fullDate, slotKey)
  ) {
    // 如果展开，找到当前时间段最后一个任务的位置，在其下方放置按钮
    const lastTask = allTasks.findLast((task) => task.slotKey === slotKey);
    return lastTask.top + lastTask.height + 4; // 4px间距，使按钮更靠近任务
  } else {
    // 如果未展开，在当前时间段第8个任务下方放置按钮（如果有8个任务的话）
    if (slotTasks.length >= 9) {
      const ninthTask = allTasks.find(
        (task) => task.slotKey === slotKey && task.slotIndex === 8,
      );
      return ninthTask.top + ninthTask.height + 4; // 4px间距，与展开状态保持一致
    }

    // 如果任务不足8个（理论上不会发生，因为按钮只在>8时显示）
    const lastTask = allTasks.findLast((task) => task.slotKey === slotKey);
    return lastTask.top + lastTask.height + 4;
  }
};

// 计算展开时间段背景的样式
const getExpandedTimeSlotStyle = (date, slotKey) => {
  const { allTasks } = getTasksForDay(date);
  const slotTasks = allTasks.filter((task) => task.slotKey === slotKey);

  if (slotTasks.length === 0) return {};

  // 找到该时间段第一个任务的位置
  const firstTask = slotTasks[0];
  // 找到该时间段最后一个任务的位置
  const lastTask = slotTasks[slotTasks.length - 1];

  // 计算背景的位置和尺寸
  const top = firstTask.top - 4;
  // 增加高度以包含展开/收起按钮（按钮高度32px + 4px间距）
  const height = lastTask.top + lastTask.height - firstTask.top + 8 + 36;
  const width = 160 + 12; // 任务宽度 + 左右边距

  // 获取该时间段的基础zIndex，确保背景在任务下方
  const baseZIndex = {
    '00:00': 29, // 比任务的基础zIndex低1
    '08:00': 19,
    '16:00': 9,
  }[slotKey];

  return {
    top: `${top}px`,
    height: `${height}px`,
    width: `${width}px`,
    zIndex: baseZIndex,
  };
};

const router = useRouter();

const handleTaskClick = (task) => {
  router.push(`/schedule/detail/${task.id}`);
};
</script>
<template>
  <div class="week-schedule">
    <div class="calendar">
      <div class="time-column">
        <div class="time-header">GMT+8</div>
        <div class="time-slots">
          <div v-for="h in hours" :key="h" class="time-slot">
            <span class="hour-text">{{ h }}</span>
          </div>
        </div>
      </div>
      <!-- 当前时间线 -->
      <div class="current-line" :style="currentTimeLineStyle">
        <span class="current-time-label">{{ currentTimeLabel }}</span>
      </div>
      <div class="days-grid">
        <div class="days-header">
          <div
            v-for="day in weekDays"
            :key="day.date"
            class="days-header-item"
            :class="{ today: day.fullDate === today }"
          >
            <div class="date-weekday">
              <div class="weekday">{{ day.weekday }}</div>
              <div class="date">{{ day.date }}</div>
            </div>
          </div>
        </div>
        <div class="days-body">
          <div v-for="day in weekDays" :key="day.date" class="day-column">
            <div class="day-body-inner">
              <!-- hour lines -->
              <div class="hour-lines">
                <div
                  v-for="(h, i) in hours"
                  :key="h"
                  class="hour-line"
                  :style="{ height: `${hourHeight}px` }"
                ></div>
              </div>
              <!-- tasks positioned -->
              <div class="tasks-absolute">
                <!-- 获取按时间段分组的任务 -->
                <template v-if="getTasksForDay(day.date)">
                  <template
                    v-for="slotKey in ['00:00', '08:00', '16:00']"
                    :key="slotKey"
                  >
                    <!-- 展开时间段的背景装饰 -->
                    <div
                      v-if="
                        isExpanded(day.fullDate, slotKey) &&
                        getTasksForDay(day.date).timeSlots[slotKey]?.length > 9
                      "
                      class="expanded-time-slot-bg"
                      :style="getExpandedTimeSlotStyle(day.date, slotKey)"
                    ></div>

                    <!-- 显示该时间段的任务 -->
                    <div
                      v-for="task in getTasksForDay(day.date).allTasks.filter(
                        (t) => t.slotKey === slotKey,
                      )"
                      :key="task.id"
                      class="task-block"
                      :class="task.status"
                      :style="{
                        top: `${task.top}px`,
                        height: `${task.height}px`,
                        width: '160px',
                        color: '#333',
                        display:
                          task.slotIndex < 9 ||
                          isExpanded(day.fullDate, slotKey)
                            ? 'flex'
                            : 'none',
                        zIndex: task.zIndex,
                      }"
                      @click="handleTaskClick(task)"
                      title="{{ task.name }}"
                    >
                      <div class="task-content">
                        <div class="task-title">
                          {{ task.name }}
                        </div>
                      </div>
                    </div>

                    <!-- 该时间段的展开/折叠按钮 -->
                    <div
                      v-if="
                        getTasksForDay(day.date).timeSlots[slotKey] &&
                        getTasksForDay(day.date).timeSlots[slotKey].length > 9
                      "
                      class="expand-btn"
                      :style="{
                        top: `${getExpandButtonPosition(day.date, slotKey)}px`,
                        width: '160px',
                      }"
                      @click="toggleExpand(day.fullDate, slotKey)"
                    >
                      <span>{{
                        isExpanded(day.fullDate, slotKey)
                          ? '收起'
                          : `还有 ${getTasksForDay(day.date).timeSlots[slotKey].length - 9} 个日程...`
                      }}</span>
                    </div>
                  </template>
                </template>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.week-schedule {
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  box-sizing: border-box;
  max-height: 100%;
  margin: 0;
  padding: 0;
}

.calendar {
  display: flex;
  gap: 0;
  width: 100%;
  overflow: visible;
  margin: 0;
  padding: 0;
  position: relative;
}

.time-column {
  width: 100px;
  flex: 0 0 100px;
  border-right: 1px solid #e8e8e8;
}

.time-header {
  height: 35px;
  box-sizing: border-box;
  font-size: 12px;
  color: #666;
  padding: 4px;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f5f7fa;
  border-right: 1px solid #e4e7ed;
  border-bottom: 1px solid #e4e7ed;
}

.time-slots {
  margin: 0;
  padding: 0;
  width: 100%;
  box-sizing: border-box;
  overflow: hidden;
}

.time-slot {
  height: 360px;
  text-align: left;
  font-size: 12px;
  font-weight: 400;
  color: #666;
  border-top: 1px solid #e8e8e8;
  box-sizing: border-box;
  padding-left: 16px;
  position: relative;
  margin: 0;
  padding-top: 0;
  padding-bottom: 4px;
  display: flex;
  align-items: flex-end;
}

.time-slot:first-child {
  border-top: none;
}

.hour-text {
  font-size: 12px;
  color: #666;
}

.days-grid {
  flex: 1 1 auto;
  position: relative;
  overflow: hidden;
}

.days-header {
  display: flex;
}

.days-header-item {
  flex: 1;
  min-width: 80px;
  padding: 4px;
  text-align: center;
  background: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
  border-right: 1px solid #e4e7ed;
  box-sizing: border-box;
  height: 35px;
  display: flex;
  flex-direction: column;
  align-items: first baseline;
  justify-content: center;
}

.days-body {
  display: flex;
  position: relative;
  margin: 0;
  padding: 0;
  overflow: visible;
}

.day-column {
  flex: 1;
  min-width: 100px;
  border-right: 1px solid #eaeaea;
  position: relative;
  overflow: visible;
}

.day-column:last-child {
  border-right: none;
}

.day-body-inner {
  position: relative;
  margin: 0;
  padding: 0;
  overflow: visible;
}

.hour-lines {
  position: relative;
  margin: 0;
  padding: 0;
  overflow: visible;
}

.hour-line {
  border-top: 1px solid #e8e8e8;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.hour-line:first-child {
  border-top: none;
}

.tasks-absolute {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 2;
  overflow: visible;
}

.task-block {
  width: 160px;
  margin-top: 4px;
  /* height: 32px; */
  position: absolute;
  left: 6px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 4px 6px;
  border-radius: 4px;
  overflow: hidden;
  font-size: 12px;
  font-weight: normal;
  box-shadow: none;
  /* max-height: 26px; */
  border-left: 3px solid;
  background-clip: padding-box;
  margin-bottom: 2px;
  background-color: #f1f1f1;
  border-left-color: #8c8c8c;
}

/* Task status background colors */
.task-block.Authorizable {
  background-color: #e4edff;
  border-left-color: #215acd;
}

.task-block.overdue {
  background-color: #ffe6e0;
  border-left-color: #d34b27;
}

.task-block.Authorized1 {
  background-color: #d6efe6;
  border-left-color: #339169;
}
.task-block.Authorized {
  background-color: #ffead6;
  border-left-color: #ff9429;
}
/* .task-block.not-started {
  background-color: #f5f5f5;
  border-left-color: #d9d9d9;
} */

.task-content {
  flex: 1 1 auto;
  min-width: 0;
}

.task-content:hover {
  background-color: rgba(24, 144, 255, 0.1);
}

.task-title {
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: left;
  width: 100%;
  font-weight: normal;
}

.current-line {
  position: absolute;
  left: 100px;
  right: 0;
  height: 1px;
  background: #eb5e12;
  z-index: 10;
  pointer-events: none;
  width: calc(100% - 100px);
  /* box-shadow: 0 0 3px rgba(255, 215, 0, 0.8); */
}

.current-time-label {
  position: absolute;
  left: -70px;
  top: -8px;
  font-size: 14px;
  color: #eb5e12;
  z-index: 10;
}

.date-weekday {
  font-size: 11px;
  font-weight: normal;
  text-align: center;
  line-height: 1.2;
  transition: background-color 0.3s ease;
}

.date-weekday:hover {
  background-color: rgba(24, 144, 255, 0.04);
  border-radius: 4px;
}

.weekday {
  font-size: 12px;
  font-weight: 400;
  color: #666;
  transition: background-color 0.3s ease;
}

/* .weekday:hover {
  background-color: rgba(24, 144, 255, 0.06);
  border-radius: 2px;
} */

.date {
  text-align: left;
  font-size: 16px;
  font-weight: 500;
  font-weight: bold;
  margin-top: 1px;
  color: #333;
  transition: background-color 0.3s ease;
}

/* .date:hover {
  background-color: rgba(24, 144, 255, 0.06);
  border-radius: 2px;
} */

.days-header-item.today {
  /* background-color: #FFF2E8;
  border-bottom: 1px solid #FFBB96; */
}

.days-header-item.today .date {
  color: #1890ff;
}

.days-header-item.today .weekday {
  color: #1890ff;
}

/* 展开时间段的背景装饰 */
.expanded-time-slot-bg {
  position: absolute;
  left: 0;
  background-color: rgb(
    230,
    232,
    235
  ); /* 使用用户指定的#E6E8EB颜色，带透明度 */
  border: 1px solid rgba(208, 208, 208, 0.6);
  border-radius: 6px;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
}

/* 展开/折叠按钮样式 */
.expand-btn {
  position: absolute;
  left: 6px;
  height: 32px;
  background: transparent;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  font-size: 12px;
  color: #1890ff;
  transition: all 0.3s ease;
  z-index: 100;
  font-weight: normal;
  padding-left: 6px;
}

.expand-btn:hover {
  background: rgba(24, 144, 255, 0.06);
  color: #40a9ff;
}

.expand-btn span {
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 150px;
  padding: 0 4px;
}
</style>
