<script lang="ts" setup>
/**
 * 消息中心 · 排班变更专属视图（type_code=schedule_change）
 * 渲染 action_payload：动作场景卡 + 涉及日期 chips + 新时段表 + 操作人/批次溯源
 * 医生收到后一眼看清「哪家诊所把我哪些天改成了什么班」
 */
import { computed, ref } from 'vue';

const props = defineProps<{
  notice: Record<string, any>;
}>();

/** 日期默认收起阈值：月排可能 30+ 天，全量平铺会把弹窗撑爆 */
const DATE_COLLAPSE_LIMIT = 12;
const datesExpanded = ref(false);

/** action_payload 可能是对象（接口已解析）或 JSON 字符串（兜底解析） */
const payload = computed<Record<string, any>>(() => {
  const p = props.notice?.action_payload;
  if (p && typeof p === 'object') return p;
  try {
    return JSON.parse(String(p || '{}')) || {};
  } catch {
    return {};
  }
});

/** 动作场景：文案 + 色调（休诊红 / 恢复默认灰 / 排班青） */
const scene = computed(() => {
  const action = Number(payload.value?.action || 0);
  if (action === 3) return { label: '设为休诊', tone: 'danger' };
  if (action === 4) return { label: '恢复默认规则', tone: 'normal' };
  if (action === 1) {
    const name = String(payload.value?.template_name || '');
    return { label: name ? `套用模板「${name}」` : '套用班次模板', tone: 'work' };
  }
  return { label: payload.value?.action_txt || '排班调整', tone: 'work' };
});

const dates = computed<string[]>(() =>
  Array.isArray(payload.value?.dates) ? payload.value.dates : [],
);

/** 收起态只显示前 N 个日期 */
const visibleDates = computed(() =>
  datesExpanded.value ? dates.value : dates.value.slice(0, DATE_COLLAPSE_LIMIT),
);

const slots = computed<Array<Record<string, any>>>(() =>
  Array.isArray(payload.value?.slots) ? payload.value.slots : [],
);

/** 日期显示成「8/19 周三」这种紧凑格式 */
function formatDate(date: string): string {
  const d = new Date(`${date}T00:00:00`);
  if (Number.isNaN(d.getTime())) return date;
  const weeks = ['日', '一', '二', '三', '四', '五', '六'];
  return `${d.getMonth() + 1}/${d.getDate()} 周${weeks[d.getDay()]}`;
}
</script>

<template>
  <div class="sched-notice">
    <!-- 场景卡：动作 + 医生 + 门店 -->
    <div class="hero" :class="`tone-${scene.tone}`">
      <div class="hero__glow" aria-hidden="true"></div>
      <div class="hero__top">
        <span class="scene-pill">{{ scene.label }}</span>
        <span class="count-pill">{{ dates.length }} 天</span>
      </div>
      <h3 class="hero__title">
        {{ payload.doctor_name || '您' }} 的出诊排班有调整
      </h3>
      <p class="hero__store">{{ payload.store_name || notice.title || '' }}</p>
    </div>

    <!-- 涉及日期 -->
    <div v-if="dates.length > 0" class="section">
      <div class="section__label">涉及日期</div>
      <div class="date-chips">
        <span v-for="d in visibleDates" :key="d" class="date-chip">
          {{ formatDate(d) }}
        </span>
        <button
          v-if="dates.length > DATE_COLLAPSE_LIMIT"
          class="date-chip date-chip--more"
          type="button"
          @click="datesExpanded = !datesExpanded"
        >
          {{ datesExpanded ? '收起' : `+${dates.length - DATE_COLLAPSE_LIMIT}` }}
        </button>
      </div>
    </div>

    <!-- 新排班时段（休诊/恢复默认无时段） -->
    <div v-if="slots.length > 0" class="section">
      <div class="section__label">调整后的出诊时段</div>
      <div class="slot-list">
        <div v-for="(slot, i) in slots" :key="i" class="slot-row">
          <span class="slot-row__name">{{ slot.slot_name || `时段${i + 1}` }}</span>
          <span class="slot-row__time">{{ slot.start_time }} - {{ slot.end_time }}</span>
          <span class="slot-row__cap">号源 {{ slot.capacity }}</span>
        </div>
      </div>
    </div>
    <div v-else-if="Number(payload.action) === 3" class="section rest-hint">
      以上日期已停诊，患者端不再放号；已有预约不受本次操作影响
    </div>
    <div v-else-if="Number(payload.action) === 4" class="section rest-hint">
      以上日期回到您的默认排班规则（按医生管理里配置的每天/按星期规则放号）
    </div>

    <p v-if="notice.detail" class="detail">{{ notice.detail }}</p>
    <div class="meta-line">
      <span v-if="payload.operator_name">操作人：{{ payload.operator_name }}</span>
      <span v-if="payload.batch_no">批次号：{{ payload.batch_no }}</span>
    </div>
  </div>
