<template>
  <div class="info-management">
    <div class="page-title">信息设置</div>

    <!-- 基础信息 -->
    <div class="form-card">
      <div class="section-title">
        <span class="section-bar" />
        <span>基础信息</span>
      </div>
      <el-form :model="form.base" label-width="450px" class="section-form">
        <el-form-item label="未按时到店">
          <el-radio-group v-model="form.base.keepPosition">
            <el-radio label="keep"> 保留位置 </el-radio>
            <el-radio label="notKeep"> 不保留位置 </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item v-if="form.base.keepPosition === 'keep'" label="保留时长(分钟)" required>
          <el-input
            :model-value="String(form.base.retentionMinutes ?? '')"
            placeholder="请输入"
            clearable
            maxlength="2"
            class="form-input"
            @update:model-value="(v: string) => onIntInput(v, 2, n => (form.base.retentionMinutes = n))"
          />
        </el-form-item>
        <el-form-item label="预订日期显示(天)" required>
          <el-input
            :model-value="String(form.base.bookDateDays ?? '')"
            placeholder="请输入"
            clearable
            maxlength="2"
            class="form-input"
            @update:model-value="(v: string) => onIntInput(v, 2, n => (form.base.bookDateDays = n))"
          />
        </el-form-item>
        <el-form-item label="单时段最大容纳人数" required>
          <el-input
            :model-value="String(form.base.maxCapacityPerSlot ?? '')"
            placeholder="请输入"
            clearable
            maxlength="4"
            class="form-input"
            @update:model-value="(v: string) => onIntInput(v, 4, n => (form.base.maxCapacityPerSlot = n))"
          />
        </el-form-item>
      </el-form>
    </div>

    <!-- 预订设置 -->
    <div class="form-card">
      <div class="section-title">
        <span class="section-bar" />
        <span>预订设置</span>
      </div>
      <el-form :model="form.booking" label-width="450px" class="section-form">
        <el-form-item label="预订">
          <el-radio-group v-model="form.booking.feeType">
            <el-radio label="free"> 免费 </el-radio>
            <el-radio label="paid"> 付费 </el-radio>
          </el-radio-group>
        </el-form-item>
        <template v-if="form.booking.feeType === 'paid'">
          <el-form-item label="预订金额(元)" required>
            <el-input
              :model-value="String(form.booking.bookAmount ?? '')"
              placeholder="请输入"
              clearable
              maxlength="3"
              class="form-input"
              @update:model-value="(v: string) => onIntInput(v, 3, n => (form.booking.bookAmount = n))"
            />
          </el-form-item>
          <el-form-item label="取消预订退费时长设置,需提前(小时)" required>
            <el-input
              :model-value="String(form.booking.refundAdvanceHours ?? '')"
              placeholder="请输入"
              clearable
              maxlength="3"
              class="form-input"
              @update:model-value="(v: string) => onIntInput(v, 3, n => (form.booking.refundAdvanceHours = n))"
            />
          </el-form-item>
        </template>
        <el-form-item label="营业时间结束前多少分钟不可预订" required>
          <el-input
            :model-value="String(form.booking.noBookMinutesBeforeClose ?? '')"
            placeholder="请输入"
            clearable
            maxlength="3"
            class="form-input"
            @update:model-value="(v: string) => onIntInput(v, 3, n => (form.booking.noBookMinutesBeforeClose = n))"
          />
        </el-form-item>
      </el-form>
    </div>

    <!-- 正常营业 -->
    <div class="form-card">
      <div class="section-title">
        <span class="section-bar" />
        <span>正常营业</span>
      </div>
      <el-form :model="form.normalBook" label-width="450px" class="section-form">
        <el-form-item label="预订时间">
          <el-radio-group v-model="form.normalBook.timeType">
            <el-radio label="allDay" :disabled="normalAllDayDisabled"> 全天 </el-radio>
            <el-radio label="notAllDay"> 非全天 </el-radio>
          </el-radio-group>
        </el-form-item>
        <template v-if="form.normalBook.timeType === 'notAllDay'">
          <el-form-item label="时间设置">
            <div class="time-row">
              <el-time-picker
                v-model="normalStartTimeValue"
                format="HH:mm"
                value-format="HH:mm"
                placeholder="选择开始时间"
                style="width: 160px"
                :disabled-hours="normalStartDisabledHours"
                :disabled-minutes="normalStartDisabledMinutes"
                @visible-change="v => v && initNormalStartPickerRange()"
                @change="onNormalStartTimeChange"
              />
              <el-time-picker
                v-model="normalEndTimeValue"
                format="HH:mm"
                value-format="HH:mm"
                placeholder="选择结束时间(次日)"
                style="width: 160px"
                :disabled-hours="normalEndDisabledHours"
                :disabled-minutes="normalEndDisabledMinutes"
                @visible-change="v => v && initNormalEndPickerRange()"
                @change="onNormalEndTimeChange"
              />
            </div>
          </el-form-item>
        </template>
      </el-form>
    </div>

    <!-- 特殊营业 -->
    <div class="form-card">
      <div class="section-title">
        <span class="section-bar" />
        <span>特殊营业</span>
      </div>
      <el-form label-width="450px" class="section-form">
        <el-form-item label="选择节日">
          <el-select
            v-model="selectedHolidayNames"
            multiple
            collapse-tags
            collapse-tags-tooltip
            placeholder="下拉菜单"
            style="width: 40%"
            :disabled="holidayOptions.length === 0"
          >
            <el-option
              v-for="item in holidayOptions"
              :key="item.name"
              :label="item.name"
              :value="item.name"
              :disabled="!allowedFestivalSet.has(item.name)"
            />
          </el-select>
        </el-form-item>
        <template v-for="(item, idx) in form.specialList" :key="item.name + '-' + idx">
          <template v-if="showSpecialRowTimeUI(item)">
            <el-form-item :label="item.name">
              <el-radio-group v-model="item.allDay">
                <el-radio label="allDay" :disabled="!!specialAllDayDisabledMap[item.name]"> 全天 </el-radio>
                <el-radio label="notAllDay"> 非全天 </el-radio>
              </el-radio-group>
            </el-form-item>
            <div v-if="item.allDay === 'notAllDay'" class="special-time-row" style="display: flex">
              <el-form-item label="时间设置" label-width="450px">
                <el-time-picker
                  v-model="item.startTime"
                  format="HH:mm"
                  value-format="HH:mm"
                  placeholder="选择开始时间"
                  style="width: 160px"
                  :disabled-hours="() => specialDisabledHours()"
                  :disabled-minutes="(h: number) => specialDisabledMinutes(h)"
                  @visible-change="v => v && initSpecialPickerRange(item.name, 'start')"
                  @change="() => onSpecialTimeChange(item.name, 'start')"
                />
              </el-form-item>
              <el-form-item label="" label-width="10px">
                <el-time-picker
                  v-model="item.endTime"
                  format="HH:mm"
                  value-format="HH:mm"
                  placeholder="选择结束时间"
                  style="width: 160px"
                  :disabled-hours="() => specialDisabledHours()"
                  :disabled-minutes="(h: number) => specialDisabledMinutes(h)"
                  @visible-change="v => v && initSpecialPickerRange(item.name, 'end')"
                  @change="() => onSpecialTimeChange(item.name, 'end')"
                />
              </el-form-item>
            </div>
          </template>
        </template>
      </el-form>
    </div>
    <div style="display: flex; justify-content: center; width: 100%">
      <el-button type="primary" :loading="saveLoading" @click="onSave"> 保存 </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, watch } from "vue";
