/**
 * 文件职责：员工排班页面主编排。
 * 1. 维护门店、员工、模板、排班、抽屉与复制弹窗状态。
 * 2. 组装数据加载、员工管理、模板编辑、排班编辑、复制动作。
 * 3. 对视图层暴露可直接绑定的状态与方法。
 */
import type { StoreListItemDto } from '#/api/store';
import type {
  ShiftType,
  StaffDayShiftDto,
  StaffRoleType,
  StaffStatus,
  StoreShiftTemplatesDto,
  StoreStaffDto,
} from '#/api/store-staff';
import type {
  ShiftLegendItem,
  StaffDrawerMode,
  StaffEditorFormState,
  StaffFilterState,
  StaffPersonalScheduleFormState,
  WeekEditorRow,
} from '#/views/store/staff/types';

import { computed, onActivated, onMounted, reactive, ref, watch } from 'vue';

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

import {
  DAY_OPTIONS,
  DEFAULT_FILTER_STATE,
  DEFAULT_STAFF_FORM,
  EMPTY_SHIFT_TEMPLATES,
  PAGE_SIZE_OPTIONS,
  SHIFT_OPTIONS,
  STAFF_PERMISSION_OPTIONS,
  STAFF_ROLE_OPTIONS,
  STAFF_STATUS_OPTIONS,
} from './staff-page/constants';
import { createCopyActions } from './staff-page/copy-actions';
import { createDataActions } from './staff-page/data-actions';
import {
  cloneFilterState,
  cloneShifts,
  cloneStaffForm,
  cloneTemplates,
  formatShiftTimeText,
  getCurrentWeekStartDate,
  maskPhone,
  resolveAvatarText,
} from './staff-page/helpers';
import { createScheduleActions } from './staff-page/schedule-actions';
import { createStaffActions } from './staff-page/staff-actions';
import { createTemplateActions } from './staff-page/template-actions';

