/**
 * 文件职责：商品列表页面主编排。
 * 1. 维护门店、分类、列表、筛选、勾选、抽屉状态。
 * 2. 组装数据加载、列表交互、抽屉动作、批量动作。
 * 3. 对视图层暴露可直接绑定的状态与方法。
 */
import type {
  ProductCategoryDto,
  ProductListItemDto,
  ProductPickerItemDto,
  ProductStatus,
} from '#/api/product';
import type { StoreListItemDto } from '#/api/store';
import type {
  ProductBatchAction,
  ProductFilterState,
} from '#/views/product/list/types';

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

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

import { searchProductPickerApi } from '#/api/product';

import { createBatchActions } from './product-list-page/batch-actions';
import {
  DEFAULT_EDITOR_FORM,
  DEFAULT_FILTER_STATE,
  DEFAULT_QUICK_EDIT_FORM,
  DEFAULT_SOLDOUT_FORM,
  PAGE_SIZE_OPTIONS,
  PRODUCT_KIND_OPTIONS,
  PRODUCT_STATUS_OPTIONS,
  PRODUCT_VIEW_OPTIONS,
} from './product-list-page/constants';
import { createDataActions } from './product-list-page/data-actions';
import { createDrawerActions } from './product-list-page/drawer-actions';
import {
  cloneEditorForm,
  cloneFilterState,
  cloneQuickEditForm,
  cloneSoldoutForm,
  formatCurrency,
  resolveStatusMeta,
} from './product-list-page/helpers';
import { createListActions } from './product-list-page/list-actions';

