<script lang="ts" setup>
/**
 * 日程日历面板（Apple 风格卡片，可复用组件）
 * 使用方：
 * - 日程日历页 /dashboard/calendar/index：完整模式（图例 + 大标题 + 每格 3 条待办）
 * - 工作台 work_calendar widget：compact 紧凑模式（隐藏图例、格子变矮、每格 2 条待办）
 * 布局：左侧月历主区 + 右侧「选中日」详情侧栏（大日期数字/农历干支/宜忌/当日待办清单）
 * - 点击任意格子即选中该日，侧栏联动展示当日黄历与待办
 * - 右键格子弹出快捷菜单：新建待办 / 查看当日待办（定位到侧栏）
 * - 待办支持站内信/邮箱/短信定时提醒（后端 calendar:todo-remind 每分钟扫描发送）
 */
import type { Dayjs } from 'dayjs';

import { computed, onMounted, onUnmounted, reactive, ref, watch } from 'vue';

import { useVbenModal } from '@vben/common-ui';
import { IconifyIcon as VbenIcon } from '@vben/icons';

import { Button, Calendar, Checkbox, message, Modal as AntModal, Spin, Tooltip } from 'ant-design-vue';
import dayjs from 'dayjs';
import { Solar } from 'lunar-typescript';

import { deleteCalendarTodo, getCalendarTodoList, toggleCalendarTodoDone } from '../api';
import { getDayAlmanac, getDayAlmanacDetail } from '../utils/almanac';
import TodoModalComp from './todo-modal.vue';

defineOptions({ name: 'CalendarPanel' });

interface Props {
  /** 紧凑模式：工作台 widget 用，隐藏图例、格子变矮、每格待办条数减少 */
  compact?: boolean;
}
const props = withDefaults(defineProps<Props>(), { compact: false });

/** 每格露出的待办条数：紧凑模式空间小只露 2 条，超出走「还有N项」 */
const maxChips = computed(() => (props.compact ? 2 : 3));

/** 日历面板当前值：既是展示月份也是选中日期（antd Calendar 点击格子会更新它） */
const panelDate = ref<Dayjs>(dayjs());
const loading = ref(false);
/** 待办按日期分组：key = YYYY-MM-DD */
const todosMap = ref<Map<string, any[]>>(new Map());

/** 待办新建/编辑弹窗 */
const [TodoFormModal, todoModalApi] = useVbenModal({
  connectedComponent: TodoModalComp,
});

/** 头部标题：月份大数字 + 公历年 + 农历干支生肖年 */
const headerTitle = computed(() => {
  const d = panelDate.value;
  const lunar = Solar.fromYmd(d.year(), d.month() + 1, 1).getLunar();
  return {
    month: d.format('M'),
    year: d.format('YYYY年'),
    lunar: `农历${lunar.getYearInGanZhi()}${lunar.getYearShengXiao()}年`,
  };
});

/**
 * 拉取面板范围内的待办并按日期分组
 * 范围取当月前后各留一段：日历 42 格会露出上月末尾与下月开头，宽松范围一次覆盖
 */
async function loadTodos() {
  loading.value = true;
  try {
    const start = panelDate.value.startOf('month').subtract(7, 'day').startOf('day');
    const end = panelDate.value.endOf('month').add(14, 'day').endOf('day');
    const list = await getCalendarTodoList({
      start_time: start.unix(),
      end_time: end.unix(),
    });
    const map = new Map<string, any[]>();
    (list || []).forEach((todo: any) => {
      const key = dayjs.unix(Number(todo.todo_time)).format('YYYY-MM-DD');
      if (!map.has(key)) map.set(key, []);
      map.get(key)!.push(todo);
    });
    todosMap.value = map;
  } finally {
    loading.value = false;
  }
}

// 月份变化时重拉（同月内点选日期不触发，避免无谓请求）
watch(() => panelDate.value.format('YYYY-MM'), loadTodos, { immediate: true });

/** 组装单个格子的渲染数据：黄历信息 + 当日待办 + 今日/选中/周末状态 */
function cellData(current: Dayjs) {
  return {
    almanac: getDayAlmanac(current.year(), current.month() + 1, current.date()),
    todos: todosMap.value.get(current.format('YYYY-MM-DD')) || [],
    isToday: current.isSame(dayjs(), 'day'),
    isSelected: current.isSame(panelDate.value, 'day'),
    isWeekend: current.day() === 0 || current.day() === 6,
  };
}

/** 格子内待办时间点文案：00:00 视为全天不显示时间 */
function todoTimeText(todo: any) {
  const t = dayjs.unix(Number(todo.todo_time));
  return t.format('HH:mm') === '00:00' ? '' : t.format('HH:mm');
}

// ---------------- 侧栏（选中日详情） ----------------
/** 选中日期 key，侧栏与格子高亮共用 */
const selectedKey = computed(() => panelDate.value.format('YYYY-MM-DD'));
/** 选中日是否今天：决定侧栏是否显示「回今天」入口 */
const isSelectedToday = computed(() => panelDate.value.isSame(dayjs(), 'day'));
/** 选中日黄历详情（星期/农历/干支/宜忌） */
const selectedDetail = computed(() =>
  getDayAlmanacDetail(panelDate.value.year(), panelDate.value.month() + 1, panelDate.value.date()),
);
/** 选中日格子级黄历（节日/节气/休班），侧栏标签行复用 */
const selectedAlmanac = computed(() =>
  getDayAlmanac(panelDate.value.year(), panelDate.value.month() + 1, panelDate.value.date()),
);
/** 选中日待办列表：按时间点升序，全天（00:00）自然排最前 */
const selectedTodos = computed(() => {
  const list = todosMap.value.get(selectedKey.value) || [];
  return [...list].sort((a, b) => Number(a.todo_time) - Number(b.todo_time));
});
/** 选中日未完成待办数，侧栏标题角标用 */
const selectedUndoneCount = computed(
  () => selectedTodos.value.filter((t) => Number(t.is_done) !== 1).length,
);

