import type { Dayjs } from 'dayjs';

import type { ProductPickerItemDto } from '#/api/product';
import type { StoreListItemDto } from '#/api/store';
import type {
  PointMallProductCardViewModel,
  PointMallRecordDetailViewModel,
  PointMallTabKey,
} from '#/views/member/points-mall/types';

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

import { useAccessStore } from '@vben/stores';

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

import {
  exportMemberPointMallRecordApi,
  saveMemberPointMallRuleApi,
} from '#/api/member/points-mall';

import {
  createDefaultPointMallProductEditorForm,
  createDefaultPointMallProductFilterForm,
  createDefaultPointMallRecordFilterForm,
  createDefaultPointMallRecordPager,
  createDefaultPointMallRecordStats,
  createDefaultPointMallRuleForm,
  createDefaultPointMallRuleStats,
  createDefaultPointMallVerifyForm,
} from '../types';
import {
  MEMBER_POINTS_MALL_MANAGE_PERMISSION,
  MEMBER_POINTS_MALL_VIEW_PERMISSION,
  POINTS_MALL_TAB_OPTIONS,
} from './points-mall-page/constants';
import { createDataActions } from './points-mall-page/data-actions';
import { createDrawerActions } from './points-mall-page/drawer-actions';
import {
  downloadBase64File,
  mapRecordFilterToQuery,
  mapRuleFormToSavePayload,
  resetRuleForm,
} from './points-mall-page/helpers';
import { createPickerActions } from './points-mall-page/picker-actions';
import { createProductActions } from './points-mall-page/product-actions';
import { createRecordActions } from './points-mall-page/record-actions';

