<script lang="ts" setup>
/**
 * 医生排班设置抽屉
 * 配置项：出诊模式（每天/按星期多选）、时段类型（全天/上下午/自定义时段增删）、
 * 各时段号源数、可预约天数（0=跟随门店统一设置）、排班状态（停诊开关）
 * 为什么自绘控件而不用 useVbenForm：时段是动态数组（自定义模式可增删行），
 * vben form schema 不适配动态列表编辑，参照 workbench-widget.vue 自绘先例
 */
import type { ScheduleSlot } from '../api/schedule';

import { computed, ref } from 'vue';

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

import {
  Button,
  Checkbox,
  InputNumber,
  message,
  Radio,
  Switch,
  TimePicker,
} from 'ant-design-vue';
import dayjs from 'dayjs';

import { getDoctorScheduleApi, saveDoctorScheduleApi } from '../api/schedule';

/** 星期选项（值与后端 1-7 对齐，周一=1） */
const WEEK_OPTIONS = [
  { label: '周一', value: 1 },
  { label: '周二', value: 2 },
  { label: '周三', value: 3 },
  { label: '周四', value: 4 },
  { label: '周五', value: 5 },
  { label: '周六', value: 6 },
  { label: '周日', value: 7 },
];

const record = ref<any>({});
/** 出诊模式：1每天 2按星期 */
const scheduleMode = ref<number>(1);
/** 按星期出诊日 */
const weekDays = ref<number[]>([]);
/** 时段类型：1全天 2上下午 3自定义 */
const slotType = ref<number>(1);
/** 时段列表（随 slotType 切换重建） */
const slots = ref<ScheduleSlot[]>([]);
/** 可预约天数（0=跟随门店统一） */
const bookDays = ref<number>(0);
/** 门店统一天数（提示用） */
const storeDefaultDays = ref<number>(7);
/** 排班状态：true=正常放号 false=停诊 */
const enabled = ref<boolean>(true);

const drawerTitle = computed(() => {
  const name = record.value?.name || record.value?.service_user?.name || '';
  return name ? `排班设置 - ${name}` : '排班设置';
});

/** 医生 su_id（排班按医生维度，跨门店共享） */
const doctorSuId = computed(() =>
  Number(record.value?.su_id || record.value?.service_user?.id || 0),
);

/**
 * 按时段类型生成默认时段（切换类型时调用）
 */
function buildDefaultSlots(type: number): ScheduleSlot[] {
  if (type === 1) {
    return [
      { slot_name: '全天', start_time: '00:00', end_time: '23:59', capacity: 30 },
    ];
  }
  if (type === 2) {
    return [
      { slot_name: '上午', start_time: '08:00', end_time: '12:00', capacity: 15 },
      { slot_name: '下午', start_time: '13:00', end_time: '18:00', capacity: 15 },
    ];
  }
  return [
    { slot_name: '', start_time: '09:00', end_time: '10:00', capacity: 5 },
  ];
}

/**
 * 切换时段类型：保留全天容量总数体验，直接按类型重建时段行
 */
function onSlotTypeChange(type: number) {
  slotType.value = type;
  slots.value = buildDefaultSlots(type);
}

/** 自定义模式增加时段行（上限 10 个） */
function addSlot() {
  if (slots.value.length >= 10) {
    message.warning('最多支持 10 个时段');
    return;
  }
  slots.value.push({
    slot_name: '',
    start_time: '',
    end_time: '',
    capacity: 5,
  });
}

/** 自定义模式删除时段行 */
function removeSlot(index: number) {
  if (slots.value.length <= 1) {
    message.warning('至少保留一个时段');
    return;
  }
  slots.value.splice(index, 1);
}

/** TimePicker 变更（HH:mm 字符串双向） */
function onTimeChange(slot: ScheduleSlot, key: 'end_time' | 'start_time', val: any) {
  slot[key] = val ? dayjs(val, 'HH:mm').format('HH:mm') : '';
}

/**
 * 拉取排班配置回显
 */