/** 侧栏待办时间文案：全天/HH:mm */
function sideTimeText(todo: any) {
  const t = dayjs.unix(Number(todo.todo_time));
  return t.format('HH:mm') === '00:00' ? '全天' : t.format('HH:mm');
}

/** 侧栏勾选切换完成状态：本地同步字段，避免整月重拉造成闪烁 */
async function onToggleDone(todo: any, checked: boolean) {
  await toggleCalendarTodoDone({ id: todo.id, is_done: checked ? 1 : 0 });
  todo.is_done = checked ? 1 : 0;
}

/** 侧栏删除待办：确认后删除并重拉当月 */
function onDeleteTodo(todo: any) {
  AntModal.confirm({
    title: '删除待办',
    content: `确定删除「${todo.title}」吗？`,
    okText: '删除',
    okType: 'danger',
    cancelText: '取消',
    onOk: async () => {
      await deleteCalendarTodo({ id: todo.id });
      message.success('删除成功');
      loadTodos();
    },
  });
}

// ---------------- 右键菜单 ----------------
/** 右键菜单状态：位置 + 目标日期 */
const ctxMenu = reactive({ visible: false, x: 0, y: 0, date: '' });

/** 打开右键菜单：贴边时向内收，避免菜单溢出视口 */
function openCtxMenu(e: MouseEvent, current: Dayjs) {
  ctxMenu.date = current.format('YYYY-MM-DD');
  ctxMenu.x = Math.min(e.clientX, window.innerWidth - 180);
  ctxMenu.y = Math.min(e.clientY, window.innerHeight - 120);
  ctxMenu.visible = true;
}

function closeCtxMenu() {
  ctxMenu.visible = false;
}

/** 右键菜单目标日期的待办数量 */
const ctxTodoCount = computed(() => (todosMap.value.get(ctxMenu.date) || []).length);

/** 点击任意处 / 滚动时关闭右键菜单与年月选择面板 */
function closeFloatLayers() {
  closeCtxMenu();
  closePicker();
}

onMounted(() => {
  window.addEventListener('click', closeFloatLayers);
  window.addEventListener('scroll', closeFloatLayers, true);
});
onUnmounted(() => {
  window.removeEventListener('click', closeFloatLayers);
  window.removeEventListener('scroll', closeFloatLayers, true);
});

// ---------------- 待办操作 ----------------
/** 新建待办：date 为默认日期（右键格子/侧栏/头部按钮带入，默认选中日） */
function createTodo(date?: string) {
  closeCtxMenu();
  todoModalApi
    .setData({
      update: false,
      defaultDate: date || selectedKey.value,
      onSaved: loadTodos,
    })
    .open();
}

/** 编辑待办 */
function editTodo(todo: any) {
  closeCtxMenu();
  todoModalApi.setData({ update: true, values: todo, onSaved: loadTodos }).open();
}

/** 选中某天：侧栏联动展示当日详情（右键「查看当日待办」与格子「还有N项」都走这里） */
function selectDay(date: string) {
  closeCtxMenu();
  panelDate.value = dayjs(date);
}

// ---------------- 月份切换 ----------------
function prevMonth() {
  panelDate.value = panelDate.value.subtract(1, 'month');
}
function nextMonth() {
  panelDate.value = panelDate.value.add(1, 'month');
}
function backToday() {
  panelDate.value = dayjs();
}

// ---------------- 年/月快捷选择面板 ----------------
/**
 * 点击头部大月份数字弹「月份网格」（面板内可左右切年）、点击年份文字弹「年份网格」（12 年一页）
 * viewYear：月面板顶部展示/翻页用的年，选中月份前改它不影响 panelDate
 * yearBase：年面板当前页起始年（以选中年居中：-5 ~ +6）
 */
const picker = reactive({ mode: '' as '' | 'month' | 'year', viewYear: 0, yearBase: 0 });

/** 年面板当前页的 12 个年份 */
const yearList = computed(() =>
  Array.from({ length: 12 }, (_, i) => picker.yearBase + i),
);

/** 打开/收起选择面板（重复点击同一入口则收起） */
function togglePicker(mode: 'month' | 'year') {
  closeCtxMenu();
  if (picker.mode === mode) {
    picker.mode = '';
    return;
  }
  picker.mode = mode;
  picker.viewYear = panelDate.value.year();
  picker.yearBase = panelDate.value.year() - 5;
}

function closePicker() {
  picker.mode = '';
}

/**
 * 切换年月的统一入口：先落到目标月 1 号再夹取原选中日，
 * 避免 dayjs 直接 set month 时因目标月天数不足产生进位（如 1/31 → 2 月变 3 月）
 */
function setYearMonth(year: number, monthIndex: number) {
  const first = dayjs(new Date(year, monthIndex, 1));
  const day = Math.min(panelDate.value.date(), first.daysInMonth());
  panelDate.value = first.date(day);
}

/** 月面板选中某月（用面板顶部当前展示的 viewYear） */
function pickMonth(month: number) {
  setYearMonth(picker.viewYear, month - 1);
  closePicker();
}

