import type { Ref } from 'vue';

/**
 * 文件职责：大时段模式动作。
 * 1. 管理新增/编辑抽屉与表单状态。
 * 2. 处理时段新增、编辑、删除、启用切换。
 */
import type { PickupSlotDto, PickupWeekDay } from '#/api/store-pickup';
import type {
  PickupDrawerMode,
  PickupSlotFormState,
} from '#/views/store/pickup/types';

import { message } from 'ant-design-vue';

import { ALL_WEEK_DAYS, WEEKDAY_ONLY, WEEKEND_ONLY } from './constants';
import { sortSlots, validateSlotForm } from './helpers';

interface CreateSlotActionsOptions {
  bigSlots: Ref<PickupSlotDto[]>;
  createSlotId: () => string;
  isSlotDrawerOpen: Ref<boolean>;
  saveBigSlots: () => Promise<void>;
  slotDrawerMode: Ref<PickupDrawerMode>;
  slotForm: PickupSlotFormState;
}

export function createSlotActions(options: CreateSlotActionsOptions) {
  /** 打开新增/编辑抽屉并初始化表单。 */
  function openSlotDrawer(mode: PickupDrawerMode, slot?: PickupSlotDto) {
    options.slotDrawerMode.value = mode;
    if (mode === 'edit' && slot) {
      options.slotForm.id = slot.id;
      options.slotForm.name = slot.name;
      options.slotForm.startTime = slot.startTime;
      options.slotForm.endTime = slot.endTime;
      options.slotForm.cutoffMinutes = slot.cutoffMinutes;
      options.slotForm.capacity = slot.capacity;
      options.slotForm.dayOfWeeks = [...slot.dayOfWeeks];
      options.slotForm.enabled = slot.enabled;
      options.isSlotDrawerOpen.value = true;
      return;
    }

    options.slotForm.id = '';
    options.slotForm.name = '';
    options.slotForm.startTime = '09:00';
    options.slotForm.endTime = '17:00';
    options.slotForm.cutoffMinutes = 30;
    options.slotForm.capacity = 20;
    options.slotForm.dayOfWeeks = [...WEEKDAY_ONLY];
    options.slotForm.enabled = true;
    options.isSlotDrawerOpen.value = true;
  }

  /** 控制抽屉可见性。 */
  function setSlotDrawerOpen(value: boolean) {
    options.isSlotDrawerOpen.value = value;
  }

  function setSlotName(value: string) {
    options.slotForm.name = value;
  }

  function setSlotStartTime(value: string) {
    options.slotForm.startTime = value;
  }

  function setSlotEndTime(value: string) {
    options.slotForm.endTime = value;
  }

  function setSlotCutoffMinutes(value: number) {
    options.slotForm.cutoffMinutes = Math.max(
      0,
      Math.floor(Number(value || 0)),
    );
  }

  function setSlotCapacity(value: number) {
    options.slotForm.capacity = Math.max(0, Math.floor(Number(value || 0)));
  }

  function setSlotEnabled(value: boolean) {
    options.slotForm.enabled = Boolean(value);
  }

  function isSlotDaySelected(day: PickupWeekDay) {
    return options.slotForm.dayOfWeeks.includes(day);
  }

  function toggleSlotDay(day: PickupWeekDay) {
    options.slotForm.dayOfWeeks = options.slotForm.dayOfWeeks.includes(day)
      ? options.slotForm.dayOfWeeks.filter((item) => item !== day)
      : [...options.slotForm.dayOfWeeks, day].toSorted((a, b) => a - b);
  }

  function quickSelectSlotDays(mode: 'all' | 'weekday' | 'weekend') {
    if (mode === 'all') {
      options.slotForm.dayOfWeeks = [...ALL_WEEK_DAYS];
      return;
    }
    if (mode === 'weekday') {
      options.slotForm.dayOfWeeks = [...WEEKDAY_ONLY];
      return;
    }
    options.slotForm.dayOfWeeks = [...WEEKEND_ONLY];
  }

  /** 提交新增/编辑并持久化时段列表。 */
  async function handleSubmitSlot() {
    // 1. 校验表单合法性。
    const validateMessage = validateSlotForm({
      slotId: options.slotForm.id,
      slots: options.bigSlots.value,
      name: options.slotForm.name,
      startTime: options.slotForm.startTime,
      endTime: options.slotForm.endTime,
      dayOfWeeks: options.slotForm.dayOfWeeks,
      cutoffMinutes: options.slotForm.cutoffMinutes,
      capacity: options.slotForm.capacity,
    });
    if (validateMessage) {
      message.error(validateMessage);
      return;
    }

    // 2. 写回列表并排序。
    const nextRecord: PickupSlotDto = {
      id: options.slotForm.id || options.createSlotId(),
      name: options.slotForm.name.trim(),
      startTime: options.slotForm.startTime,
      endTime: options.slotForm.endTime,
      cutoffMinutes: options.slotForm.cutoffMinutes,
      capacity: options.slotForm.capacity,
      dayOfWeeks: [...options.slotForm.dayOfWeeks].toSorted((a, b) => a - b),
      enabled: options.slotForm.enabled,
      reservedCount: 0,
    };

    options.bigSlots.value =
      options.slotDrawerMode.value === 'edit' && options.slotForm.id
        ? sortSlots(
            options.bigSlots.value.map((item) =>
              item.id === options.slotForm.id
                ? { ...item, ...nextRecord, reservedCount: item.reservedCount }
                : item,
            ),
          )
        : sortSlots([...options.bigSlots.value, nextRecord]);

    // 3. 持久化并关闭抽屉。
    await options.saveBigSlots();
    options.isSlotDrawerOpen.value = false;
  }

  /** 删除时段并持久化。 */
  async function handleDeleteSlot(slotId: string) {
    options.bigSlots.value = options.bigSlots.value.filter(
      (item) => item.id !== slotId,
    );
    await options.saveBigSlots();
  }

  /** 切换时段启用状态并持久化。 */
  async function handleToggleSlotEnabled(slotId: string, enabled: boolean) {
    options.bigSlots.value = options.bigSlots.value.map((item) =>
      item.id === slotId ? { ...item, enabled } : item,
    );
    await options.saveBigSlots();
  }

  return {
    handleDeleteSlot,
    handleSubmitSlot,
    handleToggleSlotEnabled,
    isSlotDaySelected,
    openSlotDrawer,
    quickSelectSlotDays,
    setSlotCapacity,
    setSlotCutoffMinutes,
    setSlotDrawerOpen,
    setSlotEnabled,
    setSlotEndTime,
    setSlotName,
    setSlotStartTime,
    toggleSlotDay,
  };
}
