<template>
  <div class="admin-calendar">
    <!-- 顶部操作区 -->
    <div class="admin-header">
      <el-button type="success" icon="el-icon-plus" @click="openCreateModal('add')">新建日历事件</el-button>
    </div>
    <!-- 日历预览区 -->
    <div class="admin-main">
      <div class="calendar-panel">
        <div class="calendar-wrapper">
        <el-calendar v-model="calendarDate" :first-day-of-week="7">
          <template slot="dateCell" slot-scope="{date}">
            <div class="cell-content">
                <span class="date-number">{{ date.getDate() }}</span>
                <div class="event-list">
                  <div 
                    v-for="ev in eventsForDate(date)" 
                    :key="ev._id" 
                    :class="['event-item', getEventClass(ev, date)]"
                    :style="getEventInlineStyle(ev)"
                    :title="getEventTooltip(ev, date)"
                    @click.stop="openCreateModal('editor', ev.id)"
                  >
                    <span class="event-title">{{ ev.title }}</span>
                  </div>
                </div>
              </div>
            </template>
          </el-calendar>
          <!-- 连续事件覆盖层 -->
          <div class="continuous-events-overlay">
            <div 
              v-for="event in getContinuousEvents()" 
              :key="`continuous-${event.id}-${event.weekStartISO}-${event.startCol}`"
              :class="['continuous-event', `event-type-${event.type || 'default'}`]"
              :style="getContinuousEventStyle(event)"
              :title="getEventTooltip(event, new Date(event.segStartISO))"
              @click.stop="openCreateModal('editor', event.id)"
            >
              {{ event.title }}
            </div>
              </div>
        </div>
      </div>
    </div>
    <addCalendar ref="addCalendar" @refresh="getList"></addCalendar>
  </div>
</template>

<script>