/** 年面板选中某年（保持当前月） */
function pickYear(year: number) {
  setYearMonth(year, panelDate.value.month());
  closePicker();
}
</script>
<template>
  <div class="work-calendar" :class="{ 'is-compact': compact }">
    <!-- 左侧：月历主区 -->
    <div class="wc-main">
      <!-- 自定义头部：月份大数字 + 图例 + 月份切换 + 新建 -->
      <div class="wc-header">
        <div class="wc-header-left">
          <!-- 点大月份数字选月份，点年份文字选年份 -->
          <div
            class="wc-month-hero wc-pick-trigger"
            title="点击选择月份"
            @click.stop="togglePicker('month')"
          >
            <span class="wc-month-num">{{ headerTitle.month }}</span>
            <span class="wc-month-unit">月</span>
            <VbenIcon class="wc-caret" icon="lucide:chevron-down" />
          </div>
          <div class="wc-title-meta">
            <span
              class="wc-title-year wc-pick-trigger"
              title="点击选择年份"
              @click.stop="togglePicker('year')"
            >
              {{ headerTitle.year }}
              <VbenIcon class="wc-caret wc-caret-sm" icon="lucide:chevron-down" />
            </span>
            <span class="wc-lunar-year">{{ headerTitle.lunar }}</span>
          </div>

          <!-- 年/月选择面板：毛玻璃浮层，选中即跳转对应月历 -->
          <div v-if="picker.mode" class="wc-picker" @click.stop>
            <template v-if="picker.mode === 'month'">
              <div class="wc-picker-head">
                <span class="wc-picker-title">{{ picker.viewYear }}年</span>
                <div class="wc-picker-nav">
                  <button class="wc-picker-nav-btn" title="上一年" @click="picker.viewYear--">
                    <VbenIcon icon="lucide:chevron-left" />
                  </button>
                  <button class="wc-picker-nav-btn" title="下一年" @click="picker.viewYear++">
                    <VbenIcon icon="lucide:chevron-right" />
                  </button>
                </div>
              </div>
              <div class="wc-picker-grid">
                <button
                  v-for="m in 12"
                  :key="m"
                  class="wc-picker-cell"
                  :class="{
                    active: picker.viewYear === panelDate.year() && m === panelDate.month() + 1,
                    now: picker.viewYear === new Date().getFullYear() && m === new Date().getMonth() + 1,
                  }"
                  @click="pickMonth(m)"
                >
                  {{ m }}月
                </button>
              </div>
            </template>
            <template v-else>
              <div class="wc-picker-head">
                <span class="wc-picker-title">{{ yearList[0] }} - {{ yearList[11] }}</span>
                <div class="wc-picker-nav">
                  <button class="wc-picker-nav-btn" title="前 12 年" @click="picker.yearBase -= 12">
                    <VbenIcon icon="lucide:chevron-left" />
                  </button>
                  <button class="wc-picker-nav-btn" title="后 12 年" @click="picker.yearBase += 12">
                    <VbenIcon icon="lucide:chevron-right" />
                  </button>
                </div>
              </div>
              <div class="wc-picker-grid">
                <button
                  v-for="y in yearList"
                  :key="y"
                  class="wc-picker-cell"
                  :class="{ active: y === panelDate.year(), now: y === new Date().getFullYear() }"
                  @click="pickYear(y)"
                >
                  {{ y }}
                </button>
              </div>
            </template>
          </div>
        </div>
        <div class="wc-header-right">
          <!-- 紧凑模式隐藏图例，把空间留给日历本体 -->
          <div v-if="!compact" class="wc-legend">
            <span class="wc-legend-item"><i class="dot traditional"></i>传统节日</span>
            <span class="wc-legend-item"><i class="dot modern"></i>公历节日</span>
            <span class="wc-legend-item"><i class="dot jieqi"></i>节气</span>
            <span class="wc-legend-item"><i class="badge rest">休</i>法定假</span>
            <span class="wc-legend-item"><i class="badge work">班</i>补班</span>
          </div>
          <div class="wc-nav">
            <button class="wc-nav-btn" title="上一月" @click="prevMonth">
              <VbenIcon icon="lucide:chevron-left" />
            </button>
            <button class="wc-nav-today" @click="backToday">今天</button>
            <button class="wc-nav-btn" title="下一月" @click="nextMonth">
              <VbenIcon icon="lucide:chevron-right" />
            </button>
          </div>
          <Button type="primary" @click="createTodo()">
            <span class="wc-btn-inner"><VbenIcon icon="lucide:plus" />新建待办</span>
          </Button>
        </div>
      </div>
      <div class="wc-body">
        <Spin :spinning="loading">
          <Calendar v-model:value="panelDate" :fullscreen="true">
            <!-- 隐藏 antd 默认头部，统一用上方自定义头部 -->
            <template #headerRender><span></span></template>
            <template #dateFullCellRender="{ current }">
              <div
                class="cal-cell"
                :class="{
                  'is-today': cellData(current).isToday,
                  'is-selected': cellData(current).isSelected,
                  'is-weekend': cellData(current).isWeekend,
                }"
                @contextmenu.prevent="openCtxMenu($event, current)"
              >
                <div class="cal-cell-head">
                  <span class="cal-day">{{ current.date() }}</span>
                  <!-- 农历始终显示，不被节日/节气覆盖 -->
                  <span class="cal-lunar">{{ cellData(current).almanac.lunarText }}</span>
                  <span
                    v-if="cellData(current).almanac.holiday"
                    class="cal-badge"
                    :class="cellData(current).almanac.holiday!.isWork ? 'work' : 'rest'"
                  >
                    {{ cellData(current).almanac.holiday!.isWork ? '班' : '休' }}
                  </span>
                  <button
                    class="cal-add"
                    title="新建待办"
                    @click.stop="createTodo(current.format('YYYY-MM-DD'))"
                  >
                    <VbenIcon icon="lucide:plus" />
                  </button>
                </div>
                <!-- 节气/节日副行：节气青色，传统节日红、公历节日橙（颜色差异化） -->
                <div
                  v-if="cellData(current).almanac.jieQi || cellData(current).almanac.festivalItems.length > 0"
                  class="cal-subline"
                >
                  <span v-if="cellData(current).almanac.jieQi" class="cal-jieqi">
                    {{ cellData(current).almanac.jieQi }}
                  </span>
                  <Tooltip
                    v-if="cellData(current).almanac.festivalItems.length > 0"
                    :title="cellData(current).almanac.festivalItems.map((f) => f.name).join('、')"
                  >
                    <span class="cal-festival" :class="cellData(current).almanac.festivalItems[0]!.kind">
                      {{ cellData(current).almanac.festivalItems[0]!.name }}
                    </span>
                  </Tooltip>
                </div>
                <div class="cal-todos">
                  <div
                    v-for="todo in cellData(current).todos.slice(0, maxChips)"
                    :key="todo.id"
                    class="cal-todo"
                    :class="{ done: Number(todo.is_done) === 1 }"
                    @click.stop="editTodo(todo)"
                  >
                    <i class="cal-todo-dot"></i>
                    <span class="cal-todo-text">
                      <template v-if="todoTimeText(todo)">{{ todoTimeText(todo) }} </template>{{ todo.title }}
                    </span>
                  </div>
                  <div
                    v-if="cellData(current).todos.length > maxChips"
                    class="cal-more"
                    @click.stop="selectDay(current.format('YYYY-MM-DD'))"
                  >
                    还有 {{ cellData(current).todos.length - maxChips }} 项…
                  </div>
                </div>
              </div>
            </template>
          </Calendar>
        </Spin>
      </div>
    </div>
    <!-- 右侧：选中日详情侧栏（万年历式「今日」卡片 + 当日待办清单） -->
    <aside class="wc-side">
      <div class="wc-side-hero">
        <div class="wc-side-date">
          <span class="wc-side-day">{{ panelDate.date() }}</span>
          <div class="wc-side-date-meta">
            <span class="wc-side-ym">{{ panelDate.format('YYYY年M月') }}</span>
            <span class="wc-side-week">{{ selectedDetail.week }}</span>
          </div>
          <button v-if="!isSelectedToday" class="wc-back-today" @click="backToday">
            <VbenIcon icon="lucide:undo-2" />回今天
          </button>
          <span v-else class="wc-today-flag">今天</span>
        </div>
        <div class="wc-side-lunar">
          <span class="wc-side-lunar-main">农历{{ selectedDetail.lunarDate }}</span>
          <span class="wc-side-lunar-ganzhi">
            {{ selectedDetail.ganZhi }} · 属{{ selectedDetail.shengXiao }}
          </span>
        </div>
        <div
          v-if="
            selectedAlmanac.festivalItems.length > 0 ||
            selectedAlmanac.jieQi ||
            selectedAlmanac.holiday
          "
          class="wc-side-tags"
        >
          <span v-if="selectedAlmanac.holiday" class="wc-tag" :class="selectedAlmanac.holiday.isWork ? 'work' : 'rest'">
            {{ selectedAlmanac.holiday.isWork ? '班' : '休' }} · {{ selectedAlmanac.holiday.name }}
          </span>
          <span v-if="selectedAlmanac.jieQi" class="wc-tag jieqi">{{ selectedAlmanac.jieQi }}</span>
          <!-- 节日标签跟随节日类型配色：传统红 / 公历橙 -->
          <span
            v-for="f in selectedAlmanac.festivalItems.slice(0, 3)"
            :key="f.name"
            class="wc-tag"
            :class="f.kind"
          >
            {{ f.name }}
          </span>
        </div>
      </div>
      <!-- 宜忌：C 端万年历的氛围信息，民俗参考 -->
      <div class="wc-yiji">
        <div v-if="selectedDetail.yi.length > 0" class="wc-yiji-row">
          <i class="wc-yiji-mark yi">宜</i>
          <span class="wc-yiji-text">{{ selectedDetail.yi.slice(0, 6).join('　') }}</span>
        </div>
        <div v-if="selectedDetail.ji.length > 0" class="wc-yiji-row">
          <i class="wc-yiji-mark ji">忌</i>
          <span class="wc-yiji-text">{{ selectedDetail.ji.slice(0, 6).join('　') }}</span>
        </div>
      </div>
      <!-- 当日待办清单 -->
      <div class="wc-side-todos">
        <div class="wc-side-todos-head">
          <span class="wc-side-todos-title">
            待办事项
            <em v-if="selectedUndoneCount > 0" class="wc-side-todos-count">{{ selectedUndoneCount }}</em>
          </span>
          <button class="wc-mini-add" @click="createTodo(selectedKey)">
            <VbenIcon icon="lucide:plus" />添加
          </button>
        </div>
        <div class="wc-side-todo-list">
          <div
            v-for="todo in selectedTodos"
            :key="todo.id"
            class="side-todo"
            :class="{ done: Number(todo.is_done) === 1 }"
          >
            <Checkbox
              class="side-todo-check"
              :checked="Number(todo.is_done) === 1"
              @change="(e: any) => onToggleDone(todo, e.target.checked)"
            />
            <div class="side-todo-main" @click="editTodo(todo)">
              <div class="side-todo-title">{{ todo.title }}</div>
              <div class="side-todo-meta">
                <span class="side-todo-time">
                  <VbenIcon icon="lucide:clock" />{{ sideTimeText(todo) }}
                </span>
                <span v-if="Number(todo.remind_at) > 0" class="side-todo-remind">
                  <VbenIcon icon="lucide:bell" />{{ dayjs.unix(Number(todo.remind_at)).format('MM-DD HH:mm') }}
                </span>
                <span v-if="Number(todo.remind_status) === 2" class="side-todo-remind-fail">提醒失败</span>
              </div>
            </div>
            <button class="side-todo-del" title="删除" @click.stop="onDeleteTodo(todo)">
              <VbenIcon icon="lucide:trash-2" />
            </button>
          </div>
          <div v-if="selectedTodos.length === 0" class="wc-side-empty">
            <VbenIcon icon="lucide:calendar-plus" class="wc-side-empty-icon" />
            <p class="wc-side-empty-text">这一天暂无待办</p>
            <button class="wc-side-empty-btn" @click="createTodo(selectedKey)">新建一条</button>
          </div>
        </div>
      </div>
    </aside>
    <!-- 右键菜单：Teleport 到 body 避免被日历容器裁剪 -->
    <Teleport to="body">
      <div
        v-if="ctxMenu.visible"
        class="wc-ctx-menu"
        :style="{ left: `${ctxMenu.x}px`, top: `${ctxMenu.y}px` }"
        @click.stop
      >
        <div class="wc-ctx-date">{{ dayjs(ctxMenu.date).format('M月D日') }}</div>
        <div class="wc-ctx-item" @click="createTodo(ctxMenu.date)">
          <span class="wc-ctx-label"><VbenIcon icon="lucide:plus" />新建待办</span>
        </div>
        <div class="wc-ctx-item" @click="selectDay(ctxMenu.date)">
          <span class="wc-ctx-label"><VbenIcon icon="lucide:list" />查看当日待办</span>
          <span v-if="ctxTodoCount > 0" class="wc-ctx-count">{{ ctxTodoCount }}</span>
        </div>
      </div>
    </Teleport>
    <TodoFormModal />
  </div>
