import type { PieceModelProduct, PieceModelStructure } from '~/shared/types/inventory'

/**
 * Extract the products array from a piece model structure, defaulting to [].
 */
export const getStructureProducts = (structure: PieceModelStructure | null): PieceModelProduct[] =>
  Array.isArray(structure?.products) ? structure.products : []

/**
 * Build a human-readable label for a single product requirement.
 */
export const describeProductRequirement = (requirement: PieceModelProduct, index: number): string => {
  if (!requirement) {
    return `Produit ${index + 1}`
  }
  const parts: string[] = []
  if (requirement.role) {
    parts.push(requirement.role)
  }
  if (requirement.typeProductLabel) {
    parts.push(requirement.typeProductLabel)
  } else if (requirement.typeProductId) {
    parts.push(`Catégorie #${requirement.typeProductId}`)
  }
  if (requirement.familyCode) {
    parts.push(`Famille ${requirement.familyCode}`)
  }
  if (parts.length === 0) {
    parts.push(`Produit ${index + 1}`)
  }
  return parts.join(' • ')
}

/**
 * Build description strings for every product requirement in a structure.
 */
export const buildProductRequirementDescriptions = (
  products: PieceModelProduct[],
): string[] =>
  products.map((requirement, index) => describeProductRequirement(requirement, index))

/**
 * Build the entry objects used to render product selection inputs.
 */
export const buildProductRequirementEntries = (
  products: PieceModelProduct[],
  keyPrefix: string,
) =>
  products.map((requirement, index) => ({
    index,
    key: `${keyPrefix}-${index}-${requirement?.typeProductId || 'any'}`,
    label: describeProductRequirement(requirement, index),
    typeProductId: requirement?.typeProductId ? String(requirement.typeProductId) : null,
  }))

/**
 * Resize the selections array to match the expected count, preserving existing values.
 */
export const resizeProductSelections = (
  current: (string | null)[],
  count: number,
): (string | null)[] =>
  Array.from({ length: count }, (_, index) => current[index] ?? null)

/**
 * Return true when all required product slots have a non-empty string value,
 * or when no product selection is required.
 */
export const areProductSelectionsFilled = (
  requiresSelection: boolean,
  entries: { index: number }[],
  selections: (string | null)[],
): boolean =>
  !requiresSelection ||
  entries.every((entry) => {
    const value = selections[entry.index]
    return typeof value === 'string' && value.trim().length > 0
  })

/**
 * Set a single product selection by index, returning a new array.
 */
export const applyProductSelection = (
  current: (string | null)[],
  index: number,
  value: string | null,
): (string | null)[] => {
  const normalized = typeof value === 'string' ? value : null
  const next = [...current]
  next[index] = normalized
  return next
}

/**
 * Extract normalized product IDs from the current selections based on requirement entries.
 */
export const collectNormalizedProductIds = (
  entries: { index: number }[],
  selections: (string | null)[],
): string[] =>
  entries
    .map((entry) => selections[entry.index])
    .filter((value): value is string => typeof value === 'string' && value.trim().length > 0)
    .map((value) => value.trim())
