<template>
  <div class="appointment-calendar-container">
    <div class="NCC-common-layout-center" style="flex: 1; display: flex; flex-direction: column; min-height: 0;">
      <!-- 搜索条件区域 -->
      <div class="filter-section">
        <el-card class="filter-card" shadow="hover">
          <div class="filter-content">
            <el-form ref="queryForm" :model="query" @submit.native.prevent class="filter-form">
              <div class="filter-item">
                <label class="filter-label">单据门店：</label>
                <el-form-item prop="djmd" :rules="[{ required: true, message: '请选择单据门店', trigger: 'change' }]" style="margin: 0;">
                  <el-select v-model="query.djmd" placeholder="请选择单据门店" style="width: 300px">
                    <el-option v-for="(item, index) in djmdOptions" :key="index" :label="item.fullName" :value="item.id" />
                  </el-select>
                </el-form-item>
              </div>
              <div class="filter-item">
                <label class="filter-label">沟通人：</label>
                <userSelect v-model="query.yyr" placeholder="请选择沟通人" style="width: 300px" />
              </div>
              <div class="filter-item">
                <label class="filter-label">预约状态：</label>
                <el-select v-model="query.status" placeholder="预约状态" clearable style="width: 200px">
                  <el-option label="已预约" value="booked" />
                  <el-option label="服务中" value="serving" />
                  <el-option label="已完成/已转耗卡" value="converted" />
                  <el-option label="已取消" value="cancelled" />
                </el-select>
              </div>
              <div class="filter-item">
                <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
                <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button>
              </div>
            </el-form>
          </div>
        </el-card>
      </div>

      <!-- 日历视图区域 -->
      <div class="calendar-section">
        <el-card shadow="hover" class="calendar-card">
          <div class="calendar-wrapper" v-loading="listLoading">
            <FullCalendar
              class="demo-app-calendar"
              ref="fullCalendar"
              defaultView="dayGridMonth"
              :header="{
                left: 'prev,next today',
                center: 'title',
                right: 'dayGridMonth,timeGridWeek,timeGridDay'
              }"
              :plugins="calendarPlugins"
              :weekends="calendarWeekends"
              :events="calendarEvents"
              locale="zh-cn"
              :buttonText="buttonText"
              :height="calendarHeight"
              :eventLimit="true"
              allDayText="全天"
              :editable="false"
              :dayRender="onDayRender"
              @datesRender="datesRender"
              @dateClick="handleDateClick"
              @eventClick="handleEventClick"
            />
          </div>
        </el-card>
      </div>
    </div>

    <appointment-detail-dialog
      :visible.sync="detailVisible"
      :booking-id="selectedBookingId"
      :fallback-booking="selectedBookingFallback"
      :store-options="djmdOptions"
    />
  </div>
</template>

<script>
import request from '@/utils/request'
import { previewDataInterface } from '@/api/systemData/dataInterface'
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import bootstrapPlugin from '@fullcalendar/bootstrap'
import AppointmentDetailDialog from './appointment-detail-dialog.vue'
import {
  mapYyjlListRow,
  apiStatusToUi,
  uiStatusToApi,
  statusText as appointmentStatusText,
  buildYysjTimestampRange
} from '@/utils/appointmentHelper'