import addCalendar from './components/addCalendar.vue'
  import {
    index
} from '@/api/calendars/index.js'
  export default {
  components: {
      addCalendar
    },
    data() {
      return {
      list: [],
      calendarDate: new Date()
      }
    },
    computed: {
    selectMonth() {
      const now = this.calendarDate instanceof Date ? this.calendarDate : new Date(this.calendarDate)
      const month = now.getMonth() + 1 < 10 ? '0' + (now.getMonth() + 1) : now.getMonth() + 1
      const year = now.getFullYear()
      return year + '-' + month
      }
    },
    watch: {
    calendarDate: {
      handler() {
        this.getList()
      },
      deep: true
    }
    },
    created() {
      this.getList()
    },
    methods: {
    async getList() {
        const res = await index({
        month: this.selectMonth
        })
        this.list = res
      },
    openCreateModal(type, id) {
      if (type === 'editor') {
          this.$refs.addCalendar.id = id
        }
        this.$refs.addCalendar.type = type
        this.$refs.addCalendar.isShow = true
      },

    eventsForDate(date) {
      const d = new Date(date)
      return this.list.filter(ev => {
        const startDate = this.parseDateTime(ev.start_time)
        
        // 如果没有end_time，只在start_time的日期显示
        if (!ev.end_time) {
          const currentDate = new Date(d.getFullYear(), d.getMonth(), d.getDate())
          const eventStartDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate())
          return currentDate.getTime() === eventStartDate.getTime()
        }
        
        const endDate = this.parseDateTime(ev.end_time)
        
        // 判断是否是跨天事件
        const isMultiDay = startDate.getDate() !== endDate.getDate() || 
                          startDate.getMonth() !== endDate.getMonth() || 
                          startDate.getFullYear() !== endDate.getFullYear()
        
        // 跨天事件不在单元格中显示，只在覆盖层显示
        if (isMultiDay) {
          return false
        }
        
        // 单天事件正常显示
        const currentDate = new Date(d.getFullYear(), d.getMonth(), d.getDate())
        const eventStartDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate())
        return currentDate.getTime() === eventStartDate.getTime()
      })
    },
    getEventClass(event, date) {
      const startDate = new Date(event.start_time)
      const currentDate = new Date(date)
      
      // 如果没有end_time，直接返回单天事件样式
      if (!event.end_time) {
        return `single-day event-type-${event.type || 'default'}`
      }
      
      const endDate = new Date(event.end_time)
      
      // 判断是否是跨天事件
      const isMultiDay = startDate.getDate() !== endDate.getDate() || 
                        startDate.getMonth() !== endDate.getMonth() || 
                        startDate.getFullYear() !== endDate.getFullYear()
      
      if (!isMultiDay) {
        return `single-day event-type-${event.type || 'default'}`
      }
      
      // 判断当前日期在跨天事件中的位置
      const eventStartDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate())
      const eventEndDate = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate())
      const currentDateOnly = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate())
      
      if (currentDateOnly.getTime() === eventStartDate.getTime()) {
        return `multi-day-start event-type-${event.type || 'default'}`
      } else if (currentDateOnly.getTime() === eventEndDate.getTime()) {
        return `multi-day-end event-type-${event.type || 'default'}`
      } else {
        return `multi-day-middle event-type-${event.type || 'default'}`
      }
    },
    getEventTooltip(event, date) {
      const startDate = new Date(event.start_time)
      
      // 如果没有end_time，只显示事件标题和开始时间
      if (!event.end_time) {
        return `${event.title}\n时间：${this.formatDateTime(event.start_time)}`
      }
      
      const endDate = new Date(event.end_time)
      
      const isMultiDay = startDate.getDate() !== endDate.getDate() || 
                        startDate.getMonth() !== endDate.getMonth() || 
                        startDate.getFullYear() !== endDate.getFullYear()
      
      if (isMultiDay) {
        return `${event.title}\n时间：${this.formatDateTime(event.start_time)} ~ ${this.formatDateTime(event.end_time)}`
        } else {
        return `${event.title}\n时间：${this.formatDateTime(event.start_time)} ~ ${this.formatDateTime(event.end_time)}`
      }
    },
    getEventInlineStyle(event) {
      // 单天事件或在格子中显示的事件，若有自定义颜色则覆盖背景
      if (event) {
        const custom = event.color
        if (custom) {
          try { console.log('[Calendar] Single-day color applied:', event.id || event._id, custom) } catch (e) {}
          return { background: custom }
        }
        // 无自定义颜色时，显式使用类型默认色，避免出现无背景的情况
        const fallback = this.getEventTypeColor(event.type)
        return { background: fallback }
      }
      return {}
    },
    getContinuousEvents() {
      const FIRST_DOW = 0 // 0=Sunday to match :first-day-of-week="7" on el-calendar
      const continuousEvents = []

      // 仅选择跨天事件
      const multiDayEvents = this.list.filter(ev => {
        if (!ev.end_time) return false
        const s = this.parseDateTime(ev.start_time)
        const e = this.parseDateTime(ev.end_time)
        return s.toDateString() !== e.toDateString()
      })

      const currentMonth = this.calendarDate.getMonth()
      const currentYear = this.calendarDate.getFullYear()
      const monthStart = new Date(currentYear, currentMonth, 1)
      const monthEnd = new Date(currentYear, currentMonth + 1, 0)

      function getWeekStart(date) {
        const d = new Date(date)
        const jsDow = d.getDay() // 0..6 (Sun..Sat)
        const offset = (jsDow - FIRST_DOW + 7) % 7
        d.setDate(d.getDate() - offset)
        return d
      }

      multiDayEvents.forEach(ev => {
        const eventStart = this.parseDateTime(ev.start_time)
        const eventEnd = this.parseDateTime(ev.end_time)

        if (eventEnd < monthStart || eventStart > monthEnd) return

        // Clamp to month range so we only render in current month viewport
        const clampedStart = eventStart < monthStart ? monthStart : eventStart
        const clampedEnd = eventEnd > monthEnd ? monthEnd : eventEnd

        let cursor = getWeekStart(clampedStart)
        while (cursor <= clampedEnd) {
          const weekStart = new Date(cursor)
          const weekEnd = new Date(cursor)
          weekEnd.setDate(weekEnd.getDate() + 6)

          // Segment inside this week
          const segStart = clampedStart > weekStart ? clampedStart : weekStart
          const segEnd = clampedEnd < weekEnd ? clampedEnd : weekEnd
          if (segStart <= segEnd) {
            const startCol = (segStart.getDay() - FIRST_DOW + 7) % 7
            const endCol = (segEnd.getDay() - FIRST_DOW + 7) % 7
            const spanCols = endCol - startCol + 1
            continuousEvents.push({
              ...ev,
              weekStartISO: weekStart.toISOString(),
              segStartISO: segStart.toISOString(),
              segEndISO: segEnd.toISOString(),
              startCol,
              spanCols,
              endCol
            })
          }
          cursor.setDate(cursor.getDate() + 7)
        }
      })

      // 为同一周的分段分配“轨道”（lane），避免垂直重叠
      const byWeek = {}
      continuousEvents.forEach(seg => {
        const key = seg.weekStartISO
        if (!byWeek[key]) byWeek[key] = []
        byWeek[key].push(seg)
      })

      Object.values(byWeek).forEach(segs => {
        // 按开始列排序，开始相同则优先更长的，减少冲突
        segs.sort((a, b) => (a.startCol - b.startCol) || (b.spanCols - a.spanCols))
        const laneEndCols = [] // 每个轨道当前占据的最后列
        segs.forEach(seg => {
          let placed = false
          for (let i = 0; i < laneEndCols.length; i += 1) {
            if (laneEndCols[i] < seg.startCol) {
              seg.laneIndex = i
              laneEndCols[i] = seg.endCol
              placed = true
              break
            }
          }
          if (!placed) {
            seg.laneIndex = laneEndCols.length
            laneEndCols.push(seg.endCol)
          }
        })
      })

      return continuousEvents
    },
    getContinuousEventStyle(event) {
      const FIRST_DOW = 0
      const currentMonth = this.calendarDate.getMonth()
      const currentYear = this.calendarDate.getFullYear()
      const firstDay = new Date(currentYear, currentMonth, 1)

      // 使用实际分段起点，不做额外周偏移
      const segStart = new Date(event.segStartISO)

      const msPerDay = 1000 * 60 * 60 * 24
      const daysFromFirstOfMonth = Math.floor((segStart - firstDay) / msPerDay)
      const firstDayOffset = (firstDay.getDay() - FIRST_DOW + 7) % 7
      const totalDaysFromCalendarStart = daysFromFirstOfMonth + firstDayOffset
      const weekRow = Math.floor(totalDaysFromCalendarStart / 7)

      // 起始列使用预计算的列（相对于该周）
      const startColAdjusted = event.startCol

      const cellWidth = 100 / 7
      const cellHeight = 100
      const headerHeight = 0
      const cellPadding = 6 // td 与内部容器的总上内边距（约值）
      const dateNumberHeight = 25
      const eventHeight = 16
      const eventSpacing = 2
      const verticalOffset = (event.laneIndex || 0) * (eventHeight + eventSpacing)

      const custom = event.color || event.bg_color || event.background
      if (custom) { try { console.log('[Calendar] Continuous color applied:', event.id, custom) } catch (e) {} }
      return {
        position: 'absolute',
        left: `calc(${startColAdjusted * cellWidth}% + 2px)`,
        top: `${headerHeight + weekRow * cellHeight + cellPadding + dateNumberHeight + verticalOffset}px`,
        width: `calc(${event.spanCols * cellWidth}% - 4px)`,
        height: `${eventHeight}px`,
        zIndex: 1000,
        background: custom ? custom : `linear-gradient(90deg, ${this.getEventTypeColor(event.type)} 0%, ${this.darkenColor(this.getEventTypeColor(event.type))} 100%)`,
        backgroundColor: custom ? custom : undefined,
        borderRadius: '3px',
        fontSize: '11px',
        lineHeight: `${eventHeight}px`,
        color: 'white',
        padding: '0 4px',
        whiteSpace: 'nowrap',
        overflow: 'hidden',
        textOverflow: 'ellipsis',
        cursor: 'pointer',
        boxShadow: '0 1px 3px rgba(0, 0, 0, 0.3)'
      }
    },
    getEventStyle(event, date) {
      const startDate = new Date(event.start_time)
      const currentDate = new Date(date)
      
      // 如果没有end_time，使用默认样式
      if (!event.end_time) {
        return {}
      }
      
      const endDate = new Date(event.end_time)
      
      // 判断是否是跨天事件
      const isMultiDay = startDate.getDate() !== endDate.getDate() || 
                        startDate.getMonth() !== endDate.getMonth() || 
                        startDate.getFullYear() !== endDate.getFullYear()
      
      if (!isMultiDay) {
        return {}
      }
      
      // 获取当前周的开始日期（周日）
      const currentWeekStart = new Date(currentDate)
      const dayOfWeek = currentDate.getDay()
      currentWeekStart.setDate(currentDate.getDate() - dayOfWeek)
      
      // 计算事件在当前周的开始和结束位置
      const eventStartDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate())
      const eventEndDate = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate())
      const currentDateOnly = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate())
      
      // 计算当前周内事件的开始和结束天数
      const weekStart = new Date(currentWeekStart)
      const weekEnd = new Date(currentWeekStart)
      weekEnd.setDate(weekEnd.getDate() + 6)
      
      // 事件在当前周的实际开始和结束日期
      const eventWeekStart = eventStartDate < weekStart ? weekStart : eventStartDate
      const eventWeekEnd = eventEndDate > weekEnd ? weekEnd : eventEndDate
      
      // 如果当前日期不在事件范围内，不应用特殊样式
      if (currentDateOnly < eventWeekStart || currentDateOnly > eventWeekEnd) {
        return {}
      }
      
      // 如果是事件在当前周的第一天，显示标题并延伸到周末尾或事件结束
      if (currentDateOnly.getTime() === eventWeekStart.getTime()) {
        const startDayOfWeek = eventWeekStart.getDay()
        const endDayOfWeek = eventWeekEnd.getDay()
        const spanDays = endDayOfWeek - startDayOfWeek + 1
        
        // 根据事件类型设置背景色
        const bgColor = this.getEventTypeColor(event.type)
        
        return {
          position: 'absolute',
          left: '0',
          top: '1px',
          width: `calc(${spanDays * 100}% - 2px)`,
          zIndex: 10,
          background: `linear-gradient(90deg, ${bgColor} 0%, ${this.darkenColor(bgColor)} 100%)`,
          boxShadow: '0 1px 3px rgba(0, 0, 0, 0.2)',
          border: '1px solid rgba(255, 255, 255, 0.3)',
          borderRadius: '3px'
        }
      } else if (currentDateOnly > eventWeekStart && currentDateOnly <= eventWeekEnd) {
        // 其他天完全隐藏内容，保留占位
        return {
          opacity: '0',
          pointerEvents: 'none'
        }
      }
      
      return {}
    },
    getEventDisplayTitle(event, date) {
      const startDate = new Date(event.start_time)
      const currentDate = new Date(date)
      
      // 如果没有end_time，显示完整标题
      if (!event.end_time) {
        return event.title
      }
      
      const endDate = new Date(event.end_time)
      
      // 判断是否是跨天事件
      const isMultiDay = startDate.getDate() !== endDate.getDate() || 
                        startDate.getMonth() !== endDate.getMonth() || 
                        startDate.getFullYear() !== endDate.getFullYear()
      
      if (!isMultiDay) {
        return event.title
      }
      
      // 对于跨天事件，只在开始日期显示标题
      const eventStartDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate())
      const currentDateOnly = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate())
      
      // 获取当前周的开始日期
      const currentWeekStart = new Date(currentDate)
      const dayOfWeek = currentDate.getDay()
      currentWeekStart.setDate(currentDate.getDate() - dayOfWeek)
      
      const weekStart = new Date(currentWeekStart)
      const eventWeekStart = eventStartDate < weekStart ? weekStart : eventStartDate
      
      if (currentDateOnly.getTime() === eventWeekStart.getTime()) {
        return event.title
      }
      
      return '' // 其他日期不显示标题
    },
    getEventTypeColor(type) {
      // 根据事件类型返回不同颜色
      const colorMap = {
        1: '#67C23A', // 课程 - 绿色
        2: '#409EFF', // 会议 - 蓝色
        3: '#E6A23C', // 自定义事件 - 橙色
        4: '#F56C6C', // 资讯 - 红色
        5: '#909399', // 其他 - 灰色
        default: '#409EFF' // 默认蓝色
      }
      return colorMap[type] || colorMap.default
    },
    // 可靠的日期解析：避免 Safari/时区导致的偏移
    parseDateTime(dateTimeStr) {
      if (!dateTimeStr) return null
      // 支持 "YYYY-MM-DD HH:mm:ss" 或 "YYYY-MM-DD" 形式
      const [datePart, timePart = '00:00:00'] = dateTimeStr.trim().split(/\s+/)
      const [y, m, d] = datePart.split('-').map(n => parseInt(n, 10))
      const [hh = 0, mm = 0, ss = 0] = timePart.split(':').map(n => parseInt(n, 10))
      return new Date(y, (m || 1) - 1, d || 1, hh || 0, mm || 0, ss || 0)
    },
    darkenColor(color) {
      // 将颜色变暗，用于渐变效果
      const colorMap = {
        '#67C23A': '#5CB85C', // 绿色变暗
        '#409EFF': '#337ecc', // 蓝色变暗
        '#E6A23C': '#D4952B', // 橙色变暗
        '#F56C6C': '#E85555', // 红色变暗
        '#909399': '#73767A'  // 灰色变暗
      }
      return colorMap[color] || '#337ecc'
    },
    formatDateTime(val) {
      if (!val) return ''
      return val.replace('T', ' ')
      },
      typeText(className) {
      if (!className) return ''
      if (className === 1) return '课程'
      if (className === 3) return '自定义事件'
      if (className === 4) return '资讯'
      return ''
      }
    },
    filters: {
      formatDateTime(val) {
      if (!val) return ''
      return val.replace('T', ' ')
      }
    }
  }
