import type { Ref } from 'vue';
import type { Router } from 'vue-router';

import type {
  ProductAddonGroupDto,
  ProductDetailDto,
  ProductLabelDto,
  ProductSpecDto,
  ProductStatus,
} from '#/api/product';

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

import { uploadTenantFileApi } from '#/api/files';
import {
  deleteProductApi,
  getProductAddonGroupListApi,
  getProductCategoryListApi,
  getProductDetailApi,
  getProductLabelListApi,
  getProductSpecListApi,
  saveProductApi,
} from '#/api/product';

import type {
  ProductDetailCategoryOption,
  ProductDetailFormState,
} from '../../types';

import { DEFAULT_PRODUCT_DETAIL_FORM } from './constants';
import {
  buildLocalSkuCode,
  dedupeTextList,
  normalizeComboGroups,
  normalizeSkuRows,
} from './helpers';

interface CreateProductDetailDataActionsOptions {
  addonGroupOptions: Ref<ProductAddonGroupDto[]>;
  buildSkuRows: () => void;
  categoryOptions: Ref<ProductDetailCategoryOption[]>;
  detail: Ref<null | ProductDetailDto>;
  form: ProductDetailFormState;
  isLoading: Ref<boolean>;
  isSubmitting: Ref<boolean>;
  isUploadingImage: Ref<boolean>;
  labelOptions: Ref<ProductLabelDto[]>;
  productId: Ref<string>;
  router: Router;
  specTemplateOptions: Ref<ProductSpecDto[]>;
  storeId: Ref<string>;
}

