import type { Ref } from 'vue';

import type { BatchScopeType } from '../../types';

import type {
  ProductBatchPricePreviewDto,
  ProductBatchScopeDto,
} from '#/api/product';

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

import {
  batchAdjustProductPriceApi,
  batchDownloadProductImportTemplateApi,
  batchExportProductApi,
  batchImportProductApi,
  batchMoveProductCategoryApi,
  batchPreviewProductPriceApi,
  batchSwitchProductSaleApi,
  batchSyncProductStoreApi,
} from '#/api/product';

interface CreateBatchToolActionsOptions {
  exportCategoryIds: Ref<string[]>;
  exportScopeType: Ref<'all' | 'category'>;
  importFile: Ref<File | null>;
  isSubmitting: Ref<boolean>;
  latestResultText: Ref<string>;
  moveSourceCategoryId: Ref<string>;
  moveTargetCategoryId: Ref<string>;
  priceAmount: Ref<number>;
  priceAmountType: Ref<'fixed' | 'percent'>;
  priceDirection: Ref<'down' | 'up'>;
  pricePreview: Ref<ProductBatchPricePreviewDto>;
  pricePreviewLoading: Ref<boolean>;
  saleAction: Ref<'off' | 'on'>;
  scopeCategoryIds: Ref<string[]>;
  scopeProductIds: Ref<string[]>;
  scopeType: Ref<BatchScopeType>;
  selectedStoreId: Ref<string>;
  syncProductIds: Ref<string[]>;
  syncPrice: Ref<boolean>;
  syncStatus: Ref<boolean>;
  syncStock: Ref<boolean>;
  syncTargetStoreIds: Ref<string[]>;
}

function buildScope(
  type: BatchScopeType,
  categoryIds: string[],
  productIds: string[],
): ProductBatchScopeDto {
  if (type === 'category') {
    const normalized = [...new Set(categoryIds.filter(Boolean))];
    return {
      type: 'category',
      categoryIds: normalized,
      categoryId: normalized[0],
    };
  }

  if (type === 'manual') {
    return {
      type: 'manual',
      productIds: [...new Set(productIds.filter(Boolean))],
    };
  }

  return { type: 'all' };
}

function ensureScopeValid(
  type: BatchScopeType,
  categoryIds: string[],
  productIds: string[],
) {
  if (type === 'category' && categoryIds.length === 0) {
    message.warning('请选择至少一个分类');
    return false;
  }

  if (type === 'manual' && productIds.length === 0) {
    message.warning('请至少选择一个商品');
    return false;
  }

  return true;
}

function decodeBase64ToBlob(base64: string) {
  const binary = window.atob(base64);
  const bytes = new Uint8Array(binary.length);
  for (let index = 0; index < binary.length; index++) {
    bytes[index] = binary.codePointAt(index) ?? 0;
  }

  return new Blob([bytes], {
    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  });
}

function downloadBase64File(fileName: string, fileContentBase64: string) {
  const blob = decodeBase64ToBlob(fileContentBase64);
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = fileName;
  document.body.append(anchor);
  anchor.click();
  anchor.remove();
  URL.revokeObjectURL(url);
}

/**
 * 文件职责：批量工具动作。
 * 1. 封装所有批量 API 调用。
 * 2. 统一处理范围构建、结果提示与 Excel 下载。
 */