import { ElMessage } from "element-plus";
import { InfoFilled } from "@element-plus/icons-vue";
import { bookingSettingsDetail, bookingSettingsSave, getBookingBusinessHours } from "@/api/modules/scheduledService";
import { getStoreInfoBusinessHours, getHolidayList } from "@/api/modules/storeDecoration";
import { localGet } from "@/utils";

const saveLoading = ref(false);

/** 数字输入：仅保留数字、限制位数，清空为 0 */
function onIntInput(raw: string, maxLen: number, set: (n: number) => void) {
  const d = String(raw).replace(/\D/g, "").slice(0, maxLen);
  set(d === "" ? 0 : parseInt(d, 10));
}

const form = reactive({
  base: {
    id: undefined as number | string | undefined,
    keepPosition: "keep" as "keep" | "notKeep",
    retentionMinutes: 30 as number,
    bookDateDays: 7 as number,
    maxCapacityPerSlot: 10 as number
  },
  booking: {
    feeType: "free" as "free" | "paid",
    bookAmount: 0 as number,
    refundAdvanceHours: 24 as number,
    noBookMinutesBeforeClose: 30 as number
  },
  normalBook: {
    timeType: "allDay" as "allDay" | "notAllDay",
    startTime: "" as string,
    endTime: "" as string,
    normalId: 0 as number
  },
  specialList: [] as {
    name: string;
    allDay: "allDay" | "notAllDay";
    startTime: string;
    endTime: string;
    id?: number;
    essentialId?: number | string;
    /** 与商家端：用户在选择节日中勾选的行才展示时间配置；接口回显匹配上的也为 true */
    userPickedSpecial?: boolean;
  }[]
});

const listFromStoreInfo = ref<any[]>([]);
const listBooking = ref<any[]>([]);
const holidayOptions = ref<{ name: string }[]>([]);

const normalStartTimeValue = ref<string>("");
const normalEndTimeValue = ref<string>("");