export default {
  name: 'lqYyjlCalendar',
  components: {
    FullCalendar,
    AppointmentDetailDialog
  },
  data() {
    return {
      listLoading: false,
      query: {
        djmd: undefined,
        yyr: undefined,
        status: undefined
      },
      djmdOptions: [],
      calendarPlugins: [
        dayGridPlugin,
        timeGridPlugin,
        bootstrapPlugin,
        interactionPlugin
      ],
      calendarWeekends: true,
      calendarEvents: [],
      bookingList: [],
      bookingByDate: {},
      buttonText: {
        today: '今日',
        month: '月',
        week: '周',
        day: '日'
      },
      startTime: null,
      endTime: null,
      calendarHeight: 'auto',
      detailVisible: false,
      selectedBookingId: '',
      selectedBookingFallback: null,
      _pcBookingGuardInstalled: false,
      _pcBookingGuardHandler: null,
      _pcBookingGuardTarget: null,
      _loadingCalendarData: false,
      _patchingCells: false
    }
  },
  mounted() {
    this.calculateCalendarHeight()
    window.addEventListener('resize', this.calculateCalendarHeight)
    this._installBookingItemClickGuard()
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.calculateCalendarHeight)
    this._removeBookingItemClickGuard()
  },
  created() {
    if (this.$route.query.employeeId) {
      this.query.yyr = this.$route.query.employeeId
    }
    if (this.$route.query.storeId) {
      this.query.djmd = this.$route.query.storeId
    }
    if (this.$route.query.type) {
      this.query.status = apiStatusToUi(this.$route.query.type)
    }
    this.getdjmdOptions()
  },
  methods: {
    calculateCalendarHeight() {
      this.$nextTick(() => {
        const wrapper = this.$el && this.$el.querySelector('.calendar-wrapper')
        if (wrapper) {
          const height = wrapper.clientHeight - 40
          this.calendarHeight = Math.max(height, 600)
        } else {
          this.calendarHeight = 700
        }
      })
    },
    async getdjmdOptions() {
      await previewDataInterface('730960205902251269').then(res => {
        this.djmdOptions = res.data
      })
    },
    esc(s) {
      return String(s == null ? '' : s)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
    },
    formatDate(d) {
      const dt = d instanceof Date ? d : new Date(d)
      const y = dt.getFullYear()
      const m = String(dt.getMonth() + 1).padStart(2, '0')
      const day = String(dt.getDate()).padStart(2, '0')
      return `${y}-${m}-${day}`
    },
    statusText(status) {
      return appointmentStatusText(status)
    },
    statusColor(status) {
      if (status === 'booked') return '#409EFF'
      if (status === 'serving') return '#67C23A'
      if (status === 'converted') return '#909399'
      if (status === 'cancelled') return '#F56C6C'
      return '#909399'
    },
    onDayRender(info) {
      const dateStr = this.formatDate(info.date)
      const frame = this.getDayCellMountParent(info.el) || info.el
      if (!frame) return
      let mount = frame.querySelector('.pc-booking-mount')
      if (!mount) {
        mount = document.createElement('div')
        mount.className = 'pc-booking-mount'
        frame.appendChild(mount)
      }
      mount.innerHTML = this.renderDayCell(dateStr)
    },
    datesRender(info) {
      const view = info.view
      this.startTime = view.activeStart
      this.endTime = view.activeEnd
      if (this.query.djmd) {
        this.initData(false)
      }
    },
    getDayCells(root) {
      if (!root) return []
      const v5Cells = root.querySelectorAll('.fc-daygrid-day[data-date]')
      if (v5Cells.length) return Array.from(v5Cells)
      const v4Cells = root.querySelectorAll('td.fc-day[data-date]')
      return Array.from(v4Cells)
    },
    getDayCellMountParent(cell) {
      if (!cell) return null
      return cell.querySelector('.fc-daygrid-day-frame') ||
        cell.querySelector('.fc-daygrid-day-events') ||
        cell.querySelector('.fc-day-grid') ||
        cell.querySelector('.fc-content-skeleton') ||
        cell
    },
    ensureCalendarRange() {
      if (this.startTime && this.endTime) return
      const api = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi && this.$refs.fullCalendar.getApi()
      if (api && api.view) {
        this.startTime = api.view.activeStart
        this.endTime = api.view.activeEnd
      }
    },
    async refreshBookingDataSync() {
      if (!this.query.djmd) {
        this.bookingList = []
        this.bookingByDate = {}
        this.calendarEvents = []
        return
      }
      this.ensureCalendarRange()
      try {
        const rangeStart = this.startTime || new Date()
        const rangeEnd = this.endTime || new Date()
        const yysjRange = buildYysjTimestampRange(rangeStart, rangeEnd)
        const params = {
          djmd: this.query.djmd,
          currentPage: 1,
          pageSize: 1000,
          sidx: 'yysj',
          sort: 'asc'
        }
        if (yysjRange) params.yysj = yysjRange
        if (this.query.yyr) params.yyr = this.query.yyr
        const apiStatus = uiStatusToApi(this.query.status)
        if (apiStatus && this.query.status !== 'converted') {
          params.F_Status = apiStatus
        }
        const res = await request({
          url: '/api/Extend/LqYyjl',
          method: 'GET',
          data: params
        })
        const rawList = (res.data && (res.data.list || res.data.List)) || []
        let list = rawList.map(mapYyjlListRow).filter(r => r && r.date)
        if (this.query.status === 'converted') {
          list = list.filter(r => r.status === 'converted')
        } else if (this.query.status) {
          list = list.filter(r => r.status === this.query.status)
        }
        this.bookingList = list
        const map = {}
        list.forEach(r => {
          const key = r && r.date ? r.date : ''
          if (!key) return
          if (!map[key]) map[key] = []
          map[key].push(r)
        })
        Object.keys(map).forEach(k => {
          map[k] = map[k].slice().sort((a, b) => String(a.startTime || '').localeCompare(String(b.startTime || '')))
        })
        this.bookingByDate = map
        this.calendarEvents = list.map(item => {
          const dateStr = item.date || this.formatDate(new Date())
          const start = item.startTime ? `${dateStr}T${item.startTime}:00` : `${dateStr}T00:00:00`
          const end = item.endTime ? `${dateStr}T${item.endTime}:00` : start
          const title = [item.startTime, item.memberName, item.roomName].filter(Boolean).join(' ')
          return {
            id: item.id,
            title: title || '预约',
            start,
            end,
            color: this.statusColor(item.status),
            textColor: '#fff',
            className: 'admin-booking-event',
            editable: false,
            allDay: false,
            extendedProps: { ...item }
          }
        })
      } catch (e) {
        this.bookingList = []
        this.bookingByDate = {}
        this.calendarEvents = []
      }
    },
    initData(force) {
      if (this._loadingCalendarData && !force) return
      this.ensureCalendarRange()
      this._loadingCalendarData = true
      this.listLoading = true
      this.refreshBookingDataSync()
        .finally(() => {
          this._loadingCalendarData = false
          this.listLoading = false
          this.$nextTick(() => {
            this.patchAllCells()
          })
        })
    },
    _installBookingItemClickGuard() {
      this._removeBookingItemClickGuard()
      if (this._pcBookingGuardInstalled) return
      const handler = (e) => {
        const target = e.target
        if (!target || typeof target.closest !== 'function') return
        const itemEl = target.closest('.pc-booking-item')
        if (!itemEl) return
        const container = target.closest('.appointment-calendar-container')
        if (!container) return
        e.preventDefault()
        e.stopPropagation()
        const id = itemEl.getAttribute('data-id')
        const rec = (this.bookingList || []).find(x => x && x.id === id)
        if (rec) {
          this.openBookingDetail(rec)
        }
      }
      document.addEventListener('click', handler, true)
      this._pcBookingGuardHandler = handler
      this._pcBookingGuardTarget = document
      this._pcBookingGuardInstalled = true
    },
    _removeBookingItemClickGuard() {
      if (this._pcBookingGuardTarget && this._pcBookingGuardHandler) {
        this._pcBookingGuardTarget.removeEventListener('click', this._pcBookingGuardHandler, true)
        this._pcBookingGuardTarget = null
        this._pcBookingGuardHandler = null
      }
      this._pcBookingGuardInstalled = false
    },
    patchAllCells() {
      if (this._patchingCells) return
      const root = this.getCalendarRoot()
      if (!root) return
      this._patchingCells = true
      try {
        this.getDayCells(root).forEach(cell => {
          const dateStr = cell.getAttribute('data-date')
          if (!dateStr) return
          let mount = cell.querySelector('.pc-booking-mount')
          const top = this.getDayCellMountParent(cell) || cell
          if (!mount) {
            mount = document.createElement('div')
            mount.className = 'pc-booking-mount'
            top.appendChild(mount)
          }
          const html = this.renderDayCell(dateStr)
          if (mount.innerHTML !== html) {
            mount.innerHTML = html
          }
        })
      } finally {
        this._patchingCells = false
      }
    },
    renderDayCell(dateStr) {
      const list = (this.bookingByDate && this.bookingByDate[dateStr]) ? this.bookingByDate[dateStr] : []
      const total = list.length
      if (!total) return ''

      const maxShow = 2
      const showList = list.slice(0, maxShow)
      const rest = total - showList.length
      const itemsHtml = showList.map(r => {
        const time = `${this.esc(r.startTime || '')}-${this.esc(r.endTime || '')}`.replace(/^-|-$/g, '')
        const member = this.esc(r.memberName || '无')
        const room = this.esc(r.roomName || '无')
        const stText = this.esc(this.statusText(r.status))
        const stColor = this.statusColor(r.status)
        const brief = [time, member, room, stText].filter(Boolean).join(' ')
        return `<div class="pc-booking-item" data-id="${this.esc(r.id)}">
          <span class="pc-booking-dot" style="background:${stColor}"></span>
          <span class="pc-booking-brief" title="${brief}">${brief}</span>
        </div>`
      }).join('')

      const moreHtml = rest > 0 ? `<div class="pc-booking-more">+${rest}</div>` : ''
      return `<div class="pc-booking-wrap">
        <div class="pc-booking-badge">${total}</div>
        <div class="pc-booking-list">${itemsHtml}${moreHtml}</div>
      </div>`
    },
    getCalendarRoot() {
      return (this.$el && this.$el.querySelector('.demo-app-calendar')) || null
    },
    handleDateClick(arg) {
      if (arg && arg.jsEvent && arg.jsEvent.target && arg.jsEvent.target.closest && arg.jsEvent.target.closest('.pc-booking-item')) {
        return
      }
      const clickDate = arg && arg.date ? this.formatDate(arg.date) : this.formatDate(new Date())
      this.$router.push({
        path: '/lqYyjl',
        query: {
          startTime: new Date(clickDate + ' 00:00:00').getTime(),
          endTime: new Date(clickDate + ' 23:59:59').getTime(),
          storeId: this.query.djmd || undefined
        }
      })
    },
    handleEventClick(arg) {
      const id = arg && arg.event ? arg.event.id : ''
      if (!id) return
      const rec = (this.bookingList || []).find(x => x && x.id === id)
      if (rec) {
        this.openBookingDetail(rec)
        return
      }
      const props = arg && arg.event && arg.event.extendedProps
      if (props && props.id) {
        this.openBookingDetail(props)
      }
    },
    openBookingDetail(rec) {
      this.selectedBookingId = rec.id
      this.selectedBookingFallback = { ...rec }
      this.detailVisible = true
    },
    search() {
      this.$refs.queryForm.validate((valid) => {
        if (valid) {
          this.initData(true)
        } else {
          this.$message.warning('请选择单据门店')
        }
      })
    },
    reset() {
      const routeYyr = this.$route.query.employeeId
      const routeStore = this.$route.query.storeId
      this.query = {
        djmd: routeStore || undefined,
        yyr: routeYyr || undefined,
        status: undefined
      }
      this.$nextTick(() => {
        if (this.$refs.queryForm) {
          this.$refs.queryForm.clearValidate()
        }
        if (this.query.djmd) {
          this.initData()
        } else {
          this.bookingList = []
          this.bookingByDate = {}
          this.calendarEvents = []
          this.patchAllCells()
        }
      })
    },
    refresh() {
      this.search()
    }
  }
}
</script>

