/**
 * 单日时段编辑动作：
 * - 打开日编辑抽屉
 * - 编辑/删除时段行
 * - 保存当日配置
 */
import type { ComputedRef, Ref } from 'vue';

import type { DayEditFormState, DayName, EditSlotItem } from '../../types';

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

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

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

interface CreateDayEditActionsOptions {
  cloneWeeklyHours: (source: DayHoursDto[]) => DayHoursDto[];
  createSlotId: () => string;
  currentDayMeta: ComputedRef<DayName>;
  dayEditForm: DayEditFormState;
  isDayDrawerOpen: Ref<boolean>;
  normalizeWeeklyHours: (source: DayHoursDto[]) => DayHoursDto[];
  persistWeeklyHours: (
    nextWeekly: DayHoursDto[],
    successText: string,
  ) => Promise<boolean>;
  selectedStoreId: Ref<string>;
  sortSlots: (slots: TimeSlotDto[]) => TimeSlotDto[];
  validateDaySlots: (slots: TimeSlotDto[]) => null | string;
  weeklyHours: Ref<DayHoursDto[]>;
}

export function createDayEditActions(options: CreateDayEditActionsOptions) {
  // 1. 抽屉初始化与行增删。
  function openDayDrawer(dayOfWeek: number) {
    const source = options.normalizeWeeklyHours(options.weeklyHours.value)[
      dayOfWeek
    ];
    if (!source) return;

    options.dayEditForm.dayOfWeek = dayOfWeek;
    options.dayEditForm.isOpen = source.isOpen;
    options.dayEditForm.slots = source.slots.map(
      (slot): EditSlotItem => ({
        id: slot.id || options.createSlotId(),
        type: Number(slot.type) as SlotType,
        startTime: slot.startTime,
        endTime: slot.endTime,
        capacity:
          Number(slot.type) === SlotType.Delivery
            ? Number(slot.capacity ?? 50)
            : undefined,
        remark: slot.remark || '',
      }),
    );
    options.isDayDrawerOpen.value = true;
  }

  function addDaySlotRow() {
    options.dayEditForm.slots = [
      ...options.dayEditForm.slots,
      {
        id: options.createSlotId(),
        type: SlotType.Business,
        startTime: '09:00',
        endTime: '22:00',
        remark: '',
      },
    ];
  }

  function removeDaySlot(slotId: string) {
    options.dayEditForm.slots = options.dayEditForm.slots.filter(
      (slot) => slot.id !== slotId,
    );
  }

  // 2. 表单字段 setter。
  function setDayEditOpen(value: boolean) {
    options.dayEditForm.isOpen = value;
  }

  function updateDaySlot(
    slotId: string,
    updater: (slot: EditSlotItem) => void,
  ) {
    const target = options.dayEditForm.slots.find((slot) => slot.id === slotId);
    if (!target) return;
    updater(target);
  }

  function setDaySlotType(slotId: string, value: SlotType) {
    updateDaySlot(slotId, (slot) => {
      slot.type = value;
      if (value !== SlotType.Delivery) {
        slot.capacity = undefined;
      } else if (!slot.capacity || slot.capacity <= 0) {
        slot.capacity = 50;
      }
    });
  }

  function setDaySlotStartTime(slotId: string, value: string) {
    updateDaySlot(slotId, (slot) => {
      slot.startTime = value;
    });
  }

  function setDaySlotEndTime(slotId: string, value: string) {
    updateDaySlot(slotId, (slot) => {
      slot.endTime = value;
    });
  }

  function setDaySlotCapacity(slotId: string, value: number) {
    updateDaySlot(slotId, (slot) => {
      slot.capacity = Math.max(0, Number(value) || 0);
    });
  }

  // 3. 保存前校验并持久化。
  async function handleSaveDay() {
    if (!options.selectedStoreId.value) return;

    if (options.dayEditForm.isOpen && options.dayEditForm.slots.length === 0) {
      message.error('该日营业已开启，至少保留一个时段');
      return;
    }

    const nextSlots: TimeSlotDto[] = options.dayEditForm.slots.map((slot) => {
      const slotType = Number(slot.type) as SlotType;
      return {
        id: slot.id || options.createSlotId(),
        type: slotType,
        startTime: slot.startTime,
        endTime: slot.endTime,
        capacity:
          slotType === SlotType.Delivery ? Number(slot.capacity) : undefined,
        remark: slot.remark?.trim() || undefined,
      };
    });

    if (options.dayEditForm.isOpen) {
      const dayError = options.validateDaySlots(nextSlots);
      if (dayError) {
        message.error(`${options.currentDayMeta.value.label}${dayError}`);
        return;
      }
    }

    const nextWeekly = options.cloneWeeklyHours(options.weeklyHours.value);
    nextWeekly[options.dayEditForm.dayOfWeek] = {
      dayOfWeek: options.dayEditForm.dayOfWeek,
      isOpen: options.dayEditForm.isOpen,
      slots: options.sortSlots(nextSlots),
    };

    const saved = await options.persistWeeklyHours(
      nextWeekly,
      '营业时间已更新',
    );
    if (saved) {
      options.isDayDrawerOpen.value = false;
    }
  }

  return {
    addDaySlotRow,
    handleSaveDay,
    openDayDrawer,
    removeDaySlot,
    setDayEditOpen,
    setDaySlotCapacity,
    setDaySlotEndTime,
    setDaySlotStartTime,
    setDaySlotType,
  };
}