watch(
  () => form.normalBook.startTime,
  v => {
    normalStartTimeValue.value = v || "";
  },
  { immediate: true }
);
watch(
  () => form.normalBook.endTime,
  v => {
    normalEndTimeValue.value = v || "";
  },
  { immediate: true }
);
watch(normalStartTimeValue, v => {
  form.normalBook.startTime = v || "";
});
watch(normalEndTimeValue, v => {
  form.normalBook.endTime = v || "";
});

watch(
  () => form.normalBook.startTime,
  v => {
    if (form.normalBook.timeType !== "notAllDay" || !v || !form.normalBook.endTime) return;
    const st = timeStrToMinutes(v);
    const et = timeStrToMinutes(form.normalBook.endTime);
    if (et >= st) return;
    const s = minutesToTimeStr(st);
    normalEndTimeValue.value = s;
    form.normalBook.endTime = s;
  }
);

const allowedFestivalSet = computed(() => {
  const set = new Set<string>();
  listFromStoreInfo.value
    .filter(item => item.businessType === 2)
    .forEach(item => {
      const name =
        (item.holidayInfo && item.holidayInfo.festivalName != null ? String(item.holidayInfo.festivalName).trim() : "") ||
        (item.festivalName != null ? String(item.festivalName).trim() : "") ||
        (item.businessDate != null ? String(item.businessDate).trim() : "") ||
        (item.holidayType != null ? String(item.holidayType).trim() : "");
      if (name) set.add(name);
    });
  return set;
});

/** 门店单条 businessType=2：均为 00:00 为全天，否则非全天；元旦固定非全天（与商家端 infoManagement） */
function allDayFromStoreSpecialRow(storeRow: any): "allDay" | "notAllDay" {
  if (!storeRow || Number(storeRow.businessType) !== 2) return "notAllDay";
  const nm = String(
    (storeRow.holidayInfo && storeRow.holidayInfo.festivalName) || storeRow.businessDate || storeRow.holidayType || ""
  ).trim();
  if (nm === "元旦") return "notAllDay";
  const st = String(storeRow.startTime ?? "").trim();
  const et = String(storeRow.endTime ?? "").trim();
  return st === "00:00" && et === "00:00" ? "allDay" : "notAllDay";
}

function allDayFromStoreByHolidayName(holidayName: string): "allDay" | "notAllDay" {
  const n = String(holidayName || "").trim();
  if (!n) return "allDay";
  const list = Array.isArray(listFromStoreInfo.value) ? listFromStoreInfo.value : [];
  const row = list.find((item: any) => {
    if (Number(item.businessType) !== 2) return false;
    const fn = (item.holidayInfo && item.holidayInfo.festivalName != null ? String(item.holidayInfo.festivalName) : "").trim();
    const bd = item.businessDate != null ? String(item.businessDate).trim() : "";
    const ht = item.holidayType != null ? String(item.holidayType).trim() : "";
    return fn === n || bd === n || ht === n;
  });
  return row ? allDayFromStoreSpecialRow(row) : "allDay";
}

function getStoreSpecialRowMeta(name: string): { id?: number; essentialId?: number | string } {
  const n = String(name || "").trim();
  const list = Array.isArray(listFromStoreInfo.value) ? listFromStoreInfo.value : [];
  const row = list.find((item: any) => {
    if (Number(item.businessType) !== 2) return false;
    const fn = (item.holidayInfo && item.holidayInfo.festivalName != null ? String(item.holidayInfo.festivalName) : "").trim();
    const bd = item.businessDate != null ? String(item.businessDate).trim() : "";
    const ht = item.holidayType != null ? String(item.holidayType).trim() : "";
    return fn === n || bd === n || ht === n;
  });
  if (!row) return {};
  return { id: row.id != null ? Number(row.id) : undefined, essentialId: row.essentialId };
}

function rowHasSpecialTimeConfigured(s: (typeof form.specialList)[0]): boolean {
  const st = String(s.startTime ?? "").trim();
  const et = String(s.endTime ?? "").trim();
  if (s.allDay === "allDay" && st === "00:00" && et === "00:00") return true;
  return st !== "" && et !== "";
}

function showSpecialRowTimeUI(s: (typeof form.specialList)[0]): boolean {
  return rowHasSpecialTimeConfigured(s) || s.userPickedSpecial === true;
}

const selectedHolidayNames = computed({
  get: () => form.specialList.map(s => s.name),
  set: (val: string[]) => {
    const existingMap: Record<string, (typeof form.specialList)[0]> = {};
    form.specialList.forEach(s => {
      existingMap[s.name] = s;
    });
    form.specialList = val.map(name => {
      const ex = existingMap[name];
      const ad = allDayFromStoreByHolidayName(name);
      const meta = getStoreSpecialRowMeta(name);
      if (ex) {
        return { ...ex, allDay: ad, userPickedSpecial: true };
      }
      return {
        name,
        allDay: ad,
        startTime: "",
        endTime: "",
        userPickedSpecial: true,
        id: meta.id,
        essentialId: meta.essentialId
      };
    });
  }
});