async function fetchData() {
  if (!doctorSuId.value) {
    message.error('医生信息缺失（su_id）');
    return;
  }
  const data = await getDoctorScheduleApi(doctorSuId.value);
  scheduleMode.value = Number(data?.schedule_mode || 1);
  weekDays.value = Array.isArray(data?.week_days) ? data.week_days : [];
  slotType.value = Number(data?.slot_type || 1);
  bookDays.value = Number(data?.book_days || 0);
  storeDefaultDays.value = Number(data?.store_default_book_days || 7);
  enabled.value = Number(data?.status ?? 1) === 1;
  const list = Array.isArray(data?.slots) ? data.slots : [];
  slots.value =
    list.length > 0
      ? list.map((item: any) => ({
          id: Number(item.id || 0),
          slot_name: String(item.slot_name || ''),
          start_time: String(item.start_time || ''),
          end_time: String(item.end_time || ''),
          capacity: Number(item.capacity || 0),
        }))
      : buildDefaultSlots(slotType.value);
}

/**
 * 前端轻校验后提交（重叠/格式等强校验在服务端兜底）
 */
async function handleSave() {
  if (scheduleMode.value === 2 && weekDays.value.length === 0) {
    message.warning('按星期出诊时请至少选择一个出诊日');
    return;
  }
  for (const slot of slots.value) {
    if (slotType.value !== 1 && (!slot.start_time || !slot.end_time)) {
      message.warning('请补全各时段的开始/结束时间');
      return;
    }
    if (!slot.capacity || slot.capacity < 1) {
      message.warning('各时段号源数量至少为 1');
      return;
    }
  }
  DrawerApi.lock();
  try {
    await saveDoctorScheduleApi({
      doctor_id: doctorSuId.value,
      schedule_mode: scheduleMode.value,
      week_days: weekDays.value,
      slot_type: slotType.value,
      book_days: bookDays.value,
      status: enabled.value ? 1 : 0,
      slots: slots.value,
    });
    message.success('排班保存成功');
    DrawerApi.close();
  } catch {
    // 错误提示由 requestClient 统一弹出
  } finally {
    DrawerApi.unlock();
  }
}

const [Drawer, DrawerApi] = useVbenDrawer({
  onOpenChange(isOpen) {
    if (isOpen) {
      record.value = DrawerApi.getData()?.record || {};
      DrawerApi.setState({ loading: true });
      fetchData()
        .catch(() => message.error('获取排班配置失败'))
        .finally(() => DrawerApi.setState({ loading: false }));
    }
  },
  onConfirm: handleSave,
});

defineExpose({ DrawerApi });
</script>

