import type {
  CategoryFormModel,
  CategoryStatsViewModel,
  ChannelFilter,
  DrawerMode,
  ProductPreviewItem,
  StoreOption,
} from '../types';

/**
 * 文件职责：分类管理页面状态与行为编排。
 * 1. 维护页面状态、衍生视图数据与监听器。
 * 2. 组合数据、抽屉、商品选择、复制等动作模块。
 */
import type {
  ProductCategoryManageDto,
  ProductPickerItemDto,
} from '#/api/product';
import type { StoreListItemDto } from '#/api/store';

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

import { CATEGORY_CHANNEL_ORDER } from '../types';
import { createCopyActions } from './category-page/copy-actions';
import { createDataActions } from './category-page/data-actions';
import { createDrawerActions } from './category-page/drawer-actions';
import { createPickerActions } from './category-page/picker-actions';

/** 分类管理页面组合式状态。 */
export function useProductCategoryPage() {
  const stores = ref<StoreListItemDto[]>([]);
  const selectedStoreId = ref('');
  const isStoreLoading = ref(false);

  const categories = ref<ProductCategoryManageDto[]>([]);
  const isCategoryLoading = ref(false);
  const selectedCategoryId = ref('');
  const categoryKeyword = ref('');
  const channelFilter = ref<ChannelFilter>('all');

  const categoryProducts = ref<ProductPreviewItem[]>([]);
  const isCategoryProductsLoading = ref(false);

  const isDrawerOpen = ref(false);
  const drawerMode = ref<DrawerMode>('create');
  const isDrawerSubmitting = ref(false);
  const form = reactive<CategoryFormModel>({
    id: '',
    name: '',
    description: '',
    icon: '',
    channels: [...CATEGORY_CHANNEL_ORDER],
    sort: 1,
    status: 'enabled',
  });

  const isPickerOpen = ref(false);
  const pickerKeyword = ref('');
  const pickerProducts = ref<ProductPickerItemDto[]>([]);
  const pickerSelectedIds = ref<string[]>([]);
  const isPickerLoading = ref(false);
  const isPickerSubmitting = ref(false);

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

  const storeOptions = computed<StoreOption[]>(() =>
    stores.value.map((item) => ({
      label: item.name,
      value: item.id,
    })),
  );

  const selectedCategory = computed(() =>
    categories.value.find((item) => item.id === selectedCategoryId.value),
  );

  const stats = computed<CategoryStatsViewModel>(() => {
    const totalCategories = categories.value.length;
    const enabledCategories = categories.value.filter(
      (item) => item.status === 'enabled',
    ).length;
    const totalProducts = categories.value.reduce(
      (sum, item) => sum + item.productCount,
      0,
    );
    const wmCount = categories.value.filter((item) =>
      item.channels.includes('wm'),
    ).length;
    const pickupCount = categories.value.filter((item) =>
      item.channels.includes('pickup'),
    ).length;
    const dineInCount = categories.value.filter((item) =>
      item.channels.includes('dine_in'),
    ).length;

    return {
      totalCategories,
      enabledCategories,
      totalProducts,
      wmCount,
      pickupCount,
      dineInCount,
    };
  });

  const filteredCategories = computed(() => {
    const keyword = categoryKeyword.value.trim().toLowerCase();
    return categories.value.filter((item) => {
      if (
        channelFilter.value !== 'all' &&
        !item.channels.includes(channelFilter.value)
      ) {
        return false;
      }
      if (!keyword) return true;
      return (
        item.name.toLowerCase().includes(keyword) ||
        item.description.toLowerCase().includes(keyword)
      );
    });
  });

  const drawerTitle = computed(() =>
    drawerMode.value === 'create' ? '添加分类' : '编辑分类',
  );
  const drawerSubmitText = computed(() =>
    drawerMode.value === 'create' ? '确认添加' : '保存修改',
  );

  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 { loadCategories, loadCategoryProducts, loadStores } =
    createDataActions({
      stores,
      selectedStoreId,
      isStoreLoading,
      categories,
      isCategoryLoading,
      selectedCategoryId,
      categoryProducts,
      isCategoryProductsLoading,
    });

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

  const {
    openCreateDrawer,
    openEditDrawer,
    removeSelectedCategory,
    setDrawerOpen,
    setFormDescription,
    setFormIcon,
    setFormName,
    setFormSort,
    submitDrawer,
    toggleDrawerChannel,
    toggleDrawerStatus,
  } = createDrawerActions({
    categories,
    drawerMode,
    form,
    isDrawerOpen,
    isDrawerSubmitting,
    loadCategories,
    selectedCategory,
    selectedStoreId,
  });

  const {
    loadPickerProducts,
    openProductPicker,
    setPickerKeyword,
    setPickerOpen,
    submitProductPicker,
    togglePickerProduct,
    unbindProduct,
  } = createPickerActions({
    categoryProducts,
    isPickerLoading,
    isPickerOpen,
    isPickerSubmitting,
    loadCategories,
    pickerKeyword,
    pickerProducts,
    pickerSelectedIds,
    selectedCategory,
    selectedStoreId,
  });

  function setSelectedStoreId(value: string) {
    selectedStoreId.value = value;
  }

  function setCategoryKeyword(value: string) {
    categoryKeyword.value = value;
  }

  function setChannelFilter(value: ChannelFilter) {
    channelFilter.value = value;
  }

  function selectCategory(id: string) {
    if (selectedCategoryId.value === id) return;
    selectedCategoryId.value = id;
  }

  watch(selectedStoreId, () => {
    categoryKeyword.value = '';
    channelFilter.value = 'all';
    isCopyModalOpen.value = false;
    copyTargetStoreIds.value = [];
    void loadCategories();
  });

  watch(filteredCategories, (list) => {
    if (list.length === 0) {
      selectedCategoryId.value = '';
      categoryProducts.value = [];
      return;
    }
    const hasSelected = list.some(
      (item) => item.id === selectedCategoryId.value,
    );
    if (!hasSelected) {
      selectedCategoryId.value = list[0]?.id ?? '';
    }
  });

  watch(selectedCategoryId, () => {
    void loadCategoryProducts();
  });

  onMounted(loadStores);

  return {
    categoryKeyword,
    categoryProducts,
    categories,
    channelFilter,
    copyCandidates,
    copyTargetStoreIds,
    drawerMode,
    drawerSubmitText,
    drawerTitle,
    filteredCategories,
    form,
    isCategoryLoading,
    isCategoryProductsLoading,
    isCopyAllChecked,
    isCopyIndeterminate,
    isCopyModalOpen,
    isCopySubmitting,
    isDrawerOpen,
    isDrawerSubmitting,
    isPickerLoading,
    isPickerOpen,
    isPickerSubmitting,
    isStoreLoading,
    pickerKeyword,
    pickerProducts,
    pickerSelectedIds,
    selectedCategory,
    selectedCategoryId,
    selectedStoreId,
    selectedStoreName,
    stats,
    storeOptions,
    handleCopyCheckAll,
    handleCopySubmit,
    loadPickerProducts,
    openCopyModal,
    openCreateDrawer,
    openEditDrawer,
    openProductPicker,
    removeSelectedCategory,
    selectCategory,
    setCategoryKeyword,
    setChannelFilter,
    setCopyModalOpen,
    setDrawerOpen,
    setFormDescription,
    setFormIcon,
    setFormName,
    setFormSort,
    setPickerKeyword,
    setPickerOpen,
    setSelectedStoreId,
    submitDrawer,
    submitProductPicker,
    toggleCopyStore,
    toggleDrawerChannel,
    toggleDrawerStatus,
    togglePickerProduct,
    unbindProduct,
  };
}