function getStoreId(): number | string | null {
  return localGet("geeker-user")?.userInfo?.storeId ?? localGet("createdId") ?? null;
}

function subtractMinutesFromTime(timeStr: string, minutes: number): string {
  const [h, m] = (timeStr || "00:00").split(":").map(Number);
  let total = (h || 0) * 60 + (m || 0);
  total = Math.max(0, total - (Number(minutes) || 0));
  const nh = Math.floor(total / 60) % 24;
  const nm = total % 60;
  return `${String(nh).padStart(2, "0")}:${String(nm).padStart(2, "0")}`;
}

function timeStrToMinutes(timeStr: string): number {
  const [h, m] = String(timeStr || "00:00")
    .split(":")
    .map(Number);
  return Math.max(0, Math.min(23 * 60 + 59, (h || 0) * 60 + (m || 0)));
}

function minutesToTimeStr(total: number): string {
  const t = Math.max(0, Math.min(23 * 60 + 59, total));
  const h = Math.floor(t / 60);
  const m = t % 60;
  return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
}

/**
 * 与 group_merchant infoManagement：只要填写了「结束前不可预订」分钟数，
 * 正常/特殊营业的结束时间可选上限 = 营业 endTime − 该分钟数（picker 用）
 */
function getNoBookMinutesForPicker(): number {
  const v = form.booking.noBookMinutesBeforeClose;
  if (v == null) return 0;
  const n = Number(v);
  return n > 0 && !isNaN(n) ? n : 0;
}

/**
 * 门店营业结束时刻 → 回显「可预约结束时间」：营业 endTime − 「结束前不可预订」分钟（与 computePickerEndMinutes 一致）。
 * 仅用于从 getStoreInfoBusinessHours 回填；预约接口已存的 endTime 勿再调用，避免重复相减。
 */
function echoBookableEndFromStoreEnd(storeEndTime: string | undefined | null): string {
  const raw = String(storeEndTime ?? "23:59").trim() || "23:59";
  const noBook = getNoBookMinutesForPicker();
  if (!noBook) return raw;
  return subtractMinutesFromTime(raw, noBook);
}

/** 正常营业「全天/非全天」仅按门店 getStoreInfoBusinessHours 中 businessType=1 或 0 的 startTime、endTime */
function applyNormalTimeTypeFromStore() {
  const storeInfoList = Array.isArray(listFromStoreInfo.value) ? listFromStoreInfo.value : [];
  const normal = storeInfoList.find((item: any) => item.businessType === 1 || item.businessType === 0);
  if (!normal) return;
  const st = String(normal.startTime ?? "").trim();
  const et = String(normal.endTime ?? "").trim();
  form.normalBook.timeType = st === "00:00" && et === "00:00" ? "allDay" : "notAllDay";
}

/** 无预约数据时，修改「结束前不可预订」需同步更新「可预约结束时间」回显（与 echoBookableEndFromStoreEnd 一致） */
watch(
  () => form.booking.noBookMinutesBeforeClose,
  () => {
    const list = listBooking.value;
    if (Array.isArray(list) && list.length) return;
    const storeInfoList = listFromStoreInfo.value;
    const storeNormal = storeInfoList.find((item: any) => item.businessType === 1 || item.businessType === 0);
    if (!storeNormal) return;
    form.normalBook.endTime = echoBookableEndFromStoreEnd(storeNormal.endTime);
  }
);

function computePickerEndMinutes(endTimeRaw: string): number {
  const noBook = getNoBookMinutesForPicker();
  return timeStrToMinutes(subtractMinutesFromTime(endTimeRaw || "23:59", noBook));
}

/** 与商家端：正常营业时间选择器仅以 getStoreInfoBusinessHours（businessType=1）的 startTime、endTime 为可选范围 */
function getNormalWindowForPicker() {
  const store = (Array.isArray(listFromStoreInfo.value) ? listFromStoreInfo.value : []).find((x: any) => x.businessType === 1);
  let startTime = store?.startTime != null && String(store.startTime).trim() !== "" ? String(store.startTime).trim() : "00:00";
  let endTimeRaw = store?.endTime != null && String(store.endTime).trim() !== "" ? String(store.endTime).trim() : "23:59";
  if (startTime === "00:00" && endTimeRaw === "00:00") {
    endTimeRaw = "23:59";
  }
  return { startTime, endTimeRaw };
}