<template>
  <Drawer :title="drawerTitle" class="w-[520px]">
    <div class="schedule-form">
      <!-- 排班状态 -->
      <div class="schedule-form__item">
        <div class="schedule-form__label">排班状态</div>
        <div class="schedule-form__control">
          <Switch v-model:checked="enabled" />
          <span class="schedule-form__tip">{{
            enabled ? '正常放号' : '停诊（患者端不可预约）'
          }}</span>
        </div>
      </div>

      <!-- 出诊模式 -->
      <div class="schedule-form__item">
        <div class="schedule-form__label">出诊模式</div>
        <div class="schedule-form__control">
          <Radio.Group v-model:value="scheduleMode">
            <Radio :value="1">每天出诊</Radio>
            <Radio :value="2">按星期出诊</Radio>
          </Radio.Group>
        </div>
      </div>

      <!-- 按星期出诊日 -->
      <div v-if="scheduleMode === 2" class="schedule-form__item">
        <div class="schedule-form__label">出诊日</div>
        <div class="schedule-form__control">
          <Checkbox.Group v-model:value="weekDays" :options="WEEK_OPTIONS" />
        </div>
      </div>

      <!-- 时段类型 -->
      <div class="schedule-form__item">
        <div class="schedule-form__label">时段类型</div>
        <div class="schedule-form__control">
          <Radio.Group
            :value="slotType"
            @update:value="(val: any) => onSlotTypeChange(Number(val))"
          >
            <Radio :value="1">全天</Radio>
            <Radio :value="2">上下午</Radio>
            <Radio :value="3">自定义时段</Radio>
          </Radio.Group>
        </div>
      </div>

      <!-- 时段列表 -->
      <div class="schedule-form__item">
        <div class="schedule-form__label">
          号源时段
          <Button
            v-if="slotType === 3"
            size="small"
            type="link"
            @click="addSlot"
          >
            <VbenIcon icon="lucide:plus" />
            加时段
          </Button>
        </div>
        <div class="schedule-form__slots">
          <div v-for="(slot, index) in slots" :key="index" class="slot-row">
            <span v-if="slotType !== 3" class="slot-row__name">
              {{ slot.slot_name }}
            </span>
            <template v-if="slotType !== 1">
              <TimePicker
                :value="slot.start_time ? dayjs(slot.start_time, 'HH:mm') : null"
                format="HH:mm"
                placeholder="开始"
                size="small"
                @update:value="(val: any) => onTimeChange(slot, 'start_time', val)"
              />
              <span class="slot-row__sep">~</span>
              <TimePicker
                :value="slot.end_time ? dayjs(slot.end_time, 'HH:mm') : null"
                format="HH:mm"
                placeholder="结束"
                size="small"
                @update:value="(val: any) => onTimeChange(slot, 'end_time', val)"
              />
            </template>
            <span v-else class="slot-row__name-full">00:00 ~ 23:59</span>
            <InputNumber
              v-model:value="slot.capacity"
              :max="999"
              :min="1"
              size="small"
              style="width: 90px"
            />
            <span class="slot-row__unit">个号</span>
            <Button
              v-if="slotType === 3"
              danger
              size="small"
              type="text"
              @click="removeSlot(index)"
            >
              <VbenIcon icon="lucide:x" />
            </Button>
          </div>
        </div>
        <div v-if="slotType === 3" class="schedule-form__tip">
          自定义时段名称留空时自动使用时间段命名，时段之间不可重叠
        </div>
      </div>

      <!-- 可预约天数 -->
      <div class="schedule-form__item">
        <div class="schedule-form__label">可预约天数（含当天）</div>
        <div class="schedule-form__control">
          <InputNumber v-model:value="bookDays" :max="30" :min="0" style="width: 120px" />
          <span class="schedule-form__tip">
            0 = 跟随门店统一设置（当前 {{ storeDefaultDays }} 天）
          </span>
        </div>
      </div>

      <!-- 日历排班指引：本抽屉配置的是默认规则，按日期排班走诊所管理入口 -->
      <div class="schedule-form__notice">
        此处为医生的<b>默认排班规则</b>。如需按具体日期排班（周排/月排、套班次模板、单日休诊），
        请到「诊所药店管理 → 操作 → 排班管理」的日历排班中设置，按日期排班优先于默认规则生效。
      </div>
    </div>
  </Drawer>
</template>

<style scoped>
.schedule-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.schedule-form__label {
  display: flex;
  gap: 4px;
  align-items: center;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.schedule-form__control {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

.schedule-form__tip {
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}

.schedule-form__slots {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.slot-row {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 8px 10px;
  background: hsl(var(--muted) / 0.25);
  border: 1px solid hsl(var(--border));
  border-radius: 6px;
}

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

.slot-row__name-full {
  font-size: 13px;
  color: hsl(var(--muted-foreground));
}

.slot-row__sep,
.slot-row__unit {
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}

/* 日历排班指引：同色系边框 + 微光，不用左侧色条 */
.schedule-form__notice {
  padding: 10px 12px;
  font-size: 12px;
  line-height: 1.7;
  color: hsl(var(--muted-foreground));
  background: hsl(var(--primary) / 0.04);
  border: 1px solid hsl(var(--primary) / 30%);
  border-radius: 8px;
  box-shadow: 0 0 6px hsl(var(--primary) / 18%);
}

.schedule-form__notice b {
  color: hsl(var(--foreground));
}
</style>