export function createBatchToolActions(options: CreateBatchToolActionsOptions) {
  function resolveCurrentScope() {
    return buildScope(
      options.scopeType.value,
      options.scopeCategoryIds.value,
      options.scopeProductIds.value,
    );
  }

  async function previewPriceAdjust() {
    if (!options.selectedStoreId.value) {
      return;
    }

    if (
      !ensureScopeValid(
        options.scopeType.value,
        options.scopeCategoryIds.value,
        options.scopeProductIds.value,
      )
    ) {
      return;
    }

    if (options.priceAmount.value < 0) {
      message.warning('调价数值不能小于 0');
      return;
    }

    options.pricePreviewLoading.value = true;
    try {
      options.pricePreview.value = await batchPreviewProductPriceApi({
        storeId: options.selectedStoreId.value,
        scope: resolveCurrentScope(),
        direction: options.priceDirection.value,
        amountType: options.priceAmountType.value,
        amount: options.priceAmount.value,
      });
    } catch (error) {
      console.error(error);
    } finally {
      options.pricePreviewLoading.value = false;
    }
  }

  async function submitPriceAdjust() {
    if (!options.selectedStoreId.value) {
      return;
    }

    if (
      !ensureScopeValid(
        options.scopeType.value,
        options.scopeCategoryIds.value,
        options.scopeProductIds.value,
      )
    ) {
      return;
    }

    if (options.priceAmount.value < 0) {
      message.warning('调价数值不能小于 0');
      return;
    }

    options.isSubmitting.value = true;
    try {
      const result = await batchAdjustProductPriceApi({
        storeId: options.selectedStoreId.value,
        scope: resolveCurrentScope(),
        direction: options.priceDirection.value,
        amountType: options.priceAmountType.value,
        amount: options.priceAmount.value,
      });
      options.latestResultText.value = `调价完成：成功 ${result.successCount} / 总计 ${result.totalCount}，跳过 ${result.skippedCount}`;
      message.success('批量调价已完成');
      await previewPriceAdjust();
    } catch (error) {
      console.error(error);
    } finally {
      options.isSubmitting.value = false;
    }
  }

  async function submitSaleSwitch() {
    if (!options.selectedStoreId.value) {
      return;
    }

    if (
      !ensureScopeValid(
        options.scopeType.value,
        options.scopeCategoryIds.value,
        options.scopeProductIds.value,
      )
    ) {
      return;
    }

    options.isSubmitting.value = true;
    try {
      const result = await batchSwitchProductSaleApi({
        storeId: options.selectedStoreId.value,
        scope: resolveCurrentScope(),
        action: options.saleAction.value,
      });
      options.latestResultText.value = `上下架完成：成功 ${result.successCount} / 总计 ${result.totalCount}，跳过 ${result.skippedCount}`;
      message.success('批量上下架已完成');
    } catch (error) {
      console.error(error);
    } finally {
      options.isSubmitting.value = false;
    }
  }

  async function submitMoveCategory() {
    if (!options.selectedStoreId.value) {
      return;
    }

    if (!options.moveTargetCategoryId.value) {
      message.warning('请选择目标分类');
      return;
    }

    if (
      options.moveSourceCategoryId.value === options.moveTargetCategoryId.value
    ) {
      message.warning('源分类和目标分类不能相同');
      return;
    }

    const scope = options.moveSourceCategoryId.value
      ? buildScope('category', [options.moveSourceCategoryId.value], [])
      : resolveCurrentScope();

    if (
      scope.type !== 'category' &&
      !ensureScopeValid(
        options.scopeType.value,
        options.scopeCategoryIds.value,
        options.scopeProductIds.value,
      )
    ) {
      return;
    }

    options.isSubmitting.value = true;
    try {
      const result = await batchMoveProductCategoryApi({
        storeId: options.selectedStoreId.value,
        scope,
        sourceCategoryId: options.moveSourceCategoryId.value || undefined,
        targetCategoryId: options.moveTargetCategoryId.value,
      });
      options.latestResultText.value = `移动分类完成：成功 ${result.successCount} / 总计 ${result.totalCount}，跳过 ${result.skippedCount}`;
      message.success('批量移动分类已完成');
    } catch (error) {
      console.error(error);
    } finally {
      options.isSubmitting.value = false;
    }
  }

  async function submitStoreSync() {
    if (!options.selectedStoreId.value) {
      return;
    }

    if (options.syncTargetStoreIds.value.length === 0) {
      message.warning('请至少选择一个目标门店');
      return;
    }

    if (options.syncProductIds.value.length === 0) {
      message.warning('请至少选择一个商品');
      return;
    }

    options.isSubmitting.value = true;
    try {
      const result = await batchSyncProductStoreApi({
        sourceStoreId: options.selectedStoreId.value,
        targetStoreIds: options.syncTargetStoreIds.value,
        productIds: options.syncProductIds.value,
        syncPrice: options.syncPrice.value,
        syncStock: options.syncStock.value,
        syncStatus: options.syncStatus.value,
      });
      options.latestResultText.value = `同步完成：成功 ${result.successCount} / 总计 ${result.totalCount}，失败 ${result.failedCount}`;
      message.success('批量同步门店已完成');
    } catch (error) {
      console.error(error);
    } finally {
      options.isSubmitting.value = false;
    }
  }

  async function downloadImportTemplate() {
    if (!options.selectedStoreId.value) {
      return;
    }

    options.isSubmitting.value = true;
    try {
      const result = await batchDownloadProductImportTemplateApi(
        options.selectedStoreId.value,
      );
      downloadBase64File(result.fileName, result.fileContentBase64);
      message.success('导入模板已下载');
    } catch (error) {
      console.error(error);
    } finally {
      options.isSubmitting.value = false;
    }
  }

  async function submitImport() {
    if (!options.selectedStoreId.value) {
      return;
    }

    if (!options.importFile.value) {
      message.warning('请先选择导入文件');
      return;
    }

    options.isSubmitting.value = true;
    try {
      const result = await batchImportProductApi({
        storeId: options.selectedStoreId.value,
        file: options.importFile.value,
      });
      options.latestResultText.value = `导入完成：成功 ${result.successCount} / 总计 ${result.totalCount}，失败 ${result.failedCount}`;
      message.success('批量导入已完成');
    } catch (error) {
      console.error(error);
    } finally {
      options.isSubmitting.value = false;
    }
  }

  async function submitExport() {
    if (!options.selectedStoreId.value) {
      return;
    }

    const scope = buildScope(
      options.exportScopeType.value,
      options.exportCategoryIds.value,
      [],
    );
    if (
      options.exportScopeType.value === 'category' &&
      options.exportCategoryIds.value.length === 0
    ) {
      message.warning('导出按分类时请至少选择一个分类');
      return;
    }

    options.isSubmitting.value = true;
    try {
      const result = await batchExportProductApi({
        storeId: options.selectedStoreId.value,
        scope,
      });
      downloadBase64File(result.fileName, result.fileContentBase64);
      options.latestResultText.value = `导出完成：导出 ${result.successCount} / 总计 ${result.totalCount}`;
      message.success('批量导出已完成');
    } catch (error) {
      console.error(error);
    } finally {
      options.isSubmitting.value = false;
    }
  }

  return {
    buildScope,
    downloadImportTemplate,
    previewPriceAdjust,
    submitExport,
    submitImport,
    submitMoveCategory,
    submitPriceAdjust,
    submitSaleSwitch,
    submitStoreSync,
  };
}