export function createProductDetailDataActions(
  options: CreateProductDetailDataActionsOptions,
) {
  const {
    addonGroupOptions,
    buildSkuRows,
    categoryOptions,
    detail,
    form,
    isLoading,
    isSubmitting,
    isUploadingImage,
    labelOptions,
    productId,
    router,
    specTemplateOptions,
    storeId,
  } = options;

  function resetForm() {
    Object.assign(form, {
      ...DEFAULT_PRODUCT_DETAIL_FORM,
      imageUrls: [],
      specTemplateIds: [],
      addonGroupIds: [],
      labelIds: [],
      skus: [],
      comboGroups: [],
    });
  }

  function patchForm(data: ProductDetailDto) {
    form.id = data.id;
    form.name = data.name;
    form.subtitle = data.subtitle;
    form.categoryId = data.categoryId;
    form.kind = data.kind;
    form.description = data.description;
    form.sortWeight = Math.max(0, Number(data.sortWeight || 0));

    form.imageUrls = dedupeTextList([...(data.imageUrls || []), data.imageUrl]).slice(
      0,
      5,
    );

    form.price = Number(data.price || 0);
    form.originalPrice =
      data.originalPrice !== null && data.originalPrice !== undefined
        ? Number(data.originalPrice)
        : null;
    form.stock = Math.max(0, Math.floor(Number(data.stock || 0)));
    form.warningStock =
      data.warningStock !== null && data.warningStock !== undefined
        ? Math.max(0, Math.floor(Number(data.warningStock)))
        : null;
    form.packingFee =
      data.packingFee !== null && data.packingFee !== undefined
        ? Number(data.packingFee)
        : null;

    form.specTemplateIds = dedupeTextList(data.specTemplateIds || []);
    form.addonGroupIds = dedupeTextList(data.addonGroupIds || []);
    form.labelIds = dedupeTextList(data.labelIds || []);

    form.skus = normalizeSkuRows(data.skus || []);
    form.comboGroups = normalizeComboGroups(data.comboGroups || []);

    form.status = data.status;
    if (data.status === 'on_sale') {
      form.shelfMode = 'now';
    } else if (data.timedOnShelfAt) {
      form.shelfMode = 'scheduled';
    } else {
      form.shelfMode = 'draft';
    }
    form.timedOnShelfAt = data.timedOnShelfAt || '';
  }

  function clearPageData() {
    detail.value = null;
    resetForm();
    categoryOptions.value = [];
    specTemplateOptions.value = [];
    addonGroupOptions.value = [];
    labelOptions.value = [];
  }

  function toggleAddonGroup(groupId: string) {
    const selected = new Set(form.addonGroupIds);
    if (selected.has(groupId)) {
      selected.delete(groupId);
    } else {
      selected.add(groupId);
    }
    form.addonGroupIds = [...selected];
  }

  function toggleLabel(labelId: string) {
    const selected = new Set(form.labelIds);
    if (selected.has(labelId)) {
      selected.delete(labelId);
    } else {
      selected.add(labelId);
    }
    form.labelIds = [...selected];
  }

  async function uploadImage(file: File) {
    isUploadingImage.value = true;
    try {
      const uploaded = await uploadTenantFileApi(file, 'dish_image');
      const url = String(uploaded.url || '').trim();
      if (!url) {
        message.error('图片上传失败');
        return;
      }
      form.imageUrls = dedupeTextList([...form.imageUrls, url]).slice(0, 5);
      message.success('图片上传成功');
    } catch (error) {
      console.error(error);
    } finally {
      isUploadingImage.value = false;
    }
  }

  function removeImage(index: number) {
    if (index < 0 || index >= form.imageUrls.length) return;
    form.imageUrls = form.imageUrls.filter((_, itemIndex) => itemIndex !== index);
  }

  function setPrimaryImage(index: number) {
    if (index <= 0 || index >= form.imageUrls.length) return;
    const next = [...form.imageUrls];
    const [picked] = next.splice(index, 1);
    if (!picked) return;
    form.imageUrls = [picked, ...next];
  }

  async function loadDetail() {
    if (!storeId.value || !productId.value) {
      clearPageData();
      return;
    }

    isLoading.value = true;
    try {
      const [detailData, categories, specs, addons, labels] = await Promise.all([
        getProductDetailApi({
          storeId: storeId.value,
          productId: productId.value,
        }),
        getProductCategoryListApi(storeId.value),
        getProductSpecListApi({ storeId: storeId.value }),
        getProductAddonGroupListApi({ storeId: storeId.value }),
        getProductLabelListApi({ storeId: storeId.value }),
      ]);

      detail.value = detailData;
      categoryOptions.value = categories.map((item) => ({
        label: item.name,
        value: item.id,
      }));
      specTemplateOptions.value = specs;
      addonGroupOptions.value = addons;
      labelOptions.value = labels;

      patchForm(detailData);
      buildSkuRows();
    } catch (error) {
      console.error(error);
      clearPageData();
    } finally {
      isLoading.value = false;
    }
  }

  async function saveDetail() {
    if (!storeId.value || !form.id) return;
    if (!form.name.trim()) {
      message.warning('请输入商品名称');
      return;
    }
    if (!form.categoryId) {
      message.warning('请选择商品分类');
      return;
    }
    if (form.shelfMode === 'scheduled' && !form.timedOnShelfAt) {
      message.warning('请选择定时上架时间');
      return;
    }

    if (form.kind === 'combo') {
      if (form.comboGroups.length === 0) {
        message.warning('套餐至少需要一个分组');
        return;
      }

      for (const group of form.comboGroups) {
        if (!group.name.trim()) {
          message.warning('请填写套餐分组名称');
          return;
        }
        if (group.items.length === 0) {
          message.warning(`分组「${group.name}」至少需要一个商品`);
          return;
        }
        if (group.maxSelect < group.minSelect) {
          message.warning(`分组「${group.name}」最大选择数不能小于最小选择数`);
          return;
        }
      }
    }

    for (const sku of form.skus) {
      if (sku.price < 0 || sku.stock < 0) {
        message.warning('SKU 的售价和库存不能小于 0');
        return;
      }
    }

    isSubmitting.value = true;
    try {
      const saved = await saveProductApi({
        id: form.id,
        storeId: storeId.value,
        categoryId: form.categoryId,
        kind: form.kind,
        name: form.name.trim(),
        subtitle: form.subtitle.trim(),
        description: form.description.trim(),
        price: Number(Number(form.price || 0).toFixed(2)),
        originalPrice:
          form.originalPrice !== null &&
          form.originalPrice !== undefined &&
          Number(form.originalPrice) > 0
            ? Number(Number(form.originalPrice).toFixed(2))
            : null,
        stock: Math.max(0, Math.floor(Number(form.stock || 0))),
        status: form.status,
        shelfMode: form.shelfMode,
        timedOnShelfAt:
          form.shelfMode === 'scheduled' && form.timedOnShelfAt
            ? form.timedOnShelfAt
            : undefined,
        imageUrls: [...form.imageUrls],
        sortWeight: Math.max(0, Math.floor(Number(form.sortWeight || 0))),
        warningStock:
          form.warningStock !== null && form.warningStock !== undefined
            ? Math.max(0, Math.floor(Number(form.warningStock)))
            : null,
        packingFee:
          form.packingFee !== null && form.packingFee !== undefined
            ? Math.max(0, Number(Number(form.packingFee).toFixed(2)))
            : null,
        specTemplateIds: [...form.specTemplateIds],
        addonGroupIds: [...form.addonGroupIds],
        labelIds: [...form.labelIds],
        skus: form.skus.map((item, index) => ({
          skuCode: item.skuCode || buildLocalSkuCode(index + 1),
          price: Math.max(0, Number(Number(item.price || 0).toFixed(2))),
          originalPrice:
            item.originalPrice !== null &&
            item.originalPrice !== undefined &&
            Number(item.originalPrice) > 0
              ? Number(Number(item.originalPrice).toFixed(2))
              : null,
          stock: Math.max(0, Math.floor(Number(item.stock || 0))),
          isEnabled: item.isEnabled,
          sortOrder: Math.max(1, Math.floor(Number(item.sortOrder || index + 1))),
          attributes: item.attributes.map((attr) => ({
            templateId: attr.templateId,
            optionId: attr.optionId,
          })),
        })),
        comboGroups:
          form.kind === 'combo'
            ? form.comboGroups.map((group, groupIndex) => ({
                name: group.name.trim(),
                minSelect: Math.max(1, Math.floor(Number(group.minSelect || 1))),
                maxSelect: Math.max(1, Math.floor(Number(group.maxSelect || 1))),
                sortOrder: Math.max(
                  1,
                  Math.floor(Number(group.sortOrder || groupIndex + 1)),
                ),
                items: group.items.map((item, itemIndex) => ({
                  productId: item.productId,
                  quantity: Math.max(1, Math.floor(Number(item.quantity || 1))),
                  sortOrder: Math.max(
                    1,
                    Math.floor(Number(item.sortOrder || itemIndex + 1)),
                  ),
                })),
              }))
            : [],
        tags: [],
      });

      detail.value = saved;
      patchForm(saved);
      buildSkuRows();
      message.success('商品详情已保存');
    } catch (error) {
      console.error(error);
    } finally {
      isSubmitting.value = false;
    }
  }

  async function toggleSaleStatus(next: ProductStatus) {
    if (next !== 'on_sale' && next !== 'off_shelf') return;
    form.status = next;
    form.shelfMode = next === 'on_sale' ? 'now' : 'draft';
    await saveDetail();
  }

  function setShelfMode(mode: 'draft' | 'now' | 'scheduled') {
    form.shelfMode = mode;
    form.status = mode === 'now' ? 'on_sale' : 'off_shelf';
  }

  async function deleteCurrentProduct() {
    if (!storeId.value || !form.id) return;
    await deleteProductApi({
      storeId: storeId.value,
      productId: form.id,
    });
    message.success('商品已删除');
    router.push('/product/list');
  }

  return {
    deleteCurrentProduct,
    loadDetail,
    removeImage,
    saveDetail,
    setPrimaryImage,
    setShelfMode,
    toggleAddonGroup,
    toggleLabel,
    toggleSaleStatus,
    uploadImage,
  };
}
