import type {
  ProductDetailComboGroupItemState,
  ProductDetailComboGroupState,
  ProductDetailSkuAttrState,
  ProductDetailSkuRowState,
} from '../../types';

import type { ProductDetailDto, ProductSkuDto } from '#/api/product';

interface ProductDetailSkuTemplateInput {
  id: string;
  name: string;
  options: Array<{ id: string; name: string }>;
}

export function dedupeTextList(source: string[]) {
  return source
    .map((item) => String(item || '').trim())
    .filter(Boolean)
    .filter((item, index, list) => list.indexOf(item) === index);
}

export function buildSkuCombinations(
  templates: ProductDetailSkuTemplateInput[],
) {
  if (templates.length === 0) return [];

  const combos: ProductDetailSkuAttrState[][] = [];
  const walk = (depth: number, chain: ProductDetailSkuAttrState[]) => {
    if (depth >= templates.length) {
      combos.push([...chain]);
      return;
    }
    const current = templates[depth];
    if (!current) {
      return;
    }
    for (const option of current.options) {
      walk(depth + 1, [
        ...chain,
        {
          templateId: current.id,
          optionId: option.id,
        },
      ]);
    }
  };

  walk(0, []);
  return combos;
}

export function buildSkuKey(attrs: ProductDetailSkuAttrState[]) {
  if (attrs.length === 0) return 'default';
  return attrs
    .toSorted((a, b) => {
      if (a.templateId === b.templateId) {
        return a.optionId.localeCompare(b.optionId);
      }
      return a.templateId.localeCompare(b.templateId);
    })
    .map((item) => `${item.templateId}:${item.optionId}`)
    .join('|');
}

export function normalizeSkuRows(source: ProductSkuDto[]) {
  const rows = source.map(
    (item, index): ProductDetailSkuRowState => ({
      id: item.id || '',
      skuCode: item.skuCode || '',
      price: Number(item.price || 0),
      originalPrice:
        item.originalPrice !== null && item.originalPrice !== undefined
          ? Number(item.originalPrice)
          : null,
      stock: Math.max(0, Math.floor(Number(item.stock || 0))),
      isEnabled: item.isEnabled !== false,
      sortOrder: Math.max(1, Math.floor(Number(item.sortOrder || index + 1))),
      attributes: (item.attributes || [])
        .map((attr) => ({
          templateId: String(attr.templateId || '').trim(),
          optionId: String(attr.optionId || '').trim(),
        }))
        .filter((attr) => attr.templateId && attr.optionId),
    }),
  );

  return rows.toSorted((a, b) => a.sortOrder - b.sortOrder);
}

export function normalizeComboGroups(
  source: ProductDetailDto['comboGroups'],
): ProductDetailComboGroupState[] {
  return source.map(
    (group, groupIndex): ProductDetailComboGroupState => ({
      name: String(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): ProductDetailComboGroupItemState => ({
          productId: String(item.productId || '').trim(),
          productName: String(item.productName || '').trim(),
          quantity: Math.max(1, Math.floor(Number(item.quantity || 1))),
          sortOrder: Math.max(
            1,
            Math.floor(Number(item.sortOrder || itemIndex + 1)),
          ),
        }),
      ),
    }),
  );
}
