<template>
  <el-dialog
    :visible.sync="visibleProxy"
    :show-close="false"
    width="90%"
    :close-on-click-modal="false"
    custom-class="booking-calendar-dialog"
    append-to-body
  >
    <div class="dialog-inner">
      <div class="dialog-header">
        <div class="dialog-title">
          <i class="el-icon-date"></i> 预约日历
        </div>
        <div class="view-switcher">
          <el-button-group>
            <el-button :type="currentView === 'calendar' ? 'primary' : ''" size="mini" @click="currentView = 'calendar'">
              <i class="el-icon-calendar"></i> 日历
            </el-button>
            <el-button :type="currentView === 'list' ? 'primary' : ''" size="mini" @click="currentView = 'list'">
              <i class="el-icon-s-order"></i> 列表
            </el-button>
          </el-button-group>
        </div>
        <span class="dialog-close" @click="visibleProxy = false"><i class="el-icon-close"></i></span>
      </div>

      <div class="dialog-search">
        <el-form @submit.native.prevent :inline="true" size="small">
          <el-form-item label="预约状态">
            <el-select v-model="query.status" placeholder="全部状态" clearable style="width:150px">
              <el-option label="已预约" value="booked" />
              <el-option label="服务中" value="serving" />
              <el-option label="已完成/已转耗卡" value="converted" />
              <el-option label="已取消" value="cancelled" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" @click="search">查询</el-button>
            <el-button icon="el-icon-refresh" @click="reset">重置</el-button>
          </el-form-item>
        </el-form>
      </div>

      <div class="dialog-content" v-loading="loading">
        <!-- 日历视图 -->
        <div v-show="currentView === 'calendar'" class="calendar-view">
          <FullCalendar
            ref="fullCalendar"
            class="store-calendar"
            defaultView="dayGridMonth"
            :header="calendarHeader"
            :plugins="calendarPlugins"
            :weekends="true"
            :events="calendarEvents"
            locale="zh-cn"
            :buttonText="buttonText"
            :height="calendarHeight"
            :eventLimit="true"
            allDayText="全天"
            :editable="false"
            :dayRender="onDayRender"
            @datesRender="datesRender"
            @dateClick="handleDateClick"
            @eventClick="handleEventClick"
          />
        </div>
        
        <!-- 列表视图 -->
        <div v-show="currentView === 'list'" class="list-view">
          <div class="list-view-header">
            <div class="list-header-left">
              <span class="list-date-range">{{ dateRangeText }}</span>
              <span class="list-total">共 <strong>{{ bookingList.length }}</strong> 条预约</span>
            </div>
            <div class="list-header-right">
              <el-tag size="small" type="primary" effect="plain">已预约 {{ statusCount('booked') }}</el-tag>
              <el-tag size="small" type="success" effect="plain">服务中 {{ statusCount('serving') }}</el-tag>
              <el-tag size="small" type="info" effect="plain">已完成 {{ statusCount('converted') }}</el-tag>
              <el-tag size="small" type="danger" effect="plain">已取消 {{ statusCount('cancelled') }}</el-tag>
            </div>
          </div>
          <el-table
            :data="bookingList"
            style="width: 100%"
            :row-class-name="tableRowClassName"
            @row-click="handleListRowClick"
          >
            <el-table-column label="预约时间" width="180">
              <template slot-scope="scope">
                <div class="time-cell">
                  <div class="date-text">{{ scope.row.date }}</div>
                  <div class="time-text">{{ scope.row.startTime }} - {{ scope.row.endTime }}</div>
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="memberName" label="会员姓名" width="120">
              <template slot-scope="scope">
                <div class="member-cell">
                  <div class="member-avatar">{{ (scope.row.memberName || '').charAt(0) }}</div>
                  <span>{{ scope.row.memberName }}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="roomName" label="房间" width="100" />
            <el-table-column label="状态" width="110">
              <template slot-scope="scope">
                <el-tag :type="getStatusType(scope.row.status)" size="small" effect="light">
                  {{ statusText(scope.row.status) }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="projectName" label="项目" min-width="150" show-overflow-tooltip />
            <el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip>
              <template slot-scope="scope">
                <span class="remark-text">{{ scope.row.remark || '-' }}</span>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="80" fixed="right" align="center">
              <template slot-scope="scope">
                <el-button type="primary" size="mini" link @click.stop="openBookingDetail(scope.row)">
                  详情
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </div>

    <booking-consume-dialog
      :visible.sync="consumeVisible"
      :prefill="consumePrefill"
      @saved="handleConsumeSaved"
    />
    <booking-consume-detail-dialog
      :visible.sync="detailVisible"
      :booking="selectedBooking"
      @cancel="handleDetailCancel"
      @edit="handleDetailEdit"
      @start="handleDetailStart"
      @convert="handleDetailConvert"
    />
  </el-dialog>
</template>

<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import BookingConsumeDialog from '@/components/booking-consume-dialog.vue'
import BookingConsumeDetailDialog from '@/components/booking-consume-detail-dialog.vue'
import { getYyjlList, getYyjlInfo, startYyjlService, cancelYyjl } from '@/api/lqYyjl'
import {
  mapYyjlListRow,
  mapYyjlInfoToFormRecord,
  apiStatusToUi,
  statusText as appointmentStatusText,
  uiStatusToApi,
  formatDateYMD,
  buildYysjTimestampRange
} from '@/utils/appointmentHelper'

export default {
  name: 'BookingCalendarDialog',
  components: { FullCalendar, BookingConsumeDialog, BookingConsumeDetailDialog },
  props: {
    visible: { type: Boolean, default: false },
    /** 与 dashboard 当前选中门店同步 */
    currentStoreId: { type: String, default: '' }
  },
  data() {
    return {
      loading: false,
      currentView: 'calendar',
      query: { status: undefined },
      calendarPlugins: [dayGridPlugin, timeGridPlugin, interactionPlugin],
      calendarEvents: [],
      calendarHeader: { left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay' },
      buttonText: { today: '今日', month: '月', week: '周', day: '日' },
      startTime: null,
      endTime: null,
      calendarHeight: 600,
      consumeVisible: false,
      consumePrefill: {},
      detailVisible: false,
      selectedBooking: null,
      bookingList: [],
      bookingByDate: {}
    }
  },
  computed: {
    visibleProxy: {
      get() { return this.visible },
      set(v) { this.$emit('update:visible', v) }
    },
    dateRangeText() {
      if (this.startTime && this.endTime) {
        const start = this.formatDate(this.startTime)
        const end = this.formatDate(this.endTime)
        if (start === end) return start
        return `${start} 至 ${end}`
      }
      return ''
    }
  },
  watch: {
    visible(v) {
      if (v) {
        this.setCurrentMonthRange()
        this._installBookingItemClickGuard()
        this.$nextTick(() => {
          this.calcHeight()
          this.initData()
        })
      } else {
        this._removeBookingItemClickGuard()
      }
    }
  },
  mounted() {
    window.addEventListener('resize', this.calcHeight)
    window.addEventListener('store_pc_bookings_updated', this.onBookingsUpdated)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.calcHeight)
    window.removeEventListener('store_pc_bookings_updated', this.onBookingsUpdated)
    this._removeBookingItemClickGuard()
  },
  methods: {
    storeId() {
      return this.currentStoreId || (this.$store.getters.storeInfo || {}).storeId || ''
    },
    onBookingsUpdated() {
      if (this.visibleProxy) {
        this.refreshBookingDataSync()
        this.initData()
      }
    },
    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)
    },
    statusCount(status) {
      return (this.bookingList || []).filter(r => r.status === status).length
    },
    tableRowClassName({ row }) {
      if (row.status === 'cancelled') return 'cancelled-row'
      if (row.status === 'serving') return 'serving-row'
      return ''
    },
    getStatusType(status) {
      if (status === 'booked') return 'primary'
      if (status === 'serving') return 'success'
      if (status === 'converted') return 'info'
      if (status === 'cancelled') return 'danger'
      return 'info'
    },
    statusColor(status) {
      if (status === 'booked') return '#409EFF'
      if (status === 'serving') return '#67C23A'
      if (status === 'converted') return '#909399'
      if (status === 'cancelled') return '#F56C6C'
      return '#909399'
    },
    calcHeight() {
      this.$nextTick(() => {
        const el = this.$el && this.$el.querySelector('.dialog-content')
        if (el) {
          this.calendarHeight = Math.max(el.clientHeight - 20, 500)
        }
      })
    },
    onDayRender(info) {
      const dateStr = this.formatDate(info.date)
      const frame = info.el && (info.el.querySelector('.fc-daygrid-day-frame') || info.el.querySelector('.fc-daygrid-day-events') || 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
      this.initData()
    },
    getCalendarRoot() {
      // append-to-body 时日历在 document.body，优先从 document 查找
      const fromDoc = document.querySelector('.booking-calendar-dialog .store-calendar')
      return fromDoc || (this.$el && this.$el.querySelector('.store-calendar')) || null
    },
    getVisibleMonthDate() {
      if (this.startTime && this.endTime) {
        const mid = (this.startTime.getTime() + this.endTime.getTime()) / 2
        return new Date(mid)
      }
      return new Date()
    },
    async refreshBookingDataSync() {
      const storeId = this.storeId()
      if (!storeId) {
        this.bookingList = []
        this.bookingByDate = {}
        this.calendarEvents = []
        return
      }
      try {
        let rangeStart = this.startTime
        let rangeEnd = this.endTime
        if (!rangeStart || !rangeEnd) {
          const now = new Date()
          rangeStart = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0, 0)
          rangeEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999)
        }
        const yysjRange = buildYysjTimestampRange(rangeStart, rangeEnd)
        const params = {
          djmd: storeId,
          currentPage: 1,
          pageSize: 500,
          sidx: 'yysj',
          sort: 'asc'
        }
        if (yysjRange) params.yysj = yysjRange
        const apiStatus = uiStatusToApi(this.query.status)
        if (apiStatus && this.query.status !== 'converted') {
          params.F_Status = apiStatus
        }
        const res = await getYyjlList(params)
        let list = (res.data?.list || []).map(mapYyjlListRow)
        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
          return {
            id: item.id,
            title: '',
            start,
            end,
            color: 'transparent',
            textColor: 'transparent',
            classNames: ['pc-booking-hidden-event'],
            editable: false,
            allDay: false
          }
        })
      } catch (e) {
        this.bookingList = []
        this.bookingByDate = {}
        this.calendarEvents = []
      }
    },
    async loadBookingDetail(id) {
      const res = await getYyjlInfo(id)
      const info = res.data || {}
      return mapYyjlInfoToFormRecord(info, info.lqYyjlPxList || [])
    },
    setCurrentMonthRange() {
      const now = new Date()
      const y = now.getFullYear()
      const m = now.getMonth()
      this.startTime = new Date(y, m, 1, 0, 0, 0, 0)
      this.endTime = new Date(y, m + 1, 0, 23, 59, 59, 999)
    },
    initData() {
      this.loading = true
      this.refreshBookingDataSync()
        .finally(() => {
          this.loading = false
          this.$nextTick(() => {
            this.installDayCellRenderer()
            this.patchAllCells()
            const api = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi && this.$refs.fullCalendar.getApi()
            if (api && api.rerenderDates) api.rerenderDates()
            this.$nextTick(() => this.patchAllCells())
          })
        })
    },
    _installBookingItemClickGuard() {
      this._removeBookingItemClickGuard()
      if (this._pcBookingGuardInstalled) return
      const handler = (e) => {
        if (!this.visibleProxy) return
        const target = e.target
        if (!target || typeof target.closest !== 'function') return
        const itemEl = target.closest('.pc-booking-item')
        if (!itemEl) return
        const dialog = target.closest('.booking-calendar-dialog')
        if (!dialog) 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
    },
    installDayCellRenderer() {
      const root = this.getCalendarRoot()
      if (!root) return
      if (this._pcBookingDelegationInstalled) return
      this._pcBookingDelegationInstalled = true

      // 监听 FullCalendar 月视图切换导致的 DOM 变动，及时重绘日格摘要
      this._pcBookingMutation && this._pcBookingMutation.disconnect && this._pcBookingMutation.disconnect()
      this._pcBookingMutation = new MutationObserver(() => {
        this.patchAllCells()
      })
      this._pcBookingMutation.observe(root, { childList: true, subtree: true })
    },
    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>`
    },
    patchAllCells() {
      const root = this.getCalendarRoot()
      if (!root) return
      const cells = root.querySelectorAll('.fc-daygrid-day')
      cells.forEach(cell => {
        const dateStr = cell.getAttribute('data-date')
        if (!dateStr) return
        let mount = cell.querySelector('.pc-booking-mount')
        if (!mount) {
          // 不能挂在 day-top（高度小/可能 overflow），挂到 day-frame/事件容器里更稳定
          const top = cell.querySelector('.fc-daygrid-day-frame') ||
            cell.querySelector('.fc-daygrid-day-events') ||
            cell
          mount = document.createElement('div')
          mount.className = 'pc-booking-mount'
          top.appendChild(mount)
        }
        mount.innerHTML = this.renderDayCell(dateStr)
      })
    },
    handleDateClick(arg) {
      // 若点击的是预约条目，不打开新建预约，由 capture 层只打开详情
      if (arg && arg.jsEvent && arg.jsEvent.target && arg.jsEvent.target.closest && arg.jsEvent.target.closest('.pc-booking-item')) {
        return
      }
      // 点击空白日期格：打开新建预约，预填点击的日期
      const dateStr = arg && arg.date ? this.formatDate(arg.date) : this.formatDate(new Date())
      this.consumePrefill = { date: dateStr }
      this.consumeVisible = true
    },
    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)
    },
    handleListRowClick(row) {
      this.openBookingDetail(row)
    },
    async openBookingDetail(rec) {
      try {
        const detail = await this.loadBookingDetail(rec.id)
        this.selectedBooking = detail
        this.detailVisible = true
      } catch (e) {
        this.selectedBooking = { ...rec }
        this.detailVisible = true
      }
    },
    handleConsumeSaved() {
      this.consumeVisible = false
      this.refreshBookingDataSync().then(() => this.initData())
    },
    handleDetailCancel(b) {
      if (!b || !b.id) return
      this.$confirm(`确定取消「${b.memberName || '该会员'}」在 ${b.date} ${b.startTime || ''}-${b.endTime || ''} 的预约吗？`, '取消预约确认', {
        confirmButtonText: '确定',
        cancelButtonText: '再想想',
        type: 'warning'
      }).then(async () => {
        await cancelYyjl(b.id, '')
        this.detailVisible = false
        this.selectedBooking = null
        await this.refreshBookingDataSync()
        this.initData()
        this.$message.success('已取消预约')
      }).catch(() => {})
    },
    handleDetailEdit(b) {
      if (!b) return
      this.consumePrefill = { ...b }
      this.detailVisible = false
      this.$nextTick(() => {
        this.consumeVisible = true
      })
    },
    async handleDetailStart(b) {
      if (!b || !b.id) return
      try {
        await startYyjlService(b.id)
        this.selectedBooking = { ...this.selectedBooking, status: 'serving', fStatus: '服务中' }
        await this.refreshBookingDataSync()
        this.initData()
        this.$message.success('已开始服务')
      } catch (e) {}
    },
    handleDetailConvert(b) {
      if (!b) return
      this.detailVisible = false
      this.$emit('convert-consume', {
        appointmentId: b.id,
        memberId: b.memberId,
        memberName: b.memberName
      })
    },
    search() { this.initData() },
    reset() { this.query.status = undefined; this.initData() }
  }
}
</script>

<style lang="scss">
@import '~@fullcalendar/core/main.css';
@import '~@fullcalendar/daygrid/main.css';
@import '~@fullcalendar/timegrid/main.css';

.booking-calendar-dialog .store-calendar {
  .fc-toolbar.fc-header-toolbar { padding: 16px 20px; 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: 18px; font-weight: 700; color: #1e293b; }
  .fc-button-primary { background-color: #3b82f6; border-color: #3b82f6; border-radius: 10px; font-size: 13px; font-weight: 500; height: 34px; line-height: 34px; padding: 0 14px; transition: all 0.2s; &:hover { background: #2563eb; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(59,130,246,0.3); } }
  .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-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, #2563eb); color: #fff; border-radius: 6px; box-shadow: 0 2px 8px rgba(59,130,246,0.3); } }
  .fc-event { cursor: pointer; border-radius: 6px; padding: 3px 6px; font-size: 12px; font-weight: 500; border: none; box-shadow: 0 2px 4px rgba(0,0,0,0.1); transition: all 0.2s; &:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); } }
  .fc-day-header { font-size: 14px !important; color: #64748b !important; font-weight: 700 !important; background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%) !important; border-bottom: 2px solid #e2e8f0 !important; padding: 12px 8px !important; }
  .fc-unthemed th, .fc-unthemed td { border-color: #f1f5f9; }
}

.booking-calendar-dialog .store-calendar {
  .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>

<style lang="scss" scoped>
::v-deep .booking-calendar-dialog {
  max-width: 1600px;
  margin-top: 3vh !important;
  border-radius: 20px;
  padding: 0;
  background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(0, 0, 0, 0.05);
  overflow: hidden;
}

::v-deep .el-dialog__header { display: none; }
::v-deep .el-dialog__body { padding: 0; }

.dialog-inner {
  display: flex;
  flex-direction: column;
  max-height: 90vh;
  height: 85vh;
}

.dialog-header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 16px 20px 0;
  padding: 14px 20px;
  border-radius: 12px;
  background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
  border: 1px solid rgba(59, 130, 246, 0.1);
}

.dialog-title {
  font-size: 18px;
  font-weight: 700;
  color: #1e293b;
  display: flex;
  align-items: center;
  gap: 8px;
  
  i {
    color: #3b82f6;
    font-size: 20px;
  }
}

.dialog-close {
  cursor: pointer;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  color: #64748b;
  transition: all 0.2s;
  
  &:hover {
    background: rgba(0, 0, 0, 0.08);
    color: #0f172a;
  }
}

.dialog-search {
  flex-shrink: 0;
  padding: 16px 20px 8px;
  border-bottom: 1px solid #f1f5f9;
}

.dialog-content {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  padding: 16px 20px 20px;
}

::v-deep .booking-calendar-dialog {
  .el-input__inner {
    border-radius: 8px;
    height: 32px;
    line-height: 32px;
    border-color: #e2e8f0;
    background-color: #ffffff;
    transition: all 0.2s;
    
    &:focus {
      border-color: #3b82f6;
      box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
    }
  }
  
  .el-button--primary {
    border-radius: 8px;
    background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
    border-color: #3b82f6;
    box-shadow: 0 2px 8px rgba(37, 99, 235, 0.3);
    font-weight: 500;
    
    &:hover {
      background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
      box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4);
    }
  }
  
  .el-button--default {
    border-radius: 8px;
    font-weight: 500;
  }
  
  .el-form-item {
    margin-bottom: 0;
    margin-right: 12px;
  }
  
  .el-form-item__label {
    white-space: nowrap;
    color: #475569;
    font-weight: 500;
  }
}

.view-switcher {
  flex: 1;
  display: flex;
  justify-content: center;
  
  .el-button-group {
    .el-button {
      border-radius: 6px;
      font-size: 13px;
      font-weight: 500;
      padding: 8px 16px;
      transition: all 0.2s;
      
      &:first-child {
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
      }
      
      &:last-child {
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
      }
      
      i {
        margin-right: 4px;
      }
    }
  }
}

.calendar-view, .list-view {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.list-view {
  padding: 0;
  
  .list-view-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 16px;
    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
    border-radius: 10px;
    margin-bottom: 12px;
    flex-shrink: 0;
    border: 1px solid #e2e8f0;
    
    .list-header-left {
      display: flex;
      align-items: center;
      gap: 16px;
      
      .list-date-range {
        font-size: 15px;
        font-weight: 600;
        color: #1e293b;
      }
      
      .list-total {
        font-size: 13px;
        color: #64748b;
        
        strong {
          color: #3b82f6;
          font-weight: 600;
        }
      }
    }
    
    .list-header-right {
      display: flex;
      gap: 8px;
    }
  }
  
  .el-table {
    flex: 1;
    overflow: auto;
    border-radius: 8px;
    border: 1px solid #e2e8f0;
    
    &::before {
      display: none;
    }
    
    th {
      background: #f8fafc !important;
      color: #475569;
      font-weight: 600;
      font-size: 13px;
      border-bottom: 1px solid #e2e8f0;
    }
    
    td {
      padding: 10px 0;
      border-bottom: 1px solid #f1f5f9;
      font-size: 13px;
    }
    
    tr:hover > td {
      background: #f8fafc !important;
    }
  }
  
  .cancelled-row {
    opacity: 0.6;
    
    &:hover {
      opacity: 0.8;
    }
  }
  
  .serving-row {
    background: rgba(34, 197, 94, 0.04);
  }
  
  .time-cell {
    .date-text {
      font-size: 13px;
      color: #1e293b;
      font-weight: 500;
    }
    
    .time-text {
      font-size: 12px;
      color: #64748b;
      margin-top: 2px;
    }
  }
  
  .member-cell {
    display: flex;
    align-items: center;
    gap: 8px;
    
    .member-avatar {
      width: 28px;
      height: 28px;
      border-radius: 50%;
      background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
      color: white;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 12px;
      font-weight: 600;
      flex-shrink: 0;
    }
    
    span {
      color: #1e293b;
      font-weight: 500;
    }
  }
  
  .remark-text {
    color: #94a3b8;
    font-size: 12px;
  }
}
</style>