export function useMemberPointsMallPage() {
  const accessStore = useAccessStore();

  const stores = ref<StoreListItemDto[]>([]);
  const selectedStoreId = ref('');
  const isStoreLoading = ref(false);

  const activeTab = ref<PointMallTabKey>('rules');

  const ruleForm = reactive(createDefaultPointMallRuleForm());
  const ruleStats = ref(createDefaultPointMallRuleStats());
  const isRuleLoading = ref(false);
  const isRuleSubmitting = ref(false);

  const productFilterForm = reactive(createDefaultPointMallProductFilterForm());
  const productRows = ref<PointMallProductCardViewModel[]>([]);
  const isProductLoading = ref(false);

  const drawerMode = ref<'create' | 'edit'>('create');
  const productForm = reactive(createDefaultPointMallProductEditorForm());
  const isDrawerOpen = ref(false);
  const isDrawerLoading = ref(false);
  const isDrawerSubmitting = ref(false);
  const couponOptions = ref<Array<{ label: string; value: string }>>([]);

  const isPickerOpen = ref(false);
  const isPickerLoading = ref(false);
  const pickerKeyword = ref('');
  const pickerRows = ref<ProductPickerItemDto[]>([]);
  const pickerSelectedId = ref('');

  const recordFilterForm = reactive(createDefaultPointMallRecordFilterForm());
  const recordPager = ref(createDefaultPointMallRecordPager());
  const recordStats = ref(createDefaultPointMallRecordStats());
  const isRecordLoading = ref(false);
  const isExporting = ref(false);

  const selectedRecordId = ref('');
  const detailRecord = ref<null | PointMallRecordDetailViewModel>(null);
  const isDetailOpen = ref(false);
  const isDetailLoading = ref(false);
  const verifyForm = reactive(createDefaultPointMallVerifyForm());
  const isVerifyOpen = ref(false);
  const isVerifyLoading = ref(false);
  const isVerifySubmitting = ref(false);

  const accessCodeSet = computed(
    () => new Set((accessStore.accessCodes ?? []).map(String)),
  );
  const canManage = computed(() =>
    accessCodeSet.value.has(MEMBER_POINTS_MALL_MANAGE_PERMISSION),
  );
  const canView = computed(
    () =>
      canManage.value ||
      accessCodeSet.value.has(MEMBER_POINTS_MALL_VIEW_PERMISSION),
  );

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

  const drawerTitle = computed(() =>
    drawerMode.value === 'create' ? '添加兑换商品' : '编辑兑换商品',
  );
  const drawerSubmitText = computed(() => '保存');

  const { loadStores, loadRuleDetail, loadProductList, loadRecordList } =
    createDataActions({
      stores,
      selectedStoreId,
      isStoreLoading,
      ruleForm,
      ruleStats,
      isRuleLoading,
      productFilterForm,
      productRows,
      isProductLoading,
      recordFilterForm,
      recordPager,
      recordStats,
      isRecordLoading,
    });

  const {
    loadPickerProducts,
    openPicker,
    setPickerKeyword,
    setPickerOpen,
    setPickerSelectedId,
    submitPicker,
  } = createPickerActions({
    isPickerOpen,
    isPickerLoading,
    pickerKeyword,
    pickerRows,
    pickerSelectedId,
    selectedStoreId,
    onPicked(item) {
      if (!item) {
        return;
      }
      productForm.productId = item.id;
      productForm.productName = item.name;
      if (!productForm.name.trim()) {
        productForm.name = item.name;
      }
    },
  });

  const {
    loadCouponOptions,
    openCreateDrawer,
    openEditDrawer,
    openProductPicker,
    setDrawerOpen,
    setFormCashAmount,
    setFormCouponTemplateId,
    setFormDescription,
    setFormExchangeType,
    setFormImageUrl,
    setFormName,
    setFormPerMemberLimit,
    setFormPhysicalName,
    setFormPickupMethod,
    setFormRedeemType,
    setFormRequiredPoints,
    setFormStatus,
    setFormStockTotal,
    submitDrawer,
    toggleNotifyChannel,
  } = createDrawerActions({
    canManage,
    drawerMode,
    form: productForm,
    isDrawerLoading,
    isDrawerOpen,
    isDrawerSubmitting,
    selectedStoreId,
    couponOptions,
    loadProductList,
    openPicker,
  });

  const { removeProduct, toggleStatus } = createProductActions({
    canManage,
    selectedStoreId,
    loadProductList,
  });

  const {
    openDetailDrawer,
    openVerifyDrawer,
    setDetailOpen,
    setVerifyMethod,
    setVerifyOpen,
    setVerifyRemark,
    submitVerify,
  } = createRecordActions({
    canManage,
    selectedStoreId,
    selectedRecordId,
    detailRecord,
    isDetailLoading,
    isDetailOpen,
    verifyForm,
    isVerifyLoading,
    isVerifyOpen,
    isVerifySubmitting,
    loadRecordList,
  });

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

  function setActiveTab(value: PointMallTabKey) {
    activeTab.value = value;
  }

  function setRuleConsumeRewardEnabled(value: boolean) {
    ruleForm.isConsumeRewardEnabled = value;
  }

  function setRuleConsumeAmountPerStep(value: null | number) {
    ruleForm.consumeAmountPerStep = value;
  }

  function setRuleConsumeRewardPointsPerStep(value: null | number) {
    ruleForm.consumeRewardPointsPerStep = value;
  }

  function setRuleReviewRewardEnabled(value: boolean) {
    ruleForm.isReviewRewardEnabled = value;
  }

  function setRuleReviewRewardPoints(value: null | number) {
    ruleForm.reviewRewardPoints = value;
  }

  function setRuleRegisterRewardEnabled(value: boolean) {
    ruleForm.isRegisterRewardEnabled = value;
  }

  function setRuleRegisterRewardPoints(value: null | number) {
    ruleForm.registerRewardPoints = value;
  }

  function setRuleSigninRewardEnabled(value: boolean) {
    ruleForm.isSigninRewardEnabled = value;
  }

  function setRuleSigninRewardPoints(value: null | number) {
    ruleForm.signinRewardPoints = value;
  }

  function setRuleExpiryMode(value: 'permanent' | 'yearly_clear') {
    ruleForm.expiryMode = value;
  }

  function validateRuleForm() {
    if (
      ruleForm.isConsumeRewardEnabled &&
      (!ruleForm.consumeAmountPerStep || ruleForm.consumeAmountPerStep <= 0)
    ) {
      message.warning('消费获取规则中“每消费金额”必须大于 0');
      return false;
    }

    if (
      ruleForm.isConsumeRewardEnabled &&
      (!ruleForm.consumeRewardPointsPerStep ||
        ruleForm.consumeRewardPointsPerStep <= 0)
    ) {
      message.warning('消费获取规则中“每步积分”必须大于 0');
      return false;
    }

    if (
      ruleForm.isReviewRewardEnabled &&
      (!ruleForm.reviewRewardPoints || ruleForm.reviewRewardPoints <= 0)
    ) {
      message.warning('评价奖励积分必须大于 0');
      return false;
    }

    if (
      ruleForm.isRegisterRewardEnabled &&
      (!ruleForm.registerRewardPoints || ruleForm.registerRewardPoints <= 0)
    ) {
      message.warning('注册奖励积分必须大于 0');
      return false;
    }

    if (
      ruleForm.isSigninRewardEnabled &&
      (!ruleForm.signinRewardPoints || ruleForm.signinRewardPoints <= 0)
    ) {
      message.warning('签到奖励积分必须大于 0');
      return false;
    }

    return true;
  }

  async function saveRule() {
    if (!canManage.value) {
      return;
    }

    if (!selectedStoreId.value) {
      message.warning('请先选择门店');
      return;
    }

    if (!validateRuleForm()) {
      return;
    }

    isRuleSubmitting.value = true;
    try {
      await saveMemberPointMallRuleApi(
        mapRuleFormToSavePayload(ruleForm, selectedStoreId.value),
      );
      message.success('规则已保存');
      await loadRuleDetail();
    } catch (error) {
      console.error(error);
      message.error('保存规则失败');
    } finally {
      isRuleSubmitting.value = false;
    }
  }

  function setProductKeyword(value: string) {
    productFilterForm.keyword = value;
  }

  function setProductStatusFilter(value: '' | 'disabled' | 'enabled') {
    productFilterForm.status = value;
  }

  async function applyProductFilters() {
    await loadProductList();
  }

  async function resetProductFilters() {
    productFilterForm.status = '';
    productFilterForm.keyword = '';
    await loadProductList();
  }

  function setRecordRedeemType(value: '' | 'coupon' | 'physical' | 'product') {
    recordFilterForm.redeemType = value;
  }

  function setRecordStatus(
    value: '' | 'canceled' | 'completed' | 'issued' | 'pending_pickup',
  ) {
    recordFilterForm.status = value;
  }

  function setRecordKeyword(value: string) {
    recordFilterForm.keyword = value;
  }

  function setRecordDateRange(value: [Dayjs, Dayjs] | null) {
    recordFilterForm.dateRange = value ?? null;
  }

  async function applyRecordFilters() {
    recordPager.value = {
      ...recordPager.value,
      page: 1,
    };
    await loadRecordList();
  }

  async function resetRecordFilters() {
    recordFilterForm.redeemType = '';
    recordFilterForm.status = '';
    recordFilterForm.keyword = '';
    recordFilterForm.dateRange = null;
    recordPager.value = {
      ...recordPager.value,
      page: 1,
    };
    await loadRecordList();
  }

  async function handleRecordPageChange(page: number, pageSize: number) {
    recordPager.value = {
      ...recordPager.value,
      page,
      pageSize,
    };
    await loadRecordList();
  }

  async function exportRecords() {
    if (!selectedStoreId.value) {
      message.warning('请先选择门店');
      return;
    }

    isExporting.value = true;
    try {
      const query = mapRecordFilterToQuery(recordFilterForm);
      const result = await exportMemberPointMallRecordApi({
        storeId: selectedStoreId.value,
        ...query,
      });
      downloadBase64File(result.fileName, result.fileContentBase64);
      message.success(`导出成功，共 ${result.totalCount} 条`);
    } catch (error) {
      console.error(error);
      message.error('导出失败');
    } finally {
      isExporting.value = false;
    }
  }

  function openEditProduct(item: PointMallProductCardViewModel) {
    void openEditDrawer(item);
  }

  function openCreateProduct() {
    void openCreateDrawer();
  }

  function openProductPickerDrawer() {
    void openProductPicker();
  }

  function onPickedProductSelected(id: string) {
    setPickerSelectedId(id);
  }

  function submitProductPicker() {
    submitPicker();
  }

  function searchPickerProducts() {
    void loadPickerProducts();
  }

  function searchCouponOptions(keyword: string) {
    void loadCouponOptions(keyword);
  }

  watch(selectedStoreId, async () => {
    recordPager.value = {
      ...recordPager.value,
      page: 1,
      pageSize: 10,
    };
    await Promise.all([loadRuleDetail(), loadProductList(), loadRecordList()]);
    await loadCouponOptions();
  });

  onMounted(async () => {
    await loadStores();
    if (selectedStoreId.value) {
      await Promise.all([
        loadRuleDetail(),
        loadProductList(),
        loadRecordList(),
      ]);
      await loadCouponOptions();
    } else {
      resetRuleForm(ruleForm);
    }
  });

  return {
    activeTab,
    applyProductFilters,
    applyRecordFilters,
    canManage,
    canView,
    couponOptions,
    detailRecord,
    drawerSubmitText,
    drawerTitle,
    exportRecords,
    hasStore,
    handleRecordPageChange,
    isDetailLoading,
    isDetailOpen,
    isDrawerLoading,
    isDrawerOpen,
    isDrawerSubmitting,
    isExporting,
    isPickerLoading,
    isPickerOpen,
    isProductLoading,
    isRecordLoading,
    isRuleLoading,
    isRuleSubmitting,
    isStoreLoading,
    isVerifyLoading,
    isVerifyOpen,
    isVerifySubmitting,
    openCreateProduct,
    openDetailDrawer,
    openEditProduct,
    openProductPickerDrawer,
    openVerifyDrawer,
    pickerKeyword,
    pickerRows,
    pickerSelectedId,
    productFilterForm,
    productForm,
    productRows,
    recordFilterForm,
    recordPager,
    recordStats,
    removeProduct,
    resetProductFilters,
    resetRecordFilters,
    ruleForm,
    ruleStats,
    saveRule,
    selectedStoreId,
    setActiveTab,
    setDetailOpen,
    setDrawerOpen,
    setFormCashAmount,
    setFormCouponTemplateId,
    setFormDescription,
    setFormExchangeType,
    setFormImageUrl,
    setFormName,
    setFormPerMemberLimit,
    setFormPhysicalName,
    setFormPickupMethod,
    setFormRedeemType,
    setFormRequiredPoints,
    setFormStatus,
    setFormStockTotal,
    setPickedProductId: onPickedProductSelected,
    setPickerKeyword,
    setPickerOpen,
    setProductKeyword,
    setProductStatusFilter,
    setRecordDateRange,
    setRecordKeyword,
    setRecordRedeemType,
    setRecordStatus,
    setRuleConsumeAmountPerStep,
    setRuleConsumeRewardEnabled,
    setRuleConsumeRewardPointsPerStep,
    setRuleExpiryMode,
    setRuleRegisterRewardEnabled,
    setRuleRegisterRewardPoints,
    setRuleReviewRewardEnabled,
    setRuleReviewRewardPoints,
    setRuleSigninRewardEnabled,
    setRuleSigninRewardPoints,
    setSelectedStoreId,
    searchCouponOptions,
    searchPickerProducts,
    setVerifyMethod,
    setVerifyOpen,
    setVerifyRemark,
    storeOptions,
    submitDrawer,
    submitProductPicker,
    submitVerify,
    tabOptions: POINTS_MALL_TAB_OPTIONS,
    toggleNotifyChannel,
    toggleStatus,
    verifyForm,
  };
}