</template>

<style scoped>
.sched-notice {
  padding: 2px 0 6px;
}

/* 场景 hero 卡：青色系（对应 schedule_change 类型色），休诊红、恢复灰 */
.hero {
  position: relative;
  padding: 18px 20px;
  overflow: hidden;
  color: #fff;
  background: linear-gradient(135deg, #16323a 0%, #1f5560 48%, #2a97a8 100%);
  border-radius: 16px;
  box-shadow:
    0 10px 28px hsl(190 45% 22% / 0.28),
    inset 0 1px 0 hsl(0 0% 100% / 0.12);
}

.hero.tone-danger {
  background: linear-gradient(135deg, #2a181c 0%, #5a2430 52%, #a33b4a 100%);
  box-shadow:
    0 10px 28px hsl(350 45% 22% / 0.28),
    inset 0 1px 0 hsl(0 0% 100% / 0.12);
}

.hero.tone-normal {
  background: linear-gradient(135deg, #23272e 0%, #3a4149 52%, #5d6b77 100%);
  box-shadow:
    0 10px 28px hsl(215 15% 22% / 0.28),
    inset 0 1px 0 hsl(0 0% 100% / 0.12);
}

.hero__glow {
  position: absolute;
  inset: -40% auto auto -20%;
  width: 70%;
  height: 90%;
  pointer-events: none;
  background: radial-gradient(circle, hsl(0 0% 100% / 0.16), transparent 68%);
}

.hero__top {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 12px;
}

.scene-pill,
.count-pill {
  display: inline-flex;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  background: hsl(0 0% 100% / 0.16);
  backdrop-filter: blur(6px);
  border-radius: 999px;
}

.hero__title {
  position: relative;
  z-index: 1;
  margin: 0;
  font-size: 18px;
  font-weight: 720;
  letter-spacing: -0.02em;
}

.hero__store {
  position: relative;
  z-index: 1;
  margin: 6px 0 0;
  font-size: 13px;
  opacity: 0.85;
}

.section {
  margin-top: 14px;
}

.section__label {
  margin-bottom: 8px;
  font-size: 12px;
  font-weight: 600;
  color: hsl(var(--muted-foreground));
}

.date-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.date-chip {
  padding: 3px 10px;
  font-size: 12px;
  color: hsl(var(--foreground));
  background: hsl(var(--muted) / 0.35);
  border: 1px solid hsl(var(--border));
  border-radius: 8px;
}

.date-chip--more {
  color: hsl(var(--primary));
  cursor: pointer;
  background: hsl(var(--primary) / 0.08);
  border-color: hsl(var(--primary) / 0.35);
}

.slot-list {
  overflow: hidden;
  border: 1px solid hsl(var(--border));
  border-radius: 12px;
}

.slot-row {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 10px 14px;
  background: hsl(var(--card, var(--background)));
}

.slot-row + .slot-row {
  border-top: 1px solid hsl(var(--border) / 0.6);
}

.slot-row__name {
  min-width: 64px;
  font-size: 13px;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.slot-row__time {
  flex: 1;
  font-size: 13px;
  color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums;
}

.slot-row__cap {
  font-size: 12px;
  font-weight: 600;
  color: hsl(var(--primary));
}

.rest-hint {
  padding: 10px 14px;
  font-size: 13px;
  color: hsl(var(--muted-foreground));
  background: hsl(var(--muted) / 0.25);
  border: 1px solid hsl(var(--border));
  border-radius: 12px;
}

.detail {
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: hsl(var(--muted-foreground));
}

.meta-line {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 10px;
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}
</style>