export function useStoreStaffPage() {
  // 1. 页面 loading / submitting 状态。
  const isStoreLoading = ref(false);
  const isPageLoading = ref(false);
  const isStaffSaving = ref(false);
  const isTemplateSaving = ref(false);
  const isPersonalSaving = ref(false);
  const isWeekSaving = ref(false);
  const isCopySubmitting = ref(false);
  const deletingStaffId = ref('');

  // 2. 页面核心业务数据。
  const stores = ref<StoreListItemDto[]>([]);
  const selectedStoreId = ref('');

  const filters = reactive<StaffFilterState>(
    cloneFilterState(DEFAULT_FILTER_STATE),
  );

  const staffRows = ref<StoreStaffDto[]>([]);
  const staffTotal = ref(0);
  const staffDirectory = ref<StoreStaffDto[]>([]);
  const isTemplateConfigured = ref(false);
  const isScheduleConfigured = ref(false);

  const templates = ref<StoreShiftTemplatesDto>(
    cloneTemplates(EMPTY_SHIFT_TEMPLATES),
  );
  const scheduleMap = ref<Record<string, StaffDayShiftDto[]>>({});
  const scheduleSnapshot = ref<null | {
    scheduleMap: Record<string, StaffDayShiftDto[]>;
    templates: StoreShiftTemplatesDto;
  }>(null);

  // 3. 抽屉与弹窗状态。
  const isStaffDrawerOpen = ref(false);
  const staffDrawerMode = ref<StaffDrawerMode>('create');
  const staffForm = reactive<StaffEditorFormState>(
    cloneStaffForm(DEFAULT_STAFF_FORM),
  );

  const isPersonalDrawerOpen = ref(false);
  const personalScheduleForm = reactive<StaffPersonalScheduleFormState>({
    staffId: '',
    staffName: '',
    roleType: 'cashier',
    shifts: [],
  });

  const isWeekDrawerOpen = ref(false);
  const weekRows = ref<WeekEditorRow[]>([]);

  const isCopyModalOpen = ref(false);
  const copyTargetStoreIds = ref<string[]>([]);

  // 4. 页面衍生数据。
  const storeOptions = computed(() =>
    stores.value.map((item) => ({ label: item.name, value: item.id })),
  );

  const selectedStoreName = computed(
    () =>
      stores.value.find((item) => item.id === selectedStoreId.value)?.name ??
      '',
  );

  const copyCandidates = computed(() =>
    stores.value.filter((item) => item.id !== selectedStoreId.value),
  );

  const isCopyAllChecked = computed(
    () =>
      copyCandidates.value.length > 0 &&
      copyTargetStoreIds.value.length === copyCandidates.value.length,
  );

  const isCopyIndeterminate = computed(
    () =>
      copyTargetStoreIds.value.length > 0 &&
      copyTargetStoreIds.value.length < copyCandidates.value.length,
  );

  const roleOptionMap = computed(() => {
    const map = new Map<StaffRoleType, (typeof STAFF_ROLE_OPTIONS)[number]>();
    for (const option of STAFF_ROLE_OPTIONS) {
      map.set(option.value, option);
    }
    return map;
  });

  const statusOptionMap = computed(() => {
    const map = new Map<StaffStatus, (typeof STAFF_STATUS_OPTIONS)[number]>();
    for (const option of STAFF_STATUS_OPTIONS) {
      map.set(option.value, option);
    }
    return map;
  });

  const shiftOptionMap = computed(() => {
    const map = new Map<ShiftType, (typeof SHIFT_OPTIONS)[number]>();
    for (const option of SHIFT_OPTIONS) {
      map.set(option.value, option);
    }
    return map;
  });

  const staffDrawerTitle = computed(() =>
    staffDrawerMode.value === 'edit'
      ? `编辑员工${staffForm.name ? ` - ${staffForm.name}` : ''}`
      : '添加员工',
  );

  const staffSubmitText = computed(() =>
    staffDrawerMode.value === 'edit' ? '保存修改' : '确认添加',
  );

  const personalDrawerTitle = computed(() => {
    if (!personalScheduleForm.staffName) return '编辑排班';
    return `编辑排班 - ${personalScheduleForm.staffName}`;
  });

  const boardRows = computed(() => {
    const visibleStaffs = staffDirectory.value.filter(
      (item) => item.status !== 'resigned',
    );

    return visibleStaffs.map((staff) => ({
      staffId: staff.id,
      staffName: staff.name,
      roleType: staff.roleType,
      status: staff.status,
      shifts: cloneShifts(scheduleMap.value[staff.id] ?? []),
    }));
  });

  const shiftLegendItems = computed<ShiftLegendItem[]>(() => {
    return SHIFT_OPTIONS.filter((item) => item.value !== 'off').map((item) => {
      const template = templates.value[item.value as Exclude<ShiftType, 'off'>];
      return {
        type: item.value as Exclude<ShiftType, 'off'>,
        label: item.label,
        className: item.className,
        timeText:
          template.startTime && template.endTime
            ? `${template.startTime}-${template.endTime}`
            : '未配置',
      };
    });
  });

  // 5. 数据动作装配。
  const {
    clearStoreData,
    loadScheduleSettings,
    loadStaffPage,
    loadStores,
    patchScheduleMap,
    patchStaffSchedule,
    patchTemplates,
    reloadStoreData,
  } = createDataActions({
    filters,
    isScheduleConfigured,
    isTemplateConfigured,
    isPageLoading,
    isStoreLoading,
    scheduleMap,
    scheduleSnapshot,
    selectedStoreId,
    staffDirectory,
    staffRows,
    staffTotal,
    stores,
    templates,
  });

  const {
    handleDeleteStaff,
    handleSubmitStaff,
    openStaffDrawer,
    setStaffEmail,
    setStaffName,
    setStaffPermissions,
    setStaffPhone,
    setStaffRoleType,
    setStaffStatus,
  } = createStaffActions({
    deletingStaffId,
    isStaffSaving,
    isStaffDrawerOpen,
    reloadStoreData,
    selectedStoreId,
    staffDrawerMode,
    staffForm,
  });

  const { handleSaveTemplates, resetTemplates, setTemplateTime } =
    createTemplateActions({
      isTemplateSaving,
      loadScheduleSettings,
      patchTemplates,
      scheduleSnapshot,
      selectedStoreId,
      templates,
    });

  const {
    cycleWeekShift,
    handleSavePersonalSchedule,
    handleSaveWeekSchedule,
    openPersonalScheduleDrawer,
    openWeekScheduleDrawer,
    setPersonalShiftEnd,
    setPersonalShiftStart,
    setPersonalShiftType,
  } = createScheduleActions({
    isPersonalDrawerOpen,
    isPersonalSaving,
    isWeekDrawerOpen,
    isWeekSaving,
    loadScheduleSettings,
    patchScheduleMap,
    patchStaffSchedule,
    personalForm: personalScheduleForm,
    scheduleMap,
    selectedStoreId,
    staffDirectory,
    templates,
    weekRows,
  });

  const {
    handleCopyCheckAll,
    handleCopySubmit,
    openCopyModal,
    toggleCopyStore,
  } = createCopyActions({
    copyCandidates,
    copyTargetStoreIds,
    isCopyModalOpen,
    isCopySubmitting,
    selectedStoreId,
  });

  // 6. 页面交互方法。
  function setSelectedStoreId(value: string) {
    selectedStoreId.value = value;
  }

  function setFilterKeyword(value: string) {
    filters.keyword = value;
  }

  function setFilterRoleType(value: '' | StaffRoleType) {
    filters.roleType = value;
  }

  function setFilterStatus(value: '' | StaffStatus) {
    filters.status = value;
  }

  /** 应用筛选条件后重新查询列表。 */
  async function applyFilters() {
    filters.page = 1;
    await loadStaffPage();
  }

  /** 重置筛选并重新查询列表。 */
  async function resetFilters() {
    filters.keyword = '';
    filters.roleType = '';
    filters.status = '';
    filters.page = 1;
    await loadStaffPage();
  }

  /** 切换分页。 */
  async function handlePageChange(payload: { page: number; pageSize: number }) {
    filters.page = payload.page;
    filters.pageSize = payload.pageSize;
    await loadStaffPage();
  }

  function setStaffDrawerOpen(value: boolean) {
    isStaffDrawerOpen.value = value;
  }

  function setPersonalDrawerOpen(value: boolean) {
    isPersonalDrawerOpen.value = value;
  }

  function setWeekDrawerOpen(value: boolean) {
    isWeekDrawerOpen.value = value;
  }

  function setCopyModalOpen(value: boolean) {
    isCopyModalOpen.value = value;
  }

  /** 判断员工是否可进入排班。 */
  function isScheduleDisabled(staff: StoreStaffDto) {
    return staff.status === 'resigned' || !isTemplateConfigured.value;
  }

  /** 打开个人排班抽屉。 */
  function handleOpenPersonalSchedule(staff: StoreStaffDto) {
    if (isScheduleDisabled(staff)) return;
    openPersonalScheduleDrawer(staff);
  }

  /** 打开周排班抽屉。 */
  function handleOpenWeekSchedule() {
    if (!isTemplateConfigured.value) {
      message.warning('请先配置班次模板，再编辑排班');
      return;
    }
    openWeekScheduleDrawer();
  }

  /** 获取角色展示文案。 */
  function getRoleLabel(roleType: StaffRoleType) {
    return roleOptionMap.value.get(roleType)?.label ?? roleType;
  }

  /** 获取角色标签样式类。 */
  function getRoleTagClass(roleType: StaffRoleType) {
    return roleOptionMap.value.get(roleType)?.tagClassName ?? 'role-cashier';
  }

  /** 获取状态展示文案。 */
  function getStatusLabel(status: StaffStatus) {
    return statusOptionMap.value.get(status)?.label ?? status;
  }

  /** 获取状态圆点样式类。 */
  function getStatusDotClass(status: StaffStatus) {
    return (
      statusOptionMap.value.get(status)?.dotClassName ?? 'status-dot-active'
    );
  }

  /** 获取班次文案。 */
  function getShiftLabel(shiftType: ShiftType) {
    return shiftOptionMap.value.get(shiftType)?.label ?? shiftType;
  }

  /** 获取班次样式类。 */
  function getShiftClass(shiftType: ShiftType) {
    return shiftOptionMap.value.get(shiftType)?.className ?? 'shift-off';
  }

  // 7. 监听门店切换。
  watch(selectedStoreId, async (storeId) => {
    if (!storeId) {
      clearStoreData();
      return;
    }

    filters.page = 1;
    await reloadStoreData();
  });

  // 8. 页面首屏加载。
  onMounted(loadStores);
  // 9. 路由回到当前页时刷新门店列表，避免使用旧缓存。
  onActivated(loadStores);

  return {
    DAY_OPTIONS,
    PAGE_SIZE_OPTIONS,
    SHIFT_OPTIONS,
    STAFF_PERMISSION_OPTIONS,
    STAFF_ROLE_OPTIONS,
    STAFF_STATUS_OPTIONS,
    applyFilters,
    boardRows,
    copyCandidates,
    copyTargetStoreIds,
    deletingStaffId,
    filters,
    getCurrentWeekStartDate,
    isScheduleConfigured,
    isTemplateConfigured,
    getRoleLabel,
    getRoleTagClass,
    getShiftClass,
    getShiftLabel,
    getStatusDotClass,
    getStatusLabel,
    handleCopyCheckAll,
    handleCopySubmit,
    handleDeleteStaff,
    handleOpenPersonalSchedule,
    handlePageChange,
    handleSavePersonalSchedule,
    handleSaveTemplates,
    handleSaveWeekSchedule,
    handleSubmitStaff,
    isCopyAllChecked,
    isCopyIndeterminate,
    isCopyModalOpen,
    isCopySubmitting,
    isPageLoading,
    isPersonalDrawerOpen,
    isPersonalSaving,
    isScheduleDisabled,
    isStaffDrawerOpen,
    isStaffSaving,
    isStoreLoading,
    isTemplateSaving,
    isWeekDrawerOpen,
    isWeekSaving,
    maskPhone,
    openCopyModal,
    openStaffDrawer,
    handleOpenWeekSchedule,
    personalDrawerTitle,
    personalScheduleForm,
    resetFilters,
    resetTemplates,
    resolveAvatarText,
    selectedStoreId,
    selectedStoreName,
    setCopyModalOpen,
    setFilterKeyword,
    setFilterRoleType,
    setFilterStatus,
    setPersonalDrawerOpen,
    setPersonalShiftEnd,
    setPersonalShiftStart,
    setPersonalShiftType,
    setSelectedStoreId,
    setStaffDrawerOpen,
    setStaffEmail,
    setStaffName,
    setStaffPermissions,
    setStaffPhone,
    setStaffRoleType,
    setStaffStatus,
    setTemplateTime,
    setWeekDrawerOpen,
    shiftLegendItems,
    staffDrawerTitle,
    staffDrawerMode,
    staffForm,
    staffRows,
    staffSubmitText,
    staffTotal,
    storeOptions,
    templates,
    toggleCopyStore,
    weekRows,
    cycleWeekShift,
    formatShiftTimeText,
  };
}
