/**
 * 添加时段抽屉动作：
 * - 表单字段更新
 * - 快捷选星期
 * - 提交时段并做冲突校验
 */
import type { Ref } from 'vue';

import type { AddDaysMode, AddSlotFormState, DayName } from '../../types';

import type { DayHoursDto, TimeSlotDto } from '#/api/store-hours';

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

import { SlotType } from '#/api/store-hours';

interface CreateAddSlotActionsOptions {
  addSlotForm: AddSlotFormState;
  cloneWeeklyHours: (source: DayHoursDto[]) => DayHoursDto[];
  createSlotId: () => string;
  defaultDayName: DayName;
  dayNames: DayName[];
  isAddDrawerOpen: Ref<boolean>;
  persistWeeklyHours: (
    nextWeekly: DayHoursDto[],
    successText: string,
  ) => Promise<boolean>;
  selectedStoreId: Ref<string>;
  sortSlots: (slots: TimeSlotDto[]) => TimeSlotDto[];
  validateDaySlots: (slots: TimeSlotDto[]) => null | string;
  validateSlot: (slot: TimeSlotDto) => null | string;
  weeklyHours: Ref<DayHoursDto[]>;
}

export function createAddSlotActions(options: CreateAddSlotActionsOptions) {
  // 1. 表单字段 setter。
  function setAddSlotType(type: SlotType) {
    options.addSlotForm.type = type;
  }

  function setAddSlotStartTime(value: string) {
    options.addSlotForm.startTime = value;
  }

  function setAddSlotEndTime(value: string) {
    options.addSlotForm.endTime = value;
  }

  function setAddSlotCapacity(value: number) {
    options.addSlotForm.capacity = Math.max(0, Number(value) || 0);
  }

  function setAddSlotRemark(value: string) {
    options.addSlotForm.remark = value;
  }

  // 2. 抽屉初始化与星期选择。
  function resetAddSlotForm() {
    options.addSlotForm.type = SlotType.Business;
    options.addSlotForm.selectedDays = [0, 1, 2, 3, 4];
    options.addSlotForm.startTime = '09:00';
    options.addSlotForm.endTime = '22:00';
    options.addSlotForm.capacity = 50;
    options.addSlotForm.remark = '';
  }

  function openAddSlotDrawer() {
    resetAddSlotForm();
    options.isAddDrawerOpen.value = true;
  }

  function isAddDaySelected(dayOfWeek: number) {
    return options.addSlotForm.selectedDays.includes(dayOfWeek);
  }

  function toggleAddDay(dayOfWeek: number) {
    const existed = options.addSlotForm.selectedDays.includes(dayOfWeek);
    options.addSlotForm.selectedDays = existed
      ? options.addSlotForm.selectedDays.filter((item) => item !== dayOfWeek)
      : [...options.addSlotForm.selectedDays, dayOfWeek].toSorted(
          (a, b) => a - b,
        );
  }

  function quickSelectAddDays(mode: AddDaysMode) {
    if (mode === 'all') {
      options.addSlotForm.selectedDays = [0, 1, 2, 3, 4, 5, 6];
      return;
    }
    if (mode === 'weekday') {
      options.addSlotForm.selectedDays = [0, 1, 2, 3, 4];
      return;
    }
    options.addSlotForm.selectedDays = [5, 6];
  }

  // 3. 提交前校验并持久化。
  async function handleAddSlotSubmit() {
    if (!options.selectedStoreId.value) return;

    if (options.addSlotForm.selectedDays.length === 0) {
      message.error('请至少选择一个适用星期');
      return;
    }

    const nextType = Number(options.addSlotForm.type) as SlotType;
    const slotTemplate: TimeSlotDto = {
      id: options.createSlotId(),
      type: nextType,
      startTime: options.addSlotForm.startTime,
      endTime: options.addSlotForm.endTime,
      capacity:
        nextType === SlotType.Delivery
          ? Number(options.addSlotForm.capacity)
          : undefined,
      remark: options.addSlotForm.remark.trim() || undefined,
    };

    const slotError = options.validateSlot(slotTemplate);
    if (slotError) {
      message.error(slotError);
      return;
    }

    const nextWeekly = options.cloneWeeklyHours(options.weeklyHours.value);
    for (const dayOfWeek of options.addSlotForm.selectedDays) {
      const day = nextWeekly[dayOfWeek];
      if (!day) continue;

      day.isOpen = true;
      day.slots = options.sortSlots([
        ...day.slots,
        {
          ...slotTemplate,
          id: options.createSlotId(),
        },
      ]);

      const dayError = options.validateDaySlots(day.slots);
      if (dayError) {
        const dayMeta = options.dayNames[dayOfWeek] ?? options.defaultDayName;
        message.error(`${dayMeta.label}${dayError}`);
        return;
      }
    }

    const saved = await options.persistWeeklyHours(nextWeekly, '添加时段成功');
    if (saved) {
      options.isAddDrawerOpen.value = false;
    }
  }

  return {
    handleAddSlotSubmit,
    isAddDaySelected,
    openAddSlotDrawer,
    quickSelectAddDays,
    setAddSlotCapacity,
    setAddSlotEndTime,
    setAddSlotRemark,
    setAddSlotStartTime,
    setAddSlotType,
    toggleAddDay,
  };
}