function getSpecialWindowForPicker(holidayName: string) {
  const n = String(holidayName || "").trim();
  const storeList = Array.isArray(listFromStoreInfo.value) ? listFromStoreInfo.value : [];
  const storeRow = storeList.find(
    (s: any) =>
      s.businessType === 2 &&
      ((s.holidayInfo && String(s.holidayInfo.festivalName || "").trim()) === n ||
        String(s.businessDate || "").trim() === n ||
        String(s.holidayType || "").trim() === n)
  );
  let startTime =
    storeRow?.startTime != null && String(storeRow.startTime).trim() !== "" ? String(storeRow.startTime).trim() : "00:00";
  let endTimeRaw =
    storeRow?.endTime != null && String(storeRow.endTime).trim() !== "" ? String(storeRow.endTime).trim() : "23:59";
  if (startTime === "00:00" && endTimeRaw === "00:00") {
    endTimeRaw = "23:59";
  }
  return { startTime, endTimeRaw };
}

function buildDisabledHours(sm: number, em: number): number[] {
  const arr: number[] = [];
  for (let h = 0; h < 24; h++) {
    const lo = h * 60;
    const hi = h * 60 + 59;
    if (hi < sm || lo > em) arr.push(h);
  }
  return arr;
}

function buildDisabledMinutes(hour: number, sm: number, em: number): number[] {
  const arr: number[] = [];
  const startH = Math.floor(sm / 60);
  const endH = Math.floor(em / 60);
  if (hour < startH || hour > endH) {
    return Array.from({ length: 60 }, (_, i) => i);
  }
  let minM = 0;
  let maxM = 59;
  if (startH === endH) {
    minM = sm % 60;
    maxM = em % 60;
  } else if (hour === startH) {
    minM = sm % 60;
  } else if (hour === endH) {
    maxM = em % 60;
  }
  for (let m = 0; m < 60; m++) {
    if (m < minM || m > maxM) arr.push(m);
  }
  return arr;
}

const normalStartPickSm = ref(0);
const normalStartPickEm = ref(23 * 60 + 59);
const normalEndPickSm = ref(0);
const normalEndPickEm = ref(23 * 60 + 59);
const specialPickSm = ref(0);
const specialPickEm = ref(23 * 60 + 59);

function initNormalStartPickerRange() {
  const { startTime, endTimeRaw } = getNormalWindowForPicker();
  let sm = timeStrToMinutes(startTime || "00:00");
  let em = computePickerEndMinutes(endTimeRaw);
  if (em < sm) em = 23 * 60 + 59;
  normalStartPickSm.value = sm;
  normalStartPickEm.value = em;
}

function initNormalEndPickerRange() {
  const { startTime, endTimeRaw } = getNormalWindowForPicker();
  let sm = timeStrToMinutes(startTime || "00:00");
  let em = computePickerEndMinutes(endTimeRaw);
  if (em < sm) em = 23 * 60 + 59;
  const stSel = timeStrToMinutes(form.normalBook.startTime || "00:00");
  sm = Math.max(sm, stSel);
  if (sm > em) em = sm;
  normalEndPickSm.value = sm;
  normalEndPickEm.value = em;
}

function initSpecialPickerRange(holidayName: string, key: "start" | "end") {
  const { startTime, endTimeRaw } = getSpecialWindowForPicker(holidayName);
  let sm = timeStrToMinutes(startTime || "00:00");
  let em = computePickerEndMinutes(endTimeRaw);
  if (em < sm) em = 23 * 60 + 59;
  if (key === "end") {
    const item = form.specialList.find(s => s.name === holidayName);
    const stSel = timeStrToMinutes(item?.startTime || "00:00");
    sm = Math.max(sm, stSel);
    if (sm > em) em = sm;
  }
  specialPickSm.value = sm;
  specialPickEm.value = em;
}

function normalStartDisabledHours() {
  return buildDisabledHours(normalStartPickSm.value, normalStartPickEm.value);
}
function normalStartDisabledMinutes(hour: number) {
  return buildDisabledMinutes(hour, normalStartPickSm.value, normalStartPickEm.value);
}
function normalEndDisabledHours() {
  return buildDisabledHours(normalEndPickSm.value, normalEndPickEm.value);
}
function normalEndDisabledMinutes(hour: number) {
  return buildDisabledMinutes(hour, normalEndPickSm.value, normalEndPickEm.value);
}
function specialDisabledHours() {
  return buildDisabledHours(specialPickSm.value, specialPickEm.value);
}
function specialDisabledMinutes(hour: number) {
  return buildDisabledMinutes(hour, specialPickSm.value, specialPickEm.value);
}

function onNormalStartTimeChange(val: string | null) {
  if (val == null || val === "") return;
  let vm = timeStrToMinutes(val);
  vm = Math.max(normalStartPickSm.value, Math.min(normalStartPickEm.value, vm));
  const s = minutesToTimeStr(vm);
  normalStartTimeValue.value = s;
  form.normalBook.startTime = s;
}