</template>
<style lang="scss" scoped>
.work-calendar {
  display: flex;
  gap: 14px;
  align-items: stretch;
  height: 100%;
}

/* ---------- 左侧月历卡片（Apple 风格：大圆角 + 发丝线描边 + 柔和弥散阴影） ---------- */
.wc-main {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  padding: 18px;
  overflow: auto;
  background: hsl(var(--card, var(--background)));
  border: 1px solid hsl(var(--border) / 60%);
  border-radius: 18px;
  box-shadow: 0 2px 12px rgb(0 0 0 / 5%);
}

/* ---------- 头部 ---------- */
.wc-header {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 14px;
}

/* 相对定位：作为年/月选择浮层的锚点 */
.wc-header-left {
  position: relative;
  display: flex;
  gap: 10px;
  align-items: center;
}

/* 可点击的年/月触发器：hover 轻着色提示可交互（负 margin 抵消 padding 保持布局不动） */
.wc-pick-trigger {
  padding: 2px 6px;
  margin: -2px -6px;
  cursor: pointer;
  border-radius: 8px;
  transition: background-color 0.2s, color 0.2s;

  &:hover {
    background: hsl(var(--muted) / 50%);

    .wc-caret {
      color: hsl(var(--primary));
      transform: translateY(1px);
    }
  }
}

