import type { Ref } from 'vue';

/**
 * 文件职责：精细规则动作。
 * 1. 管理精细规则字段与适用星期选择。
 * 2. 处理规则校验与保存提交流程。
 */
import type { PickupFineRuleDto, PickupWeekDay } from '#/api/store-pickup';

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

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

interface CreateFineRuleActionsOptions {
  fineRule: PickupFineRuleDto;
  saveFineRule: () => Promise<void>;
  selectedPreviewDate: Ref<string>;
}

export function createFineRuleActions(options: CreateFineRuleActionsOptions) {
  function setFineIntervalMinutes(value: number) {
    options.fineRule.intervalMinutes = Math.max(
      5,
      Math.floor(Number(value || 5)),
    );
  }

  function setFineSlotCapacity(value: number) {
    options.fineRule.slotCapacity = Math.max(1, Math.floor(Number(value || 1)));
  }

  function setFineDayStartTime(value: string) {
    options.fineRule.dayStartTime = value;
  }

  function setFineDayEndTime(value: string) {
    options.fineRule.dayEndTime = value;
  }

  function setFineMinAdvanceHours(value: number) {
    options.fineRule.minAdvanceHours = Math.max(
      0,
      Math.floor(Number(value || 0)),
    );
  }

  function isFineDaySelected(day: PickupWeekDay) {
    return options.fineRule.dayOfWeeks.includes(day);
  }

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

  function quickSelectFineDays(mode: 'all' | 'weekday' | 'weekend') {
    if (mode === 'all') {
      options.fineRule.dayOfWeeks = [...ALL_WEEK_DAYS];
    } else if (mode === 'weekday') {
      options.fineRule.dayOfWeeks = [...WEEKDAY_ONLY];
    } else {
      options.fineRule.dayOfWeeks = [...WEEKEND_ONLY];
    }
  }

  function setSelectedPreviewDate(date: string) {
    options.selectedPreviewDate.value = date;
  }

  /** 校验精细规则并提交保存。 */
  async function handleSaveFineRule() {
    // 1. 核心字段校验。
    if (options.fineRule.dayOfWeeks.length === 0) {
      message.error('请至少选择一个适用星期');
      return;
    }
    if (options.fineRule.slotCapacity <= 0) {
      message.error('每个时段容量必须大于 0');
      return;
    }
    if (options.fineRule.intervalMinutes <= 0) {
      message.error('时间间隔必须大于 0');
      return;
    }

    const start = parseTimeToMinutes(options.fineRule.dayStartTime);
    const end = parseTimeToMinutes(options.fineRule.dayEndTime);
    if (!Number.isFinite(start) || !Number.isFinite(end) || end <= start) {
      message.error('每日结束时间必须晚于开始时间');
      return;
    }

    // 2. 提交保存。
    await options.saveFineRule();
  }

  return {
    handleSaveFineRule,
    isFineDaySelected,
    quickSelectFineDays,
    setFineDayEndTime,
    setFineDayStartTime,
    setFineIntervalMinutes,
    setFineMinAdvanceHours,
    setFineSlotCapacity,
    setSelectedPreviewDate,
    toggleFineDay,
  };
}