</script>

<style scoped lang="scss">
  ::v-deep .el-calendar__body{
    padding-left:0;
    padding-right:0;
  }
  .admin-calendar {
    background: #f4f6fa;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
  }

  .admin-header {
    background: transparent;
    padding: 20rpx 30rpx 10rpx 30rpx;
    border-bottom: none;
    box-shadow: none;
  }

  .admin-main {
    flex: 1;
    padding: 20rpx 30rpx;
    overflow: hidden;
  }

  .calendar-panel {
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
    padding: 24rpx;
    height: 100%;
    overflow: auto;
  }

  .calendar-wrapper {
    position: relative;
  }

  .continuous-events-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    pointer-events: none;
    z-index: 100;
  }

  .continuous-event {
    pointer-events: auto;
    transition: all 0.2s ease;
  }

  .continuous-event:hover {
    transform: translateY(-1rpx);
    filter: brightness(1.1);
    z-index: 101;
  }

  /* Element UI 日历样式覆盖 */
  .calendar-panel ::v-deep .el-calendar-table {
    overflow: visible;
  }

  .calendar-panel ::v-deep .el-calendar-table .el-calendar-day {
    position: relative;
    overflow: visible;
    height: auto;
    min-height: 100rpx;
    padding: 4rpx;
  }

  .calendar-panel ::v-deep .el-calendar-table td {
    position: relative;
    overflow: visible;
    border: 1rpx solid #ebeef5;
  }

  .calendar-panel ::v-deep .el-calendar-table tbody tr {
    overflow: visible;
  }

  .calendar-panel ::v-deep .el-calendar-table tbody {
    overflow: visible;
  }

  .cell-content {
    position: relative;
    min-height: 100rpx;
    display: flex;
    flex-direction: column;
    padding: 2rpx;
    overflow: visible;
  }

  .date-number {
    font-weight: bold;
    color: #333;
    margin-bottom: 2rpx;
    position: relative;
    z-index: 1;
  }

  .event-list {
    flex: 1;
    overflow: visible;
    position: relative;
    z-index: 5;
  }

  .event-item {
    font-size: 11rpx;
    line-height: 14rpx;
    padding: 1rpx 3rpx;
    margin: 1rpx 0;
    background: #409EFF;
    color: white;
    border-radius: 3px;
    cursor: pointer;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    transition: background-color 0.2s;
    position: relative;
  }

  .event-title {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .event-item:hover {
    background: #337ecc;
  }

  /* 不同事件类型的颜色 */
  .event-item.event-type-1 {
    background: #67C23A; /* 课程 - 绿色 */
  }

  .event-item.event-type-2 {
    background: #409EFF; /* 会议 - 蓝色 */
  }

  .event-item.event-type-3 {
    background: #E6A23C; /* 自定义事件 - 橙色 */
  }

  .event-item.event-type-4 {
    background: #F56C6C; /* 资讯 - 红色 */
  }

  .event-item.event-type-5 {
    background: #909399; /* 其他 - 灰色 */
  }

  .event-item.event-type-default {
    background: #409EFF; /* 默认 - 蓝色 */
  }

  /* 悬停效果 */
  .event-item.event-type-1:hover {
    background: #5CB85C;
  }

  .event-item.event-type-2:hover {
    background: #337ecc;
  }

  .event-item.event-type-3:hover {
    background: #D4952B;
  }

  .event-item.event-type-4:hover {
    background: #E85555;
  }

  .event-item.event-type-5:hover {
    background: #73767A;
  }

  .event-item.event-type-default:hover {
    background: #337ecc;
  }

  /* 连续事件的特殊样式 */
  .event-item[style*="position: absolute"] {
    border-radius: 3px !important;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .event-item[style*="position: absolute"]:hover {
    transform: translateY(-1rpx);
    filter: brightness(1.1);
  }

  .mt-4 {
    margin-top: 24rpx;
  }

  .mb-2 {
    margin-bottom: 8rpx;
  }

  @media (max-width: 1200px) {
    .admin-header {
      padding: 15rpx 20rpx;
    }
    
    .admin-main {
      padding: 15rpx 20rpx;
    }
    
    .calendar-panel {
      padding: 16rpx;
    }
  }
</style>