<style lang="scss">
// FullCalendar 样式导入
@import '~@fullcalendar/core/main.css';
@import '~@fullcalendar/daygrid/main.css';
@import '~@fullcalendar/timegrid/main.css';
@import '~@fullcalendar/bootstrap/main.css';
</style>

<style lang="scss" scoped>
.appointment-calendar-container {
  padding: 24px;
  background: linear-gradient(135deg, #f8fafc 0%, #e8f3ff 100%);
  min-height: calc(100vh - 84px);
  height: 100%;
  position: relative;
  display: flex;
  flex-direction: column;

  &::before {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    width: 500px;
    height: 500px;
    background: radial-gradient(circle, rgba(59, 130, 246, 0.08) 0%, transparent 70%);
    pointer-events: none;
    z-index: 0;
  }

  > * {
    position: relative;
    z-index: 1;
  }

  .filter-section {
    margin-bottom: 24px;

    .filter-card {
      border-radius: 16px;
      border: 1px solid rgba(226, 232, 240, 0.8);
      background: rgba(255, 255, 255, 0.9);
      backdrop-filter: blur(12px);
      box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
      transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

      &:hover {
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
        transform: translateY(-2px);
      }

      ::v-deep .el-card__body {
        padding: 24px;
      }

      .filter-content {
        .filter-form {
          display: flex;
          align-items: center;
          gap: 20px;
          flex-wrap: wrap;

          .filter-item {
            display: flex;
            align-items: center;

            .filter-label {
              font-size: 14px;
              font-weight: 600;
              color: #1e293b;
              margin-right: 12px;
              white-space: nowrap;
              letter-spacing: -0.01em;
            }

            ::v-deep .el-select {
              .el-input__inner {
                border-radius: 10px;
                border: 1.5px solid #e2e8f0;
                transition: all 0.3s;

                &:hover {
                  border-color: #3b82f6;
                }

                &:focus {
                  border-color: #3b82f6;
                  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
                }
              }
            }

            .el-button {
              border-radius: 10px;
              font-weight: 500;
              transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

              &:hover {
                transform: translateY(-2px);
                box-shadow: 0 8px 16px rgba(59, 130, 246, 0.3);
              }
            }
          }
        }
      }
    }
  }

  .calendar-section {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;

    .calendar-card {
      flex: 1;
      display: flex;
      flex-direction: column;
      border-radius: 16px;
      border: 1px solid rgba(226, 232, 240, 0.8);
      background: rgba(255, 255, 255, 0.95);
      backdrop-filter: blur(16px);
      box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
      overflow: hidden;

      ::v-deep .el-card__body {
        padding: 0;
        flex: 1;
        display: flex;
        flex-direction: column;
        min-height: 0;
      }

      .calendar-wrapper {
        flex: 1;
        padding: 20px;
        background: #fff;
        min-height: 0;
        position: relative;
        display: flex;
        flex-direction: column;
      }
    }
  }
}
</style>

<style lang="scss">
.demo-app-calendar {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;

  .fc-view-container {
    flex: 1;
    min-height: 0;
  }

  .fc-toolbar.fc-header-toolbar {
    padding: 24px 28px;
    margin-bottom: 0;
    border-bottom: 2px solid #f1f5f9;
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.02) 0%, rgba(96, 165, 250, 0.02) 100%);
  }

  .fc-toolbar-title {
    font-size: 20px;
    font-weight: 700;
    color: #1e293b;
    letter-spacing: -0.02em;
    background: linear-gradient(135deg, #1e293b 0%, #3b82f6 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }

  .fc-button-primary {
    background-color: #3b82f6;
    border-color: #3b82f6;
    height: 36px;
    line-height: 36px;
    padding: 0 16px;
    font-size: 13px;
    font-weight: 500;
    border-radius: 10px;
    border: 1.5px solid #e2e8f0;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

    &:hover {
      border-color: #3b82f6;
      background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, rgba(96, 165, 250, 0.05) 100%);
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
    }

    &:active {
      transform: translateY(0);
    }
  }

  .fc-button-primary:not(:disabled):active,
  .fc-button-primary:not(:disabled).fc-button-active {
    background-color: #2563eb;
    border-color: #2563eb;
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
  }

  .fc-button .fc-icon {
    line-height: 16px;
  }

  .fc-unthemed th,
  .fc-daygrid-header th,
  .fc-daygrid-header .fc-col-header-cell {
    height: 70px !important;
    min-height: 70px !important;
    line-height: 70px !important;
    font-size: 14px !important;
    color: #64748b !important;
    font-weight: 700 !important;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%) !important;
    border-bottom: 2px solid #e2e8f0 !important;
    padding: 16px 8px !important;
    vertical-align: middle !important;
    box-sizing: border-box !important;
  }

  .fc-daygrid-header .fc-col-header-cell-cushion {
    height: 70px !important;
    line-height: 70px !important;
    padding: 0 !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    font-size: 14px !important;
    font-weight: 700 !important;
  }

  .fc-daygrid-header .fc-col-header {
    height: 70px !important;
  }

  .fc-daygrid-header .fc-col-header tr {
    height: 70px !important;
  }

  .fc-center {
    color: #1e293b;
  }

  .fc-unthemed th,
  .fc-unthemed td,
  .fc-unthemed thead,
  .fc-unthemed tbody,
  .fc-unthemed .fc-divider,
  .fc-unthemed .fc-row,
  .fc-unthemed .fc-content,
  .fc-unthemed .fc-popover,
  .fc-unthemed .fc-list-view,
  .fc-unthemed .fc-list-heading td {
    border-color: #f1f5f9;
    color: #1e293b;
  }

  .fc-daygrid-day {
    min-height: 120px;
    height: auto;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    padding: 8px;

    &:hover {
      background: linear-gradient(135deg, rgba(59, 130, 246, 0.04) 0%, rgba(96, 165, 250, 0.04) 100%);
    }

    .fc-daygrid-day-frame {
      min-height: 100px;
    }

    .fc-daygrid-day-top {
      padding: 4px 0;
    }

    .fc-daygrid-day-number {
      font-size: 14px;
      font-weight: 600;
      padding: 4px 8px;
    }

    .fc-daygrid-day-events {
      margin-top: 6px;
      min-height: 20px;
    }
  }

  .fc-day-today {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, rgba(96, 165, 250, 0.05) 100%);

    .fc-daygrid-day-number {
      background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
      color: #fff;
      border-radius: 6px;
      box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
    }
  }

  .fc-event {
    cursor: pointer;
    border-radius: 6px;
    padding: 4px 8px;
    font-size: 12px;
    font-weight: 500;
    border: none;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
      z-index: 10;
    }
  }

  .fc-timeGridWeek-view,
  .fc-timeGridDay-view {
    .fc-time-grid {
      min-height: 600px;
    }

    .fc-time-slot {
      min-height: 40px;
    }

    .fc-event {
      font-size: 12px;
      padding: 4px 8px;
      margin: 2px 4px;
      line-height: 1.4;
      border-radius: 6px;
    }
  }

  .fc-more-popover {
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
    border: 1px solid rgba(226, 232, 240, 0.8);

    .fc-event-container {
      max-height: 400px !important;
      overflow-y: auto !important;
    }
  }

  .fc-scroller {
    overflow-y: auto !important;
    overflow-x: hidden !important;
  }

  .fc-day-header {
    font-size: 14px !important;
    color: #64748b !important;
    font-weight: 700 !important;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%) !important;
    border-bottom: 2px solid #e2e8f0 !important;
    padding: 15px 8px !important;
    vertical-align: middle !important;
    box-sizing: border-box !important;
  }

  /* FullCalendar v4 月视图：日格摘要为主，隐藏重复 fc-event */
  .fc-month-view .fc-event.admin-booking-event {
    display: none !important;
  }

  td.fc-day {
    min-height: 120px;
    vertical-align: top;
    position: relative;
  }

  .pc-booking-hidden-event {
    display: none !important;
  }

  .pc-booking-mount {
    position: relative;
    margin: 4px 6px 0 4px;
    pointer-events: auto;
    z-index: 2;
  }

  .pc-booking-wrap {
    position: relative;
  }

  .pc-booking-badge {
    position: absolute;
    top: -2px;
    right: 6px;
    min-width: 16px;
    height: 16px;
    line-height: 16px;
    padding: 0 5px;
    border-radius: 999px;
    background: rgba(37, 99, 235, 0.12);
    color: #2563eb;
    font-size: 11px;
    font-weight: 700;
    text-align: center;
  }

  .pc-booking-list {
    margin-top: 18px;
  }

  .pc-booking-item {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 2px 0;
    padding: 2px 6px;
    border-radius: 8px;
    background: rgba(241, 245, 249, 0.55);
    cursor: pointer;
    user-select: none;
    transition: background 0.15s;

    &:hover {
      background: rgba(219, 234, 254, 0.8);
    }
  }

  .pc-booking-dot {
    width: 6px;
    height: 6px;
    border-radius: 999px;
    flex-shrink: 0;
  }

  .pc-booking-brief {
    font-size: 11px;
    color: #334155;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 16px;
    max-width: 140px;
  }

  .pc-booking-more {
    font-size: 11px;
    color: #64748b;
    padding: 0 6px;
    margin-top: 2px;
    white-space: nowrap;
  }
}
</style>