/* 年份文字触发器：行内 flex 让小箭头垂直对齐 */
.wc-title-year.wc-pick-trigger {
  display: inline-flex;
  gap: 2px;
  align-items: center;
  align-self: flex-start;
}

.wc-caret {
  align-self: center;
  margin-left: 2px;
  font-size: 14px;
  color: hsl(var(--muted-foreground));
  transition: color 0.2s, transform 0.2s;
}

.wc-caret-sm {
  font-size: 12px;
}

/* ---------- 年/月选择面板：macOS 毛玻璃浮层 ---------- */
.wc-picker {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 60;
  width: 264px;
  padding: 10px;
  background: hsl(var(--popover, var(--background)) / 88%);
  border: 1px solid hsl(var(--border) / 60%);
  border-radius: 14px;
  box-shadow: 0 12px 32px rgb(0 0 0 / 16%);
  backdrop-filter: blur(18px) saturate(160%);
}

.wc-picker-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 4px 8px;
}

.wc-picker-title {
  font-size: 13px;
  font-weight: 600;
  color: hsl(var(--foreground));
  font-variant-numeric: tabular-nums;
}

.wc-picker-nav {
  display: flex;
  gap: 2px;
  padding: 2px;
  background: hsl(var(--muted) / 60%);
  border-radius: 8px;
}

.wc-picker-nav-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 20px;
  font-size: 13px;
  color: hsl(var(--foreground) / 80%);
  cursor: pointer;
  background: transparent;
  border: none;
  border-radius: 6px;
  transition: background-color 0.2s, color 0.2s;

  &:hover {
    color: hsl(var(--foreground));
    background: hsl(var(--card, var(--background)));
    box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
  }
}

.wc-picker-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px;
}

.wc-picker-cell {
  padding: 7px 0;
  font-size: 13px;
  color: hsl(var(--foreground) / 85%);
  cursor: pointer;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
  font-variant-numeric: tabular-nums;

  &:hover {
    background: hsl(var(--muted) / 60%);
  }

  /* 今天所在的年/月：主色细描边提示（未选中时也可辨认） */
  &.now {
    border-color: hsl(var(--primary) / 45%);
  }

  /* 当前选中：主色填充 */
  &.active {
    font-weight: 600;
    color: hsl(var(--primary-foreground, 0 0% 100%));
    background: hsl(var(--primary));
    border-color: hsl(var(--primary));
  }
}

/* 月份标题：Apple 日历的中性大标题（不用品牌色染标题） */
.wc-month-hero {
  display: flex;
  align-items: baseline;
  color: hsl(var(--foreground));
}

.wc-month-num {
  font-size: 36px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -1.5px;
  font-variant-numeric: tabular-nums;
}

.wc-month-unit {
  font-size: 15px;
  font-weight: 600;
}