function onNormalEndTimeChange(val: string | null) {
  if (val == null || val === "") return;
  let vm = timeStrToMinutes(val);
  vm = Math.max(normalEndPickSm.value, Math.min(normalEndPickEm.value, vm));
  const s = minutesToTimeStr(vm);
  normalEndTimeValue.value = s;
  form.normalBook.endTime = s;
}

function onSpecialTimeChange(holidayName: string, key: "start" | "end") {
  const item = form.specialList.find(s => s.name === holidayName);
  if (!item) return;
  const field = key === "start" ? "startTime" : "endTime";
  const val = item[field];
  if (val == null || val === "") return;
  let vm = timeStrToMinutes(val);
  vm = Math.max(specialPickSm.value, Math.min(specialPickEm.value, vm));
  item[field] = minutesToTimeStr(vm);
}

/** 门店正常营业非 00:00–00:00 时不可选「全天」（与 merchant） */
const normalAllDayDisabled = computed(() => {
  const list = Array.isArray(listFromStoreInfo.value) ? listFromStoreInfo.value : [];
  const normal = list.find((item: any) => item.businessType === 1 || item.businessType === 0);
  if (!normal) return false;
  const st = String(normal.startTime || "").trim();
  const et = String(normal.endTime || "").trim();
  return st !== "00:00" || et !== "00:00";
});

/** 各节日门店配置非 00:00–00:00 时该行不可选「全天」 */
const specialAllDayDisabledMap = computed(() => {
  const list = Array.isArray(listFromStoreInfo.value) ? listFromStoreInfo.value : [];
  const map: Record<string, boolean> = {};
  list
    .filter((item: any) => item.businessType === 2)
    .forEach((s: any) => {
      const name = (s.holidayInfo && s.holidayInfo.festivalName) || s.businessDate || s.holidayType || "";
      if (name) {
        const st = String(s.startTime || "").trim();
        const et = String(s.endTime || "").trim();
        map[String(name)] = st !== "00:00" || et !== "00:00";
      }
    });
  return map;
});

async function loadHolidayOptions() {
  try {
    const year = new Date().getFullYear();
    const res: any = await getHolidayList({
      holidayName: "",
      openFlag: 1,
      year,
      page: 1,
      size: 100
    });
    const records = res?.data?.records ?? res?.records ?? [];
    holidayOptions.value = records
      .map((record: any) => ({
        name: record.festivalName ?? record.holidayName ?? record.name ?? ""
      }))
      .filter((x: { name: string }) => x.name);
  } catch {
    holidayOptions.value = [];
  }
}

async function fetchStoreInfoBusinessHours() {
  const storeId = getStoreId();
  if (!storeId) return;
  try {
    const res: any = await getStoreInfoBusinessHours({ id: storeId });
    const list = Array.isArray(res?.data) ? res.data : [];
    listFromStoreInfo.value = list;
    const normalStore = list.find((item: any) => item.businessType === 1 || item.businessType === 0);
    if (normalStore) {
      form.normalBook.normalId = Number(normalStore.id) || 0;
    }
    /** 与商家端：正常/特殊营业时间由 getBookingBusinessHours + applyListBookingToForm 统一回显 */
    form.specialList = [];
  } catch {
    listFromStoreInfo.value = [];
  }
}

