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

// Props from parent component
const props = defineProps({
  year: {
    type: Number,
    required: true,
  },
  weekNumber: {
    type: Number,
    required: true,
    alias: 'week-number',
  },
});

// 获取当前日期（YYYY-MM-DD格式）
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 tasks = ref([
  // 为测试展开功能，添加更多12月18日的任务 (08:00时间段超过9个任务)
  { id: 27, name: '测试任务 27', date: '2025-12-18', start: '08:00', status: 'overdue', department: '运维部' },
  { id: 28, name: '测试任务 28', date: '2025-12-18', start: '08:15', status: 'processable', department: '运维部' },
  { id: 29, name: '测试任务 29', date: '2025-12-18', start: '08:30', status: 'processable', department: '运维部' },
  { id: 30, name: '测试任务 30', date: '2025-12-18', start: '08:45', status: 'processable', department: '运维部' },
  { id: 58, name: '测试任务 58', date: '2025-12-18', start: '09:00', status: 'processable', department: '技术部' },
  { id: 59, name: '测试任务 59', date: '2025-12-18', start: '09:15', status: 'processable', department: '技术部' },
 
  // 添加更多测试任务，确保08:00时间段有足够数据测试展开收起
  { id: 91, name: '需求评审会议', date: '2025-12-18', start: '12:00', status: 'processable', department: '产品部' },
  { id: 92, name: '开发进度同步', date: '2025-12-18', start: '13:30', status: 'overdue', department: '技术部' },
  { id: 93, name: 'UI设计讨论', date: '2025-12-18', start: '14:00', status: 'processable', department: '设计部' },
  { id: 94, name: '测试用例评审', date: '2025-12-18', start: '15:00', status: 'processable', department: '测试部' },
  // 16:00时间段添加更多任务
  { id: 95, name: '运维系统维护', date: '2025-12-18', start: '16:30', status: 'processable', department: '运维部' },
  { id: 96, name: '数据库备份', date: '2025-12-18', start: '17:00', status: 'processable', department: '技术部' },
  { id: 97, name: '安全漏洞扫描', date: '2025-12-18', start: '17:30', status: 'processable', department: '安全部' },
  { id: 98, name: '服务器性能监控', date: '2025-12-18', start: '18:00', status: 'overdue', department: '运维部' },
  { id: 99, name: '日志分析', date: '2025-12-18', start: '18:30', status: 'processable', department: '技术部' },
  { id: 100, name: '应用部署', date: '2025-12-18', start: '19:00', status: 'processable', department: '运维部' },
  { id: 101, name: '夜间测试', date: '2025-12-18', start: '20:00', status: 'processable', department: '测试部' },
  { id: 102, name: '系统优化', date: '2025-12-18', start: '21:00', status: 'processable', department: '技术部' },
  { id: 103, name: '紧急故障修复', date: '2025-12-18', start: '22:00', status: 'overdue', department: '运维部' },
  // 00:00时间段添加更多任务
  { id: 104, name: '凌晨数据同步', date: '2025-12-18', start: '01:00', status: 'processable', department: '技术部' },
  { id: 105, name: '批处理任务', date: '2025-12-18', start: '02:00', status: 'processable', department: '运维部' },
  { id: 106, name: '系统重启维护', date: '2025-12-18', start: '03:00', status: 'overdue', department: '运维部' },
  { id: 107, name: '数据库索引重建', date: '2025-12-18', start: '04:00', status: 'processable', department: '技术部' },
  { id: 108, name: '备份验证', date: '2025-12-18', start: '05:00', status: 'processable', department: '运维部' },
  { id: 109, name: '系统状态检查', date: '2025-12-18', start: '06:00', status: 'processable', department: '运维部' },
  { id: 110, name: '早班交接会议', date: '2025-12-18', start: '07:00', status: 'overdue', department: '运维部' },
  { id: 111, name: '应用健康检查', date: '2025-12-18', start: '07:30', status: 'processable', department: '技术部' },
  // 周一（13日）
  {
    id: 1,
    name: '量缸试水 1',
    date: '2025-12-13',
    start: '00:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 2,
    name: '量缸试水 1',
    date: '2025-12-13',
    start: '01:00',
    status: 'processable',
    department: '运维部',
  },
  // 8点以后的任务
  {
    id: 31,
    name: '上午会议',
    date: '2025-12-13',
    start: '09:00',
    status: 'processable',
    department: '技术部',
  },
  {
    id: 32,
    name: '项目评审',
    date: '2025-12-13',
    start: '10:30',
    status: 'processable',
    department: '产品部',
  },
  {
    id: 33,
    name: '代码审查',
    date: '2025-12-13',
    start: '14:00',
    status: 'processable',
    department: '技术部',
  },
  {
    id: 34,
    name: '团队午餐',
    date: '2025-12-13',
    start: '12:00',
    status: 'processable',
    department: '综合部',
  },
  {
    id: 35,
    name: '客户拜访',
    date: '2025-12-13',
    start: '15:30',
    status: 'processable',
    department: '市场部',
  },
  {
    id: 36,
    name: '每日站会',
    date: '2025-12-13',
    start: '08:30',
    status: 'processable',
    department: '技术部',
  },

  // 周二（14日） - 添加8点以后任务
  {
    id: 37,
    name: '需求分析',
    date: '2025-12-14',
    start: '09:30',
    status: 'processable',
    department: '产品部',
  },
  {
    id: 38,
    name: '设计评审',
    date: '2025-12-14',
    start: '11:00',
    status: 'overdue',
    department: '设计部',
  },
  {
    id: 39,
    name: '开发任务分配',
    date: '2025-12-14',
    start: '14:00',
    status: 'processable',
    department: '技术部',
  },
  {
    id: 40,
    name: '数据库优化',
    date: '2025-12-14',
    start: '16:00',
    status: 'processable',
    department: '技术部',
  },
  {
    id: 41,
    name: '产品演示',
    date: '2025-12-14',
    start: '10:00',
    status: 'completed',
    department: '产品部',
  },

  // 周三（15日）
  {
    id: 3,
    name: '量缸试水 1',
    date: '2025-12-15',
    start: '04:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 4,
    name: '量缸试水 1',
    date: '2025-12-15',
    start: '05:00',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 5,
    name: '量缸试水 1',
    date: '2025-12-15',
    start: '06:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 6,
    name: '量缸试水 1',
    date: '2025-12-15',
    start: '07:00',
    status: 'processable',
    department: '运维部',
  },
  // 8点以后的任务
  {
    id: 42,
    name: '性能测试',
    date: '2025-12-15',
    start: '09:00',
    status: 'processable',
    department: '测试部',
  },
  {
    id: 43,
    name: '安全审计',
    date: '2025-12-15',
    start: '13:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 44,
    name: '技术分享会',
    date: '2025-12-15',
    start: '15:00',
    status: 'processable',
    department: '技术部',
  },

  // 周四（16日）
  {
    id: 7,
    name: '量缸试水 1',
    date: '2025-12-16',
    start: '00:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 8,
    name: '量缸试水 1',
    date: '2025-12-16',
    start: '01:00',
    status: 'processable',
    department: '运维部',
  },
  // 8点以后的任务
  {
    id: 45,
    name: 'API集成测试',
    date: '2025-12-16',
    start: '09:30',
    status: 'processable',
    department: '测试部',
  },
  {
    id: 46,
    name: '前端部署',
    date: '2025-12-16',
    start: '14:00',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 47,
    name: 'Bug修复',
    date: '2025-12-16',
    start: '10:30',
    status: 'overdue',
    department: '技术部',
  },
  {
    id: 48,
    name: '文档编写',
    date: '2025-12-16',
    start: '16:30',
    status: 'processable',
    department: '技术部',
  },

  // 周五（17日）
  {
    id: 9,
    name: '龙飞翔量缸试水检查龙飞翔',
    date: '2025-12-17',
    start: '08:00',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 10,
    name: '龙飞翔量缸试水检查龙飞翔',
    date: '2025-12-17',
    start: '08:30',
    status: 'processable',
    department: '运维部',
  },
  // 8点以后的任务
  {
    id: 49,
    name: '周报编写',
    date: '2025-12-17',
    start: '10:00',
    status: 'processable',
    department: '技术部',
  },
  {
    id: 50,
    name: '周会',
    date: '2025-12-17',
    start: '15:00',
    status: 'processable',
    department: '综合部',
  },
  {
    id: 51,
    name: '客户反馈处理',
    date: '2025-12-17',
    start: '13:30',
    status: 'overdue',
    department: '客服部',
  },

  // 周六（18日）
  {
    id: 11,
    name: '量缸试水',
    date: '2025-12-18',
    start: '01:00',
    status: 'completed',
    department: '运维部',
  },
  {
    id: 12,
    name: '量缸试水',
    date: '2025-12-18',
    start: '01:30',
    status: 'completed',
    department: '运维部',
  },
  {
    id: 13,
    name: '量缸试水',
    date: '2025-12-18',
    start: '02:00',
    status: 'completed',
    department: '运维部',
  },
  {
    id: 14,
    name: '量缸试水',
    date: '2025-12-18',
    start: '05:00',
    status: 'overdue',
    department: '运维部',
  },
  {
    id: 15,
    name: '量缸试水',
    date: '2025-12-18',
    start: '05:30',
    status: 'overdue',
    department: '运维部',
  },
  {
    id: 16,
    name: '量缸试水',
    date: '2025-12-18',
    start: '07:00',
    status: 'completed',
    department: '运维部',
  },
  {
    id: 17,
    name: '量缸试水',
    date: '2025-12-18',
    start: '07:30',
    status: 'completed',
    department: '运维部',
  },
  {
    id: 18,
    name: '量缸试水',
    date: '2025-12-18',
    start: '08:00',
    status: 'completed',
    department: '运维部',
  },
  // 8点以后的任务
  {
    id: 52,
    name: '系统维护',
    date: '2025-12-18',
    start: '10:00',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 53,
    name: '数据备份',
    date: '2025-12-18',
    start: '12:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 54,
    name: '性能优化',
    date: '2025-12-18',
    start: '14:30',
    status: 'processable',
    department: '技术部',
  },

  // 周日（19日） - 为测试展开功能添加更多任务
  // 00:00时间段任务
  {
    id: 19,
    name: '量缸试水',
    date: '2025-12-19',
    start: '01:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 20,
    name: '量缸试水',
    date: '2025-12-19',
    start: '02:00',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 21,
    name: '量缸试水',
    date: '2025-12-19',
    start: '04:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 22,
    name: '量缸试水',
    date: '2025-12-19',
    start: '05:00',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 23,
    name: '龙飞翔量缸试水检查龙飞翔',
    date: '2025-12-19',
    start: '06:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 24,
    name: '龙飞翔量缸试水检查龙飞翔',
    date: '2025-12-19',
    start: '07:00',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 25,
    name: '龙飞翔量缸试水检查龙飞翔',
    date: '2025-12-19',
    start: '07:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 112, name: '夜间系统巡检', date: '2025-12-19', start: '00:00', status: 'processable', department: '运维部' },
  {
    id: 113, name: '数据仓库维护', date: '2025-12-19', start: '03:00', status: 'overdue', department: '技术部' },
  {
    id: 114, name: '定时任务执行', date: '2025-12-19', start: '04:00', status: 'processable', department: '技术部' },
  {
    id: 115, name: '邮件服务器维护', date: '2025-12-19', start: '06:00', status: 'processable', department: '运维部' },
  // 08:00时间段任务
  {
    id: 26,
    name: '龙飞翔量缸试水检查龙飞翔',
    date: '2025-12-19',
    start: '08:00',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 55,
    name: '应急响应',
    date: '2025-12-19',
    start: '09:00',
    status: 'overdue',
    department: '运维部',
  },
  {
    id: 56,
    name: '监控检查',
    date: '2025-12-19',
    start: '11:30',
    status: 'processable',
    department: '运维部',
  },
  {
    id: 57,
    name: '日志分析',
    date: '2025-12-19',
    start: '13:00',
    status: 'processable',
    department: '技术部',
  },
  {
    id: 116, name: '项目进度会议', date: '2025-12-19', start: '10:00', status: 'processable', department: '产品部' },
  {
    id: 117, name: '代码审查', date: '2025-12-19', start: '11:00', status: 'overdue', department: '技术部' },
  {
    id: 118, name: '团队午餐', date: '2025-12-19', start: '12:00', status: 'processable', department: '综合部' },
  {
    id: 119, name: '产品演示', date: '2025-12-19', start: '14:00', status: 'processable', department: '产品部' },
  {
    id: 120, name: 'API集成测试', date: '2025-12-19', start: '15:00', status: 'processable', department: '测试部' },
  {
    id: 121, name: '前端开发讨论', date: '2025-12-19', start: '09:30', status: 'processable', department: '技术部' },
  // 16:00时间段任务
  {
    id: 122, name: '服务器升级', date: '2025-12-19', start: '16:00', status: 'processable', department: '运维部' },
  {
    id: 123, name: '数据库优化', date: '2025-12-19', start: '17:00', status: 'overdue', department: '技术部' },
  {
    id: 124, name: '网络安全评估', date: '2025-12-19', start: '18:00', status: 'processable', department: '安全部' },
  {
    id: 125, name: '应用性能监控', date: '2025-12-19', start: '19:00', status: 'processable', department: '技术部' },
  {
    id: 126, name: '系统日志归档', date: '2025-12-19', start: '20:00', status: 'processable', department: '运维部' },
  {
    id: 127, name: '数据备份验证', date: '2025-12-19', start: '21:00', status: 'processable', department: '技术部' },
  {
    id: 128, name: '夜间批处理任务', date: '2025-12-19', start: '22:00', status: 'overdue', department: '技术部' },
  {
    id: 129, name: '紧急故障处理', date: '2025-12-19', start: '23:00', status: 'overdue', department: '运维部' },
]);

// Calculate the 7 days of the specified week
// Note: weekNumber starts from 1 (first week of year)
const weekDays = computed(() => {
  const days = [];

  // Create a date object for January 1st of the given year
  const firstDayOfYear = new Date(props.year, 0, 1);

  // Calculate the day of the week for January 1st (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
  const firstDayOfWeek = firstDayOfYear.getDay();

  // Calculate the date of the first Monday of the year
  // If Jan 1st is Monday (1), no adjustment needed
  // If Jan 1st is Sunday (0), we need to go back 6 days
  // Otherwise, we need to go back (firstDayOfWeek - 1) days
  const diffToFirstMonday = firstDayOfWeek === 0 ? -6 : 1 - firstDayOfWeek;
  const firstMonday = new Date(firstDayOfYear);
  firstMonday.setDate(firstDayOfYear.getDate() + diffToFirstMonday);

  // Calculate the date of the Monday for the specified week number
  // Note: weekNumber - 1 because we already have the first week
  const targetMonday = new Date(firstMonday);
  targetMonday.setDate(firstMonday.getDate() + (props.weekNumber - 1) * 7);

  // Generate 7 days starting from the target Monday
  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()];

    // 使用本地时间生成fullDate，避免时区偏移问题
    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);
  // 调试：打印任务数量
  console.log(`Date: ${date}, FullDate: ${dayFull}, Task count: ${list.length}`);

  // 对任务进行排序，将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 'cancelled':
    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) return slotStart;
  
  if (isExpanded(weekDays.value.find(d => d.date === date)?.fullDate, slotKey)) {
      // 如果展开，找到当前时间段最后一个任务的位置，在其下方放置按钮
      const lastTask = allTasks.filter(task => task.slotKey === slotKey).pop();
      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.filter(task => task.slotKey === slotKey).pop();
      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) 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
  };
};
</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="getTaskStatusClass(task)"
                      :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
                      }"
                      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;
}

/* Task status background colors */
.task-block.processable {
  background-color: #e6f7ff;
  border-left-color: #1890ff;
}

.task-block.overdue {
  background-color: #fff2e8;
  border-left-color: #ff7d43;
}

.task-block.completed {
  background-color: #f6ffed;
  border-left-color: #52c41a;
}

.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>
