import type { Ref } from 'vue';

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

import type { ProductPickerItemDto } from '#/api/product';

import { computed } from 'vue';

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

interface CreateProductDetailComboActionsOptions {
  comboPickerCurrentGroupIndex: Ref<number>;
  comboPickerKeyword: Ref<string>;
  comboPickerLoading: Ref<boolean>;
  comboPickerOpen: Ref<boolean>;
  comboPickerProducts: Ref<ProductPickerItemDto[]>;
  comboPickerSelectedIds: Ref<string[]>;
  form: ProductDetailFormState;
  storeId: Ref<string>;
}

export function createProductDetailComboActions(
  options: CreateProductDetailComboActionsOptions,
) {
  const {
    comboPickerCurrentGroupIndex,
    comboPickerKeyword,
    comboPickerLoading,
    comboPickerOpen,
    comboPickerProducts,
    comboPickerSelectedIds,
    form,
    storeId,
  } = options;

  const comboPickerSelectedProducts = computed(() =>
    comboPickerProducts.value.filter((item) =>
      comboPickerSelectedIds.value.includes(item.id),
    ),
  );

  function addComboGroup() {
    form.comboGroups.push({
      name: '',
      minSelect: 1,
      maxSelect: 1,
      sortOrder: form.comboGroups.length + 1,
      items: [],
    });
  }

  function removeComboGroup(groupIndex: number) {
    if (groupIndex < 0 || groupIndex >= form.comboGroups.length) return;
    form.comboGroups = form.comboGroups.filter(
      (_, index) => index !== groupIndex,
    );
    form.comboGroups.forEach((group, index) => {
      group.sortOrder = index + 1;
    });
  }

  function removeComboItem(groupIndex: number, itemIndex: number) {
    const group = form.comboGroups[groupIndex];
    if (!group) return;
    group.items = group.items.filter((_, index) => index !== itemIndex);
    group.items.forEach((item, index) => {
      item.sortOrder = index + 1;
    });
  }

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

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

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

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

  function setComboPickerOpen(value: boolean) {
    comboPickerOpen.value = value;
    if (!value) {
      comboPickerCurrentGroupIndex.value = -1;
      comboPickerSelectedIds.value = [];
      comboPickerKeyword.value = '';
      comboPickerProducts.value = [];
    }
  }

  async function searchComboPicker() {
    if (!storeId.value) return;
    comboPickerLoading.value = true;
    try {
      const products = await searchProductPickerApi({
        storeId: storeId.value,
        keyword: comboPickerKeyword.value.trim() || undefined,
        limit: 100,
      });
      comboPickerProducts.value = products.filter(
        (item) => item.id !== form.id,
      );
    } catch (error) {
      console.error(error);
      comboPickerProducts.value = [];
    } finally {
      comboPickerLoading.value = false;
    }
  }

  async function openComboPicker(groupIndex: number) {
    const group = form.comboGroups[groupIndex];
    if (!group) return;
    comboPickerCurrentGroupIndex.value = groupIndex;
    comboPickerSelectedIds.value = group.items.map((item) => item.productId);
    setComboPickerOpen(true);
    await searchComboPicker();
  }

  function toggleComboPickerProduct(productId: string) {
    const selected = new Set(comboPickerSelectedIds.value);
    if (selected.has(productId)) {
      selected.delete(productId);
    } else {
      selected.add(productId);
    }
    comboPickerSelectedIds.value = [...selected];
  }

  function submitComboPicker() {
    const groupIndex = comboPickerCurrentGroupIndex.value;
    const group = form.comboGroups[groupIndex];
    if (!group) {
      setComboPickerOpen(false);
      return;
    }

    const currentItemMap = new Map(
      group.items.map((item) => [item.productId, item]),
    );

    const selectedProducts = comboPickerSelectedProducts.value;
    group.items = selectedProducts.map((product, index) => {
      const cached = currentItemMap.get(product.id);
      return {
        productId: product.id,
        productName: product.name,
        quantity: cached?.quantity ?? 1,
        sortOrder: index + 1,
      };
    });

    setComboPickerOpen(false);
  }

  return {
    addComboGroup,
    comboPickerSelectedProducts,
    openComboPicker,
    removeComboGroup,
    removeComboItem,
    searchComboPicker,
    setComboGroupMaxSelect,
    setComboGroupMinSelect,
    setComboGroupName,
    setComboItemQuantity,
    setComboPickerOpen,
    submitComboPicker,
    toggleComboPickerProduct,
  };
}
