import type {
  BatchCategoryOption,
  BatchScopeType,
  BatchToolCard,
  BatchToolKey,
} from '../types';

import type { StoreListItemDto } from '#/api/store';

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

import { BATCH_TOOL_CARDS } from './batch-page/constants';
import { createBatchDataActions } from './batch-page/data-actions';
import { createBatchToolActions } from './batch-page/tool-actions';

/**
 * 文件职责：批量工具页面状态编排。
 * 1. 管理门店、范围、卡片展开状态。
 * 2. 组合批量工具动作并对外暴露给视图组件。
 */
export function useProductBatchPage() {
  const stores = ref<StoreListItemDto[]>([]);
  const selectedStoreId = ref('');
  const isStoreLoading = ref(false);

  const categoryOptions = ref<BatchCategoryOption[]>([]);
  const productOptions = ref<
    Array<{ label: string; price: number; spuCode: string; value: string }>
  >([]);
  const isCategoryLoading = ref(false);
  const isProductLoading = ref(false);

  const activeTool = ref<BatchToolKey | null>(null);
  const latestResultText = ref('');
  const scopeType = ref<BatchScopeType>('all');
  const scopeCategoryIds = ref<string[]>([]);
  const scopeProductIds = ref<string[]>([]);

  const priceDirection = ref<'down' | 'up'>('up');
  const priceAmountType = ref<'fixed' | 'percent'>('fixed');
  const priceAmount = ref(2);
  const pricePreview = ref({
    totalCount: 0,
    items: [],
  });
  const pricePreviewLoading = ref(false);

  const saleAction = ref<'off' | 'on'>('on');

  const moveSourceCategoryId = ref('');
  const moveTargetCategoryId = ref('');

  const syncTargetStoreIds = ref<string[]>([]);
  const syncProductIds = ref<string[]>([]);
  const syncPrice = ref(true);
  const syncStock = ref(true);
  const syncStatus = ref(false);

  const importFile = ref<File | null>(null);
  const exportScopeType = ref<'all' | 'category'>('all');
  const exportCategoryIds = ref<string[]>([]);

  const isSubmitting = ref(false);

  const { loadStoreScopedData, loadStores } = createBatchDataActions({
    stores,
    selectedStoreId,
    isStoreLoading,
    categoryOptions,
    productOptions,
    isCategoryLoading,
    isProductLoading,
  });

  const {
    downloadImportTemplate,
    previewPriceAdjust,
    submitExport,
    submitImport,
    submitMoveCategory,
    submitPriceAdjust,
    submitSaleSwitch,
    submitStoreSync,
  } = createBatchToolActions({
    selectedStoreId,
    scopeType,
    scopeCategoryIds,
    scopeProductIds,
    priceDirection,
    priceAmountType,
    priceAmount,
    pricePreview,
    pricePreviewLoading,
    saleAction,
    moveSourceCategoryId,
    moveTargetCategoryId,
    syncTargetStoreIds,
    syncProductIds,
    syncPrice,
    syncStock,
    syncStatus,
    importFile,
    exportScopeType,
    exportCategoryIds,
    latestResultText,
    isSubmitting,
  });

  const cards = computed<BatchToolCard[]>(() => BATCH_TOOL_CARDS);

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

  const targetStoreOptions = computed(() =>
    stores.value
      .filter((item) => item.id !== selectedStoreId.value)
      .map((item) => ({
        label: item.name,
        value: item.id,
      })),
  );

  const selectedStoreLabel = computed(() => {
    return (
      stores.value.find((item) => item.id === selectedStoreId.value)?.name || ''
    );
  });

  const scopeEstimatedCount = computed(() => {
    if (scopeType.value === 'all') {
      return productOptions.value.length;
    }

    if (scopeType.value === 'manual') {
      return scopeProductIds.value.length;
    }

    const selected = new Set(scopeCategoryIds.value);
    return categoryOptions.value
      .filter((item) => selected.has(item.value))
      .reduce((sum, item) => sum + item.productCount, 0);
  });

  const moveEstimatedCount = computed(() => {
    if (moveSourceCategoryId.value) {
      return (
        categoryOptions.value.find(
          (item) => item.value === moveSourceCategoryId.value,
        )?.productCount ?? 0
      );
    }

    return scopeEstimatedCount.value;
  });

  function toggleTool(key: BatchToolKey) {
    activeTool.value = activeTool.value === key ? null : key;
  }

  function closeTool() {
    activeTool.value = null;
  }

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

  function setScopeType(value: BatchScopeType) {
    scopeType.value = value;
  }

  function setImportFile(file: File | null) {
    importFile.value = file;
  }

  async function ensureStoresLoaded() {
    await loadStores();
  }

  watch(selectedStoreId, () => {
    scopeType.value = 'all';
    scopeCategoryIds.value = [];
    scopeProductIds.value = [];
    moveSourceCategoryId.value = '';
    moveTargetCategoryId.value = '';
    syncTargetStoreIds.value = [];
    syncProductIds.value = [];
    exportScopeType.value = 'all';
    exportCategoryIds.value = [];
    importFile.value = null;
    pricePreview.value = {
      totalCount: 0,
      items: [],
    };
    void loadStoreScopedData();
  });

  watch([scopeType, scopeCategoryIds, scopeProductIds], () => {
    if (scopeType.value !== 'category' && scopeCategoryIds.value.length > 0) {
      scopeCategoryIds.value = [];
    }

    if (scopeType.value !== 'manual' && scopeProductIds.value.length > 0) {
      scopeProductIds.value = [];
    }
  });

  watch(activeTool, (value) => {
    if (value === 'price' && selectedStoreId.value) {
      void previewPriceAdjust();
    }
  });

  onMounted(() => {
    void ensureStoresLoaded();
  });

  onActivated(() => {
    if (stores.value.length === 0 || !selectedStoreId.value) {
      void ensureStoresLoaded();
    }
  });

  return {
    activeTool,
    cards,
    categoryOptions,
    closeTool,
    downloadImportTemplate,
    exportCategoryIds,
    exportScopeType,
    importFile,
    isCategoryLoading,
    isProductLoading,
    isStoreLoading,
    isSubmitting,
    latestResultText,
    moveEstimatedCount,
    moveSourceCategoryId,
    moveTargetCategoryId,
    previewPriceAdjust,
    priceAmount,
    priceAmountType,
    priceDirection,
    pricePreview,
    pricePreviewLoading,
    productOptions,
    saleAction,
    scopeCategoryIds,
    scopeEstimatedCount,
    scopeProductIds,
    scopeType,
    selectedStoreId,
    selectedStoreLabel,
    setImportFile,
    setScopeType,
    setSelectedStoreId,
    storeOptions,
    submitExport,
    submitImport,
    submitMoveCategory,
    submitPriceAdjust,
    submitSaleSwitch,
    submitStoreSync,
    syncPrice,
    syncProductIds,
    syncStatus,
    syncStock,
    syncTargetStoreIds,
    targetStoreOptions,
    toggleTool,
  };
}