.wc-title-meta {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.wc-title-year {
  font-size: 14px;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.wc-lunar-year {
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}

.wc-header-right {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

.wc-btn-inner {
  display: inline-flex;
  gap: 4px;
  align-items: center;
}

/* 新建按钮改胶囊形，贴近 iOS 填充按钮 */
.wc-header-right :deep(.ant-btn-primary) {
  padding-inline: 16px;
  border-radius: 999px;
}

/* 月份切换：macOS 分段控件（灰色轨道 + 悬浮白片段） */
.wc-nav {
  display: flex;
  gap: 2px;
  align-items: center;
  padding: 2px;
  background: hsl(var(--muted) / 60%);
  border-radius: 9px;
}

.wc-nav-btn,
.wc-nav-today {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 26px;
  padding: 0 10px;
  font-size: 13px;
  color: hsl(var(--foreground) / 80%);
  cursor: pointer;
  background: transparent;
  border: none;
  border-radius: 7px;
  transition: background-color 0.2s, color 0.2s, box-shadow 0.2s;

  &:hover {
    color: hsl(var(--foreground));
    background: hsl(var(--card, var(--background)));
    box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
  }
}

.wc-nav-today {
  font-weight: 600;
}

.wc-legend {
  display: flex;
  gap: 10px;
  align-items: center;
}

.wc-legend-item {
  display: inline-flex;
  gap: 4px;
  align-items: center;
  font-size: 12px;
  color: hsl(var(--muted-foreground));

  .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;

    &.traditional {
      background: hsl(var(--destructive));
    }

    &.modern {
      background: hsl(var(--warning));
    }

    &.jieqi {
      background: hsl(var(--primary));
    }
  }

  .badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    font-size: 10px;
    font-style: normal;
    border-radius: 4px;

    &.rest {
      color: hsl(var(--primary));
      background: hsl(var(--primary) / 12%);
    }

    &.work {
      color: hsl(var(--warning));
      background: hsl(var(--warning) / 14%);
    }
  }
}

/* 日历主体：灰底画布，本月格子以白卡浮起（Apple 小组件「卡片浮在画布上」的层次） */
.wc-body {
  flex: 1;
  min-height: 0;
  padding: 4px;
  background: hsl(var(--muted) / 25%);
  border-radius: 14px;
}

/* antd 日历根节点背景交给外层卡片，避免暗色主题下出现色块拼缝 */
:deep(.ant-picker-calendar) {
  background: transparent;
}

/* ---------- 日历格子 ---------- */
.cal-cell {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 104px;
  padding: 7px 8px;
  margin: 3px;
  overflow: hidden;
  cursor: pointer;

  /* 本月格子 = 浮在灰底画布上的白卡（Apple 小组件层次），非本月透明淡化见下方 :deep */
  background: hsl(var(--card, var(--background)));
  border: 1px solid hsl(var(--border) / 50%);
  border-radius: 12px;
  box-shadow: 0 1px 2px rgb(0 0 0 / 4%);
  transition: background-color 0.2s, border-color 0.2s, box-shadow 0.2s;

  &:hover {
    box-shadow: 0 3px 10px rgb(0 0 0 / 8%);

    .cal-add {
      opacity: 1;
    }
  }

  /* 周末日期数字置灰（Apple 日历的周末处理） */
  &.is-weekend .cal-day {
    color: hsl(var(--muted-foreground));
  }

  /* 选中态：主色描边 + 外圈焦点光晕（iOS 焦点环），让「点格子看侧栏」有明确焦点 */
  &.is-selected {
    border-color: hsl(var(--primary) / 70%);
    box-shadow: 0 0 0 3px hsl(var(--primary) / 15%);
  }

  /* 今天：只给数字上主色圆徽（Apple 只标记数字），格子仅加淡主色描边 */
  &.is-today {
    border-color: hsl(var(--primary) / 45%);

    .cal-day {
      color: hsl(var(--primary-foreground, 0 0% 100%));
      background: hsl(var(--primary));
    }
  }
}

.cal-cell-head {
  display: flex;
  gap: 6px;
  align-items: center;
  min-width: 0;
}

.cal-day {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  font-size: 14px;
  font-weight: 600;
  color: hsl(var(--foreground));
  border-radius: 50%;
  transition: background-color 0.2s;
  font-variant-numeric: tabular-nums;
}

.cal-lunar {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  font-size: 12px;
  color: hsl(var(--muted-foreground));
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 节气/节日副行：与农历分离，互不覆盖 */
.cal-subline {
  display: flex;
  gap: 6px;
  align-items: center;
  min-width: 0;
  margin-top: 3px;
}

.cal-jieqi {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 600;
  color: hsl(var(--primary));
}

/* 节日颜色差异化：传统农历节日红、公历现代节日橙 */
.cal-festival {
  overflow: hidden;
  font-size: 11px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;

  &.traditional {
    color: hsl(var(--destructive));
  }

  &.modern {
    color: hsl(var(--warning));
  }
}

.cal-badge {
  flex-shrink: 0;
  padding: 0 4px;
  font-size: 10px;
  line-height: 16px;
  border-radius: 4px;

  &.rest {
    color: hsl(var(--primary));
    background: hsl(var(--primary) / 12%);
  }

  &.work {
    color: hsl(var(--warning));
    background: hsl(var(--warning) / 14%);
  }
}

/* hover 才出现的快捷新建按钮，避免视觉噪音 */
.cal-add {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  font-size: 13px;
  color: hsl(var(--primary));
  cursor: pointer;
  background: hsl(var(--primary) / 10%);
  border: none;
  border-radius: 6px;
  opacity: 0;
  transition: opacity 0.2s, background-color 0.2s;

  &:hover {
    background: hsl(var(--primary) / 20%);
  }
}

.cal-todos {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 6px;
}

/* 待办条目：Apple 事件块的柔和淡彩 + 1px 同色边框微光（规范禁止左侧色条式强调） */
.cal-todo {
  display: flex;
  gap: 5px;
  align-items: center;
  min-width: 0;
  padding: 2px 6px;
  font-size: 12px;
  color: hsl(var(--foreground) / 85%);
  cursor: pointer;
  background: hsl(var(--primary) / 7%);
  border: 1px solid hsl(var(--primary) / 22%);
  border-radius: 7px;
  box-shadow: 0 0 5px hsl(var(--primary) / 12%);
  transition: background-color 0.2s, border-color 0.2s, box-shadow 0.2s;

  &:hover {
    background: hsl(var(--primary) / 13%);
    border-color: hsl(var(--primary) / 45%);
    box-shadow: 0 0 7px hsl(var(--primary) / 22%);
  }

  &.done {
    color: hsl(var(--muted-foreground));
    text-decoration: line-through;
    border-color: hsl(var(--muted-foreground) / 25%);
    box-shadow: none;

    .cal-todo-dot {
      background: hsl(var(--muted-foreground));
    }
  }
}

.cal-todo-dot {
  flex-shrink: 0;
  width: 5px;
  height: 5px;
  background: hsl(var(--primary));
  border-radius: 50%;
}

.cal-todo-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cal-more {
  padding-left: 6px;
  font-size: 11px;
  color: hsl(var(--primary));
  cursor: pointer;

  &:hover {
    text-decoration: underline;
  }
}

/* 非当月格子：去掉白卡（背景/描边/阴影）并整体淡化，与本月浮卡拉开层次 */
:deep(.ant-picker-cell:not(.ant-picker-cell-in-view)) {
  .cal-cell {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    opacity: 0.5;
  }
}

/* 去掉 antd 日历自带的格子上边框与内边距，让自定义格子撑满 */
:deep(.ant-picker-calendar .ant-picker-panel) {
  background: transparent;
  border-top: none;
}

:deep(.ant-picker-calendar .ant-picker-cell) {
  padding: 0;
}

/* 星期表头：Apple 式小号灰字 + 轻字距 */
:deep(.ant-picker-calendar .ant-picker-content th) {
  padding: 10px 8px 8px;
  font-size: 11px;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
  text-align: center;
  letter-spacing: 0.05em;
}

/* ---------- 右侧详情侧栏（Apple 卡片：大圆角 + 发丝线 + 弥散阴影） ---------- */
.wc-side {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  width: 300px;
  overflow: hidden;
  background: hsl(var(--card, var(--background)));
  border: 1px solid hsl(var(--border) / 60%);
  border-radius: 18px;
  box-shadow: 0 2px 12px rgb(0 0 0 / 5%);
}

/* 选中日 hero：平铺淡彩衬底 + 发丝线分隔（去掉渐变，Apple 偏平铺材质） */
.wc-side-hero {
  padding: 18px 16px 14px;
  background: hsl(var(--primary) / 6%);
  border-bottom: 1px solid hsl(var(--border) / 50%);
}

.wc-side-date {
  display: flex;
  gap: 10px;
  align-items: center;
}

.wc-side-day {
  font-size: 44px;
  font-weight: 700;
  line-height: 1;
  color: hsl(var(--primary));
  letter-spacing: -2px;
  font-variant-numeric: tabular-nums;
}

.wc-side-date-meta {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.wc-side-ym {
  font-size: 14px;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.wc-side-week {
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}

.wc-back-today {
  display: inline-flex;
  gap: 3px;
  align-items: center;
  padding: 4px 10px;
  font-size: 12px;
  color: hsl(var(--primary));
  cursor: pointer;
  background: hsl(var(--primary) / 10%);
  border: none;
  border-radius: 999px;
  transition: background-color 0.2s;

  &:hover {
    background: hsl(var(--primary) / 18%);
  }
}

.wc-today-flag {
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 600;
  color: hsl(var(--primary-foreground, 0 0% 100%));
  background: hsl(var(--primary));
  border-radius: 999px;
}

.wc-side-lunar {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 10px;
}

.wc-side-lunar-main {
  font-size: 14px;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.wc-side-lunar-ganzhi {
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}

.wc-side-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.wc-tag {
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 500;
  border-radius: 999px;

  &.traditional {
    color: hsl(var(--destructive));
    background: hsl(var(--destructive) / 10%);
  }

  &.modern {
    color: hsl(var(--warning));
    background: hsl(var(--warning) / 14%);
  }

  &.jieqi {
    color: hsl(var(--primary));
    background: hsl(var(--primary) / 10%);
  }

  &.rest {
    color: hsl(var(--primary));
    background: hsl(var(--primary) / 12%);
  }

  &.work {
    color: hsl(var(--warning));
    background: hsl(var(--warning) / 14%);
  }
}

/* ---------- 宜忌：iOS 分组列表式内嵌圆角卡 ---------- */
.wc-yiji {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  margin: 12px 12px 0;
  background: hsl(var(--muted) / 30%);
  border-radius: 12px;
}

.wc-yiji-row {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}

.wc-yiji-mark {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  font-size: 12px;
  font-style: normal;
  font-weight: 600;
  border-radius: 6px;

  /* 宜=主色、忌=灰，避免大红大绿破坏后台整体色调 */
  &.yi {
    color: hsl(var(--primary));
    background: hsl(var(--primary) / 12%);
  }

  &.ji {
    color: hsl(var(--muted-foreground));
    background: hsl(var(--muted) / 60%);
  }
}

.wc-yiji-text {
  display: -webkit-box;
  overflow: hidden;
  font-size: 12px;
  line-height: 20px;
  color: hsl(var(--foreground) / 75%);
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

/* ---------- 侧栏待办清单 ---------- */
.wc-side-todos {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  padding: 12px;
}

.wc-side-todos-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-right: 4px;
  margin-bottom: 8px;
}

.wc-side-todos-title {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  font-size: 14px;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.wc-side-todos-count {
  padding: 0 7px;
  font-size: 11px;
  font-style: normal;
  font-weight: 600;
  line-height: 18px;
  color: hsl(var(--primary));
  background: hsl(var(--primary) / 12%);
  border-radius: 999px;
}

.wc-mini-add {
  display: inline-flex;
  gap: 3px;
  align-items: center;
  padding: 4px 10px;
  font-size: 12px;
  color: hsl(var(--primary));
  cursor: pointer;
  background: hsl(var(--primary) / 10%);
  border: none;
  border-radius: 999px;
  transition: background-color 0.2s;

  &:hover {
    background: hsl(var(--primary) / 18%);
  }
}

.wc-side-todo-list {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 6px;
  padding-right: 4px;
  overflow-y: auto;
}

.side-todo {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  padding: 9px 10px;
  background: hsl(var(--muted) / 30%);
  border: 1px solid transparent;
  border-radius: 12px;
  transition: border-color 0.2s, background-color 0.2s, box-shadow 0.2s;

  &:hover {
    background: hsl(var(--muted) / 45%);
    border-color: hsl(var(--primary) / 35%);
    box-shadow: 0 2px 8px rgb(0 0 0 / 6%);

    .side-todo-del {
      opacity: 1;
    }
  }

  &.done {
    .side-todo-title {
      color: hsl(var(--muted-foreground));
      text-decoration: line-through;
    }
  }
}

.side-todo-check {
  margin-top: 1px;
}

.side-todo-main {
  flex: 1;
  min-width: 0;
  cursor: pointer;
}

.side-todo-title {
  overflow: hidden;
  font-size: 13px;
  font-weight: 500;
  color: hsl(var(--foreground));
  text-overflow: ellipsis;
  white-space: nowrap;
}

.side-todo-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 3px;
  font-size: 11px;
  color: hsl(var(--muted-foreground));
}

.side-todo-time,
.side-todo-remind {
  display: inline-flex;
  gap: 3px;
  align-items: center;
}

.side-todo-remind {
  color: hsl(var(--primary) / 90%);
}

.side-todo-remind-fail {
  color: hsl(var(--destructive));
}

/* 删除按钮 hover 行内才出现，避免列表噪音 */
.side-todo-del {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  font-size: 13px;
  color: hsl(var(--muted-foreground));
  cursor: pointer;
  background: transparent;
  border: none;
  border-radius: 6px;
  opacity: 0;
  transition: opacity 0.2s, color 0.2s, background-color 0.2s;

  &:hover {
    color: hsl(var(--destructive));
    background: hsl(var(--destructive) / 10%);
  }
}

/* 空状态：轻量插画感 */
.wc-side-empty {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  padding: 36px 0;
}

.wc-side-empty-icon {
  font-size: 40px;
  color: hsl(var(--muted-foreground) / 45%);
}

.wc-side-empty-text {
  margin: 0;
  font-size: 13px;
  color: hsl(var(--muted-foreground));
}

.wc-side-empty-btn {
  padding: 5px 14px;
  font-size: 12px;
  color: hsl(var(--primary));
  cursor: pointer;
  background: hsl(var(--primary) / 10%);
  border: none;
  border-radius: 999px;
  transition: background-color 0.2s;

  &:hover {
    background: hsl(var(--primary) / 18%);
  }
}

/* ---------- 右键菜单：macOS 毛玻璃材质 ---------- */
.wc-ctx-menu {
  position: fixed;
  z-index: 2100;
  min-width: 172px;
  padding: 6px;
  background: hsl(var(--popover, var(--background)) / 82%);
  border: 1px solid hsl(var(--border) / 60%);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgb(0 0 0 / 16%);
  backdrop-filter: blur(18px) saturate(160%);
}

.wc-ctx-date {
  padding: 4px 10px 6px;
  font-size: 12px;
  color: hsl(var(--muted-foreground));
  border-bottom: 1px solid hsl(var(--border));
}

.wc-ctx-item {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
  padding: 7px 10px;
  margin-top: 2px;
  font-size: 13px;
  color: hsl(var(--foreground));
  cursor: pointer;
  border-radius: 6px;
  transition: background-color 0.15s, color 0.15s;

  &:hover {
    color: hsl(var(--primary));
    background: hsl(var(--primary) / 10%);
  }
}

.wc-ctx-label {
  display: inline-flex;
  gap: 6px;
  align-items: center;
}

.wc-ctx-count {
  padding: 0 6px;
  font-size: 11px;
  color: hsl(var(--primary));
  background: hsl(var(--primary) / 12%);
  border-radius: 8px;
}

/* ---------- 紧凑模式（工作台 widget）：整体收紧尺寸 ---------- */
.work-calendar.is-compact {
  .wc-main {
    padding: 14px;
    border-radius: 16px;
  }

  .wc-month-num {
    font-size: 26px;
  }

  .wc-header {
    padding-bottom: 10px;
  }

  .cal-cell {
    min-height: 70px;
    padding: 5px 7px;
    margin: 2px;
  }

  .wc-side {
    width: 272px;
    border-radius: 16px;
  }

  .wc-side-day {
    font-size: 36px;
  }

  .wc-side-hero {
    padding: 14px 14px 12px;
  }

  /* 紧凑模式待办清单限高，避免 widget 被撑得过长 */
  .wc-side-todo-list {
    max-height: 300px;
  }
}

/* ---------- 窄屏适配：侧栏下移到日历下方 ---------- */
@media (max-width: 1080px) {
  .work-calendar {
    flex-direction: column;
    overflow-y: auto;
  }

  .wc-main {
    flex: none;
    overflow: visible;
  }

  /* 加上 is-compact 组合选择器保证优先级高于紧凑模式的固定宽度 */
  .wc-side,
  .work-calendar.is-compact .wc-side {
    width: 100%;
  }

  .wc-side-todo-list {
    max-height: 320px;
  }
}
</style>