export function useProductListPage() {
  const router = useRouter();

  // 1. 页面加载状态。
  const isStoreLoading = ref(false);
  const isCategoryLoading = ref(false);
  const isListLoading = ref(false);
  const isEditorSubmitting = ref(false);
  const isQuickEditSubmitting = ref(false);
  const isSoldoutSubmitting = ref(false);

  // 2. 核心业务数据。
  const stores = ref<StoreListItemDto[]>([]);
  const selectedStoreId = ref('');
  const categories = ref<ProductCategoryDto[]>([]);
  const products = ref<ProductListItemDto[]>([]);
  const total = ref(0);

  const filters = reactive<ProductFilterState>(
    cloneFilterState(DEFAULT_FILTER_STATE),
  );
  const viewMode = ref<'card' | 'list'>('list');
  const selectedProductIds = ref<string[]>([]);

  // 3. 抽屉状态与表单。
  const isEditorDrawerOpen = ref(false);
  const editorDrawerMode = ref<'create' | 'edit'>('create');
  const editorForm = reactive(cloneEditorForm(DEFAULT_EDITOR_FORM));

  const isQuickEditDrawerOpen = ref(false);
  const quickEditForm = reactive(cloneQuickEditForm(DEFAULT_QUICK_EDIT_FORM));
  const currentQuickEditProduct = ref<null | ProductListItemDto>(null);

  const isSoldoutDrawerOpen = ref(false);
  const soldoutForm = reactive(cloneSoldoutForm(DEFAULT_SOLDOUT_FORM));
  const currentSoldoutProduct = ref<null | ProductListItemDto>(null);

  const isComboPickerOpen = ref(false);
  const isComboPickerLoading = ref(false);
  const comboPickerKeyword = ref('');
  const comboPickerProducts = ref<ProductPickerItemDto[]>([]);
  const comboPickerSelectedIds = ref<string[]>([]);
  const comboPickerTargetGroupIndex = ref(-1);

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

  const categorySidebarItems = computed(() => {
    const allCount = categories.value.reduce(
      (sum, item) => sum + item.productCount,
      0,
    );
    return [
      { id: '', name: '全部商品', productCount: allCount },
      ...categories.value.map((item) => ({
        id: item.id,
        name: item.name,
        productCount: item.productCount,
      })),
    ];
  });

  const categoryOptions = computed(() =>
    categories.value.map((item) => ({
      label: item.name,
      value: item.id,
    })),
  );

  const currentPageIds = computed(() => products.value.map((item) => item.id));

  const isAllCurrentPageChecked = computed(() => {
    if (currentPageIds.value.length === 0) return false;
    return currentPageIds.value.every((id) =>
      selectedProductIds.value.includes(id),
    );
  });

  const isCurrentPageIndeterminate = computed(() => {
    const selectedCount = currentPageIds.value.filter((id) =>
      selectedProductIds.value.includes(id),
    ).length;
    return selectedCount > 0 && selectedCount < currentPageIds.value.length;
  });

  const selectedCount = computed(() => selectedProductIds.value.length);

  const editorDrawerTitle = computed(() =>
    editorDrawerMode.value === 'edit' ? '编辑商品' : '添加商品',
  );

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

  const quickEditSummary = computed(() => currentQuickEditProduct.value);
  const soldoutSummary = computed(() => currentSoldoutProduct.value);

  // 5. 动作装配。
  const { loadProducts, loadStores, reloadCurrentStoreData } =
    createDataActions({
      categories,
      filters,
      isCategoryLoading,
      isListLoading,
      isStoreLoading,
      products,
      selectedStoreId,
      stores,
      total,
    });

  const {
    applyFilters,
    changePage,
    clearSelection,
    resetFilters,
    toggleSelectAllOnPage,
    toggleSelectProduct,
  } = createListActions({
    filters,
    loadProducts,
    selectedProductIds,
  });

  const {
    changeProductStatus,
    deleteProduct,
    openCreateDrawer,
    openEditDrawer,
    openQuickEditDrawer,
    openSoldoutDrawer,
    setEditorDrawerOpen,
    setQuickEditDrawerOpen,
    setSoldoutDrawerOpen,
    submitEditor,
    submitQuickEdit,
    submitSoldout,
  } = createDrawerActions({
    clearSelection,
    currentQuickEditProduct,
    currentSoldoutProduct,
    editorDrawerMode,
    editorForm,
    isEditorDrawerOpen,
    isEditorSubmitting,
    isQuickEditDrawerOpen,
    isQuickEditSubmitting,
    isSoldoutDrawerOpen,
    isSoldoutSubmitting,
    quickEditForm,
    reloadCurrentStoreData,
    selectedStoreId,
    soldoutForm,
  });

  const { handleBatchAction } = createBatchActions({
    clearSelection,
    reloadCurrentStoreData,
    selectedProductIds,
    selectedStoreId,
  });

  // 6. 字段更新方法。
  function setSelectedStoreId(value: string) {
    selectedStoreId.value = value;
  }

  async function setSelectedCategoryId(value: string) {
    filters.categoryId = value;
    filters.page = 1;
    await loadProducts();
    clearSelection();
  }

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

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

  function setFilterKind(value: '' | 'combo' | 'single') {
    filters.kind = value;
  }

  function setViewMode(value: 'card' | 'list') {
    viewMode.value = value;
  }

  function setEditorName(value: string) {
    editorForm.name = value;
  }

  function setEditorSubtitle(value: string) {
    editorForm.subtitle = value;
  }

  function setEditorCategoryId(value: string) {
    editorForm.categoryId = value;
  }

  function setEditorDescription(value: string) {
    editorForm.description = value;
  }

  function normalizeComboGroups() {
    editorForm.comboGroups = editorForm.comboGroups.map(
      (group, groupIndex) => ({
        ...group,
        sortOrder: groupIndex + 1,
        items: group.items.map((item, itemIndex) => ({
          ...item,
          sortOrder: itemIndex + 1,
        })),
      }),
    );
  }

  function setEditorKind(value: 'combo' | 'single') {
    if (value === editorForm.kind) {
      return;
    }

    if (editorForm.kind === 'combo' && value === 'single') {
      const hasComboData = editorForm.comboGroups.some(
        (group) => group.items.length > 0 || Boolean(group.name.trim()),
      );
      if (hasComboData) {
        Modal.confirm({
          title: '切换为单品后将清空套餐分组，确认继续吗？',
          okText: '确认切换',
          cancelText: '取消',
          onOk() {
            editorForm.kind = 'single';
            editorForm.comboGroups = [];
          },
        });
        return;
      }
      editorForm.comboGroups = [];
    }

    editorForm.kind = value;
    if (value === 'combo' && editorForm.comboGroups.length === 0) {
      editorForm.comboGroups = [
        {
          name: '',
          minSelect: 1,
          maxSelect: 1,
          sortOrder: 1,
          items: [],
        },
      ];
    }
  }

  function addEditorComboGroup() {
    editorForm.comboGroups = [
      ...editorForm.comboGroups,
      {
        name: '',
        minSelect: 1,
        maxSelect: 1,
        sortOrder: editorForm.comboGroups.length + 1,
        items: [],
      },
    ];
  }

  function removeEditorComboGroup(groupIndex: number) {
    if (groupIndex < 0 || groupIndex >= editorForm.comboGroups.length) {
      return;
    }
    editorForm.comboGroups = editorForm.comboGroups.filter(
      (_, index) => index !== groupIndex,
    );
    if (comboPickerTargetGroupIndex.value === groupIndex) {
      isComboPickerOpen.value = false;
      comboPickerTargetGroupIndex.value = -1;
    }
    normalizeComboGroups();
  }

  function setEditorComboGroupName(groupIndex: number, value: string) {
    const group = editorForm.comboGroups[groupIndex];
    if (!group) return;
    group.name = value;
  }

  function setEditorComboGroupMinSelect(groupIndex: number, value: number) {
    const group = editorForm.comboGroups[groupIndex];
    if (!group) return;
    group.minSelect = Math.max(1, Math.floor(Number(value || 1)));
  }

  function setEditorComboGroupMaxSelect(groupIndex: number, value: number) {
    const group = editorForm.comboGroups[groupIndex];
    if (!group) return;
    group.maxSelect = Math.max(1, Math.floor(Number(value || 1)));
  }

  function removeEditorComboItem(groupIndex: number, itemIndex: number) {
    const group = editorForm.comboGroups[groupIndex];
    if (!group) return;
    group.items = group.items.filter((_, index) => index !== itemIndex);
    normalizeComboGroups();
  }

  function setEditorComboItemQuantity(
    groupIndex: number,
    itemIndex: number,
    value: number,
  ) {
    const group = editorForm.comboGroups[groupIndex];
    if (!group) return;
    const item = group.items[itemIndex];
    if (!item) return;
    item.quantity = Math.max(1, Math.floor(Number(value || 1)));
  }

  async function loadComboPickerProducts() {
    if (!selectedStoreId.value) {
      comboPickerProducts.value = [];
      return;
    }
    isComboPickerLoading.value = true;
    try {
      comboPickerProducts.value = await searchProductPickerApi({
        storeId: selectedStoreId.value,
        keyword: comboPickerKeyword.value.trim() || undefined,
        limit: 500,
      });
    } catch (error) {
      console.error(error);
      comboPickerProducts.value = [];
      message.error('加载商品失败');
    } finally {
      isComboPickerLoading.value = false;
    }
  }

  async function openComboGroupPicker(groupIndex: number) {
    const group = editorForm.comboGroups[groupIndex];
    if (!group) return;
    comboPickerTargetGroupIndex.value = groupIndex;
    comboPickerKeyword.value = '';
    comboPickerSelectedIds.value = group.items.map((item) => item.productId);
    comboPickerProducts.value = [];
    isComboPickerOpen.value = true;
    await loadComboPickerProducts();
  }

  function setComboPickerOpen(value: boolean) {
    isComboPickerOpen.value = value;
    if (!value) {
      comboPickerTargetGroupIndex.value = -1;
    }
  }

  function setComboPickerKeyword(value: string) {
    comboPickerKeyword.value = value;
  }

  function toggleComboPickerProduct(productId: string) {
    if (comboPickerSelectedIds.value.includes(productId)) {
      comboPickerSelectedIds.value = comboPickerSelectedIds.value.filter(
        (id) => id !== productId,
      );
      return;
    }
    comboPickerSelectedIds.value = [...comboPickerSelectedIds.value, productId];
  }

  function submitComboPickerSelection() {
    const groupIndex = comboPickerTargetGroupIndex.value;
    const group = editorForm.comboGroups[groupIndex];
    if (!group) return;
    const selectedIds = comboPickerSelectedIds.value;
    if (selectedIds.length === 0) {
      message.warning('请至少选择一个商品');
      return;
    }

    const sourceLookup = new Map(
      comboPickerProducts.value.map((item) => [item.id, item]),
    );
    group.items = selectedIds.map((id, index) => {
      const existing = group.items.find((item) => item.productId === id);
      const source = sourceLookup.get(id);
      return {
        productId: id,
        productName: existing?.productName ?? source?.name ?? id,
        quantity: Math.max(1, Math.floor(Number(existing?.quantity ?? 1))),
        sortOrder: index + 1,
      };
    });
    normalizeComboGroups();
    isComboPickerOpen.value = false;
    comboPickerTargetGroupIndex.value = -1;
  }

  function setEditorPrice(value: number) {
    editorForm.price = Math.max(0, Number(value || 0));
  }

  function setEditorOriginalPrice(value: null | number) {
    if (value === null || value === undefined || Number(value) <= 0) {
      editorForm.originalPrice = null;
      return;
    }
    editorForm.originalPrice = Math.max(0, Number(value));
  }

  function setEditorStock(value: number) {
    editorForm.stock = Math.max(0, Math.floor(Number(value || 0)));
  }

  function setEditorShelfMode(value: 'draft' | 'now' | 'scheduled') {
    editorForm.shelfMode = value;
  }

  function setEditorTimedOnShelfAt(value: string) {
    editorForm.timedOnShelfAt = value;
  }

  function setQuickEditPrice(value: number) {
    quickEditForm.price = Math.max(0, Number(value || 0));
  }

  function setQuickEditOriginalPrice(value: null | number) {
    if (value === null || value === undefined || Number(value) <= 0) {
      quickEditForm.originalPrice = null;
      return;
    }
    quickEditForm.originalPrice = Math.max(0, Number(value));
  }

  function setQuickEditStock(value: number) {
    quickEditForm.stock = Math.max(0, Math.floor(Number(value || 0)));
  }

  function setQuickEditOnSale(value: boolean) {
    quickEditForm.isOnSale = value;
  }

  function setSoldoutMode(value: 'permanent' | 'timed' | 'today') {
    soldoutForm.mode = value;
  }

  function setSoldoutRemainStock(value: number) {
    soldoutForm.remainStock = Math.max(0, Math.floor(Number(value || 0)));
  }

  function setSoldoutReason(value: string) {
    soldoutForm.reason = value;
  }

  function setSoldoutRecoverAt(value: string) {
    soldoutForm.recoverAt = value;
  }

  function setSoldoutSyncToPlatform(value: boolean) {
    soldoutForm.syncToPlatform = value;
  }

  function setSoldoutNotifyManager(value: boolean) {
    soldoutForm.notifyManager = value;
  }

  // 7. 页面动作封装。
  async function openCreateProductDrawer() {
    const fallbackCategoryId =
      filters.categoryId || categoryOptions.value[0]?.value || '';
    openCreateDrawer(fallbackCategoryId);
  }

  /** 按商品 ID 跳转详情页。 */
  function openProductDetailById(productId: string) {
    if (!selectedStoreId.value || !productId) return;
    router.push({
      path: '/product/detail',
      query: {
        storeId: selectedStoreId.value,
        productId,
      },
    });
  }

  function openProductDetail(item: ProductListItemDto) {
    openProductDetailById(item.id);
  }

  async function applySearchFilters() {
    await applyFilters();
  }

  async function resetSearchFilters() {
    await resetFilters();
  }

  async function handlePageChange(payload: { page: number; pageSize: number }) {
    await changePage(payload);
  }

  function handleToggleSelect(payload: {
    checked: boolean;
    productId: string;
  }) {
    toggleSelectProduct(payload.productId, payload.checked);
  }

  function handleToggleSelectAll(checked: boolean) {
    toggleSelectAllOnPage(currentPageIds.value, checked);
  }

  async function handleSingleStatusChange(payload: {
    item: ProductListItemDto;
    status: ProductStatus;
  }) {
    await changeProductStatus(payload.item, payload.status);
  }

  async function handleDeleteProduct(item: ProductListItemDto) {
    await deleteProduct(item);
  }

  async function handleBatchCommand(action: ProductBatchAction) {
    await handleBatchAction(action);
  }

  // 8. 监听门店切换并刷新页面。
  watch(selectedStoreId, async (storeId) => {
    if (!storeId) {
      categories.value = [];
      products.value = [];
      total.value = 0;
      clearSelection();
      return;
    }

    filters.page = 1;
    filters.categoryId = '';
    clearSelection();
    await reloadCurrentStoreData();
  });

  // 9. 页面初始化。
  onMounted(loadStores);

  return {
    PAGE_SIZE_OPTIONS,
    PRODUCT_KIND_OPTIONS,
    PRODUCT_STATUS_OPTIONS,
    PRODUCT_VIEW_OPTIONS,
    applySearchFilters,
    categories,
    categoryOptions,
    categorySidebarItems,
    clearSelection,
    comboPickerKeyword,
    comboPickerProducts,
    comboPickerSelectedIds,
    currentPageIds,
    deleteProduct: handleDeleteProduct,
    editorDrawerMode,
    editorDrawerTitle,
    editorForm,
    editorSubmitText,
    filters,
    formatCurrency,
    handleBatchCommand,
    handlePageChange,
    handleSingleStatusChange,
    handleToggleSelect,
    handleToggleSelectAll,
    isAllCurrentPageChecked,
    isCategoryLoading,
    isCurrentPageIndeterminate,
    isComboPickerLoading,
    isComboPickerOpen,
    isEditorDrawerOpen,
    isEditorSubmitting,
    isListLoading,
    isQuickEditDrawerOpen,
    isQuickEditSubmitting,
    isSoldoutDrawerOpen,
    isSoldoutSubmitting,
    isStoreLoading,
    openCreateProductDrawer,
    openEditDrawer,
    openProductDetail,
    openProductDetailById,
    openQuickEditDrawer,
    openSoldoutDrawer,
    products,
    quickEditForm,
    quickEditSummary,
    resetSearchFilters,
    resolveStatusMeta,
    selectedCount,
    selectedProductIds,
    selectedStoreId,
    setEditorCategoryId,
    setEditorDescription,
    setEditorDrawerOpen,
    setEditorKind,
    addEditorComboGroup,
    removeEditorComboGroup,
    setEditorComboGroupName,
    setEditorComboGroupMinSelect,
    setEditorComboGroupMaxSelect,
    removeEditorComboItem,
    setEditorComboItemQuantity,
    openComboGroupPicker,
    setComboPickerOpen,
    setComboPickerKeyword,
    toggleComboPickerProduct,
    submitComboPickerSelection,
    loadComboPickerProducts,
    setEditorName,
    setEditorOriginalPrice,
    setEditorPrice,
    setEditorShelfMode,
    setEditorStock,
    setEditorSubtitle,
    setEditorTimedOnShelfAt,
    setFilterKind,
    setFilterKeyword,
    setFilterStatus,
    setQuickEditDrawerOpen,
    setQuickEditOnSale,
    setQuickEditOriginalPrice,
    setQuickEditPrice,
    setQuickEditStock,
    setSelectedCategoryId,
    setSelectedStoreId,
    setSoldoutDrawerOpen,
    setSoldoutMode,
    setSoldoutNotifyManager,
    setSoldoutReason,
    setSoldoutRecoverAt,
    setSoldoutRemainStock,
    setSoldoutSyncToPlatform,
    setViewMode,
    soldoutForm,
    soldoutSummary,
    storeOptions,
    submitEditor,
    submitQuickEdit,
    submitSoldout,
    total,
    viewMode,
  };
}