/** 与 group_merchant scheduledService/infoManagement：listBooking + listFromStoreInfo 回显正常/特殊营业 */
function applyListBookingToForm() {
  const list = Array.isArray(listBooking.value) ? listBooking.value : [];
  const storeInfoList = Array.isArray(listFromStoreInfo.value) ? listFromStoreInfo.value : [];
  const specialFromStore = storeInfoList.filter((item: any) => item.businessType === 2);
  const specialFromBooking = list.filter((item: any) => item.businessType === 2);
  const bookingEmpty = !list.length;
  const useStoreInfoForSpecial = !list.length || !specialFromBooking.length;

  const bookingHolidayTypeSet = new Set(
    specialFromBooking.map((b: any) => (b.holidayType != null ? String(b.holidayType).trim() : "")).filter(Boolean)
  );

  const storeNormal = storeInfoList.find((item: any) => item.businessType === 1 || item.businessType === 0);

  /** 无预约配置：正常营业从门店营业时间回显，结束时间用 echoBookableEndFromStoreEnd（可预约结束） */
  if (!list.length) {
    if (storeNormal) {
      form.normalBook.startTime = String(storeNormal.startTime ?? "").trim();
      form.normalBook.endTime = echoBookableEndFromStoreEnd(storeNormal.endTime);
      form.normalBook.normalId = Number(storeNormal.id) || 0;
    } else {
      form.normalBook.startTime = "";
      form.normalBook.endTime = "";
    }
  } else {
    const normal = list.find((item: any) => item.businessType === 1 || item.businessType === 0);
    if (normal) {
      const st = normal.startTime || "";
      const et = normal.endTime || "23:59";
      form.normalBook.startTime = st;
      form.normalBook.endTime = et;
      form.normalBook.normalId = Number(normal.id) || 0;
    }
  }
  applyNormalTimeTypeFromStore();

  if (useStoreInfoForSpecial) {
    if (bookingEmpty) {
      form.specialList = [];
      return;
    }
    form.specialList = [];
    return;
  }

  /** 仅 getBookingBusinessHours 返回的 holidayType 对应项回显；特殊营业结束时间按接口原样，不减「结束前不可预订」 */
  form.specialList = specialFromStore.map((s: any, index: number) => {
    const name = (s.holidayInfo && s.holidayInfo.festivalName) || s.businessDate || s.holidayType || `特殊营业${index + 1}`;
    const storeFestivalName = (
      s.holidayInfo && s.holidayInfo.festivalName != null ? String(s.holidayInfo.festivalName) : ""
    ).trim();
    const shouldEchoTime = bookingHolidayTypeSet.has(storeFestivalName);
    const match = specialFromBooking.find(
      (b: any) =>
        String(b.id) === String(s.id) ||
        String(b.essentialId) === String(s.essentialId) ||
        (storeFestivalName !== "" && (b.holidayType != null ? String(b.holidayType) : "").trim() === storeFestivalName)
    );
    if (!match || !shouldEchoTime) {
      return {
        name,
        allDay: allDayFromStoreSpecialRow(s),
        startTime: "",
        endTime: "",
        id: s.id,
        essentialId: s.essentialId,
        userPickedSpecial: false
      };
    }
    const startTime = match.startTime || "";
    const endTimeRaw = match.endTime || "23:59";
    return {
      name,
      allDay: allDayFromStoreSpecialRow(s),
      startTime,
      endTime: endTimeRaw,
      id: s.id,
      essentialId: s.essentialId,
      userPickedSpecial: true
    };
  });
}

async function fetchBookingBusinessHours() {
  const settingsId = form.base.id;
  if (settingsId == null || settingsId === undefined) return;
  try {
    const res: any = await getBookingBusinessHours({ settingsId });
    const list = Array.isArray(res?.data) ? res.data : [];
    listBooking.value = list;
    applyListBookingToForm();
  } catch {
    listBooking.value = [];
  }
}

async function getInfoSettings() {
  const storeId = getStoreId();
  if (!storeId) return;
  try {
    const res: any = await bookingSettingsDetail({ storeId: Number(storeId) });
    const d = res?.data ?? res ?? {};
    form.base.id = d.id;
    form.base.keepPosition = d.retainPositionFlag === 1 ? "keep" : "notKeep";
    form.base.retentionMinutes = Number(d.retentionDuration) || 30;
    form.base.bookDateDays = Number(d.bookingDateDisplayDays) || 7;
    form.base.maxCapacityPerSlot = Number(d.maxCapacityPerSlot) || 10;

    form.booking.feeType = d.reservation === "1" ? "paid" : "free";
    form.booking.bookAmount = Number(d.reservationMoney) || 0;
    form.booking.refundAdvanceHours = Number(d.offUnsubscribeHours) || 24;
    form.booking.noBookMinutesBeforeClose = Number(d.bookingNotAvailableTime) || 30;
  } catch {
    // 无数据时使用默认值
  }
}

function validate(): boolean {
  if (form.base.keepPosition === "keep") {
    const n = Number(form.base.retentionMinutes);
    if (!n || n < 1 || n > 99) {
      ElMessage.warning("保留时长(分钟)为1-99的整数");
      return false;
    }
  }
  const bookDateNum = Number(form.base.bookDateDays);
  if (!bookDateNum || bookDateNum < 1 || bookDateNum > 99) {
    ElMessage.warning("预订日期显示(天)为1-99的整数");
    return false;
  }
  const maxCap = Number(form.base.maxCapacityPerSlot);
  if (!maxCap || maxCap < 1 || maxCap > 9999) {
    ElMessage.warning("单时段最大容纳人数为1-9999的整数");
    return false;
  }
  if (form.booking.feeType === "paid") {
    if (!Number(form.booking.bookAmount) || Number(form.booking.bookAmount) < 1 || Number(form.booking.bookAmount) > 999) {
      ElMessage.warning("预订金额(元)为1-999的整数");
      return false;
    }
    if (
      !Number(form.booking.refundAdvanceHours) ||
      Number(form.booking.refundAdvanceHours) < 1 ||
      Number(form.booking.refundAdvanceHours) > 999
    ) {
      ElMessage.warning("取消预订退费需提前(小时)为1-999的整数");
      return false;
    }
  }
  if (
    !Number(form.booking.noBookMinutesBeforeClose) ||
    Number(form.booking.noBookMinutesBeforeClose) < 1 ||
    Number(form.booking.noBookMinutesBeforeClose) > 999
  ) {
    ElMessage.warning("营业时间结束前多少分钟不可预订为1-999的整数");
    return false;
  }
  if (form.normalBook.timeType === "notAllDay") {
    if (!form.normalBook.startTime || !form.normalBook.endTime) {
      ElMessage.warning("请设置正常营业时间");
      return false;
    }
  }
  return true;
}

async function onSave() {
  if (!validate()) return;
  const storeId = getStoreId();
  if (!storeId) {
    ElMessage.warning("未找到门店信息");
    return;
  }

  saveLoading.value = true;
  try {
    const businessDate = listFromStoreInfo.value.find((item: any) => item.businessType === 1)?.businessDate;
    const specialListBuilt: any[] = [];
    let sort = 0;
    for (const cur of form.specialList) {
      if (!showSpecialRowTimeUI(cur)) continue;
      const isAllDay = cur.allDay === "allDay";
      const st = (cur.startTime || "").trim();
      const et = (cur.endTime || "").trim();
      if (!isAllDay && !st && !et) continue;
      specialListBuilt.push({
        bookingTimeType: isAllDay ? 1 : 0,
        businessType: 2,
        holidayType: cur.name || "",
        startTime: cur.startTime || "00:00",
        endTime: cur.endTime || "00:00",
        sort: sort++,
        essentialId: cur.essentialId
      });
    }
    const params: Record<string, any> = {
      storeId: Number(storeId),
      retainPositionFlag: form.base.keepPosition === "keep" ? 1 : 0,
      retentionDuration: Number(form.base.retentionMinutes) || 0,
      bookingDateDisplayDays: Number(form.base.bookDateDays) || 0,
      maxCapacityPerSlot: Number(form.base.maxCapacityPerSlot) || 0,
      reservation: form.booking.feeType === "free" ? "0" : "1",
      reservationMoney: form.booking.feeType === "paid" ? Number(form.booking.bookAmount) || 0 : 0,
      offUnsubscribeHours: Number(form.booking.refundAdvanceHours) || 0,
      bookingNotAvailableTime: Number(form.booking.noBookMinutesBeforeClose) || 0,
      normalBusinessHours: {
        businessType: 1,
        holidayType: businessDate,
        bookingTimeType: form.normalBook.timeType === "allDay" ? 1 : 0,
        startTime: form.normalBook.startTime || "",
        endTime: form.normalBook.endTime || ""
      }
    };
    if (specialListBuilt.length > 0) {
      params.specialBusinessHoursList = specialListBuilt;
    }
    await bookingSettingsSave(params);
    ElMessage.success("保存成功");
  } catch (e: any) {
    ElMessage.error(e?.message || "保存失败");
  } finally {
    saveLoading.value = false;
  }
}

onMounted(async () => {
  await loadHolidayOptions();
  await getInfoSettings();
  await fetchStoreInfoBusinessHours();
  await fetchBookingBusinessHours();
});
</script>

<style scoped lang="scss">
.info-management {
  max-width: 100%;
  padding: 16px 20px 80px;
  margin: 0 auto;
}
.page-title {
  margin-bottom: 20px;
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}
.form-card {
  padding: 20px 24px;
  margin-bottom: 16px;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0 1px 4px rgb(0 0 0 / 6%);
}
.section-title {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
  font-size: 15px;
  font-weight: 600;
  color: #303133;
  .section-bar {
    width: 4px;
    height: 16px;
    margin-right: 10px;
    background: #6c8ff8;
    border-radius: 2px;
  }
}
.section-form {
  :deep(.el-form-item) {
    margin-bottom: 18px;
  }
  :deep(.el-form-item__label) {
    align-items: center;
    font-weight: 400;
    line-height: 20px;
    color: #606266;
  }
}
.form-input {
  width: 40%;
  max-width: 100%;
}
.time-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  .time-tip {
    margin-left: 4px;
    color: #909399;
  }
}
.special-time-row {
  padding-left: 0;
  margin-bottom: 12px;
  margin-left: 0;
  .info-icon {
    margin-left: 6px;
    color: #909399;
    vertical-align: middle;
  }
  .next-day-tag {
    margin-left: 8px;
    font-size: 12px;
    color: #909399;
  }
}
.footer-actions {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  padding: 12px 20px;
  background: #ffffff;
  box-shadow: 0 -1px 4px rgb(0 0 0 / 6%);
  .el-button {
    display: block;
    width: 100%;
    max-width: 720px;
    margin: 0 auto;
  }
}
</style>
