import type {
  ComponentModelCustomFieldType,
  ComponentModelPiece,
  ComponentModelProduct,
  ComponentModelStructureNode,
} from '../types/inventory'
import { extractFieldValueObject, toStringArray } from './componentStructureSanitize'

export const hydrateCustomFields = (fields: any[]): any[] => {
  if (!Array.isArray(fields)) {
    return []
  }

  return fields.map((field, index) => {
    const valueObject = extractFieldValueObject(field)
    const name = typeof field?.name === 'string'
      ? field.name
      : typeof field?.key === 'string'
        ? field.key
        : ''

    const candidateType =
      typeof field?.type === 'string' && field.type
        ? field.type
        : typeof valueObject?.type === 'string'
          ? valueObject.type
          : ''
    const allowedTypes: ComponentModelCustomFieldType[] = ['text', 'number', 'select', 'boolean', 'date']
    const type = allowedTypes.includes(candidateType as ComponentModelCustomFieldType)
      ? (candidateType as ComponentModelCustomFieldType)
      : 'text'

    const required =
      typeof field?.required === 'boolean'
        ? field.required
        : typeof valueObject?.required === 'boolean'
          ? valueObject.required
          : false

    const options =
      toStringArray(field?.options) ||
      toStringArray(valueObject?.options) ||
      toStringArray((valueObject as any)?.choices) ||
      []

    const optionsText = typeof field?.optionsText === 'string'
      ? field.optionsText
      : options.length
        ? options.join('\n')
        : ''

    const defaultCandidate =
      field?.defaultValue ?? valueObject?.defaultValue ?? field?.value ?? field?.default ?? null
    const resolvedDefault = (() => {
      if (defaultCandidate === undefined || defaultCandidate === null) {
        return undefined
      }
      if (typeof defaultCandidate === 'object') {
        if (defaultCandidate === null) {
          return undefined
        }
        if ('defaultValue' in (defaultCandidate as Record<string, any>)) {
          return (defaultCandidate as Record<string, any>).defaultValue
        }
        if ('value' in (defaultCandidate as Record<string, any>)) {
          return (defaultCandidate as Record<string, any>).value
        }
        return undefined
      }
      return defaultCandidate
    })()
    const defaultValue =
      resolvedDefault !== undefined && resolvedDefault !== null && resolvedDefault !== ''
        ? String(resolvedDefault)
        : ''

    const id = typeof field?.id === 'string' ? field.id : undefined
    const customFieldId = typeof field?.customFieldId === 'string' ? field.customFieldId : undefined
    const orderIndex = typeof field?.orderIndex === 'number' ? field.orderIndex : index

    const machineContextOnly =
      typeof field?.machineContextOnly === 'boolean'
        ? field.machineContextOnly
        : typeof valueObject?.machineContextOnly === 'boolean'
          ? valueObject.machineContextOnly
          : false

    return {
      name,
      type,
      required,
      machineContextOnly,
      options,
      optionsText,
      defaultValue,
      id,
      customFieldId,
      orderIndex,
    }
  })
}

export const hydratePieces = (pieces: any[]): ComponentModelPiece[] => {
  if (!Array.isArray(pieces)) {
    return []
  }

  return pieces.map((piece) => ({
    typePieceId: piece?.typePieceId ?? piece?.typePiece?.id ?? '',
    typePieceLabel: piece?.typePieceLabel ?? piece?.typePiece?.name ?? '',
    reference: piece?.reference ?? '',
    familyCode: piece?.familyCode ?? piece?.typePiece?.code ?? '',
    role: piece?.role ?? '',
    ...(piece?.quantity !== undefined && piece.quantity >= 1 ? { quantity: piece.quantity } : {}),
  }))
}

export const hydrateProducts = (products: any[]): ComponentModelProduct[] => {
  if (!Array.isArray(products)) {
    return []
  }

  return products.map((product) => ({
    typeProductId: product?.typeProductId ?? product?.typeProduct?.id ?? '',
    typeProductLabel: product?.typeProductLabel ?? product?.typeProduct?.name ?? '',
    reference: product?.reference ?? '',
    familyCode: product?.familyCode ?? product?.typeProduct?.code ?? '',
    role: product?.role ?? '',
  }))
}

export const hydrateSubcomponents = (components: any[]): ComponentModelStructureNode[] => {
  if (!Array.isArray(components)) {
    return []
  }

  return components.map((component) => ({
    typeComposantId: component?.typeComposantId ?? component?.typeComposant?.id ?? '',
    typeComposantLabel: component?.typeComposantLabel ?? component?.typeComposant?.name ?? '',
    modelId: component?.modelId ?? '',
    familyCode: component?.familyCode ?? component?.typeComposant?.code ?? '',
    alias: component?.alias ?? component?.name ?? '',
    subcomponents: hydrateSubcomponents(
      Array.isArray(component?.subcomponents)
        ? component.subcomponents
        : component?.subComponents,
    ),
  }))
}

export const mapComponentCustomFields = (fields: any[]) => {
  if (!Array.isArray(fields)) {
    return []
  }
  return hydrateCustomFields(fields).map((field, index) => {
    const defaultValue =
      field?.defaultValue !== undefined && field?.defaultValue !== null && field?.defaultValue !== ''
        ? field.defaultValue
        : null
    return {
      name: typeof field?.name === 'string' ? field.name : '',
      type: field?.type ?? 'text',
      required: !!field?.required,
      machineContextOnly: !!field?.machineContextOnly,
      options: Array.isArray(field?.options) ? field.options : [],
      optionsText: typeof field?.optionsText === 'string' ? field.optionsText : '',
      defaultValue,
      id: typeof (field as any)?.id === 'string' ? (field as any).id : undefined,
      customFieldId:
        typeof (field as any)?.customFieldId === 'string'
          ? (field as any).customFieldId
          : undefined,
      orderIndex: typeof field?.orderIndex === 'number' ? field.orderIndex : index,
    }
  })
}

export const mapComponentPieces = (pieces: any[]): ComponentModelPiece[] => {
  if (!Array.isArray(pieces)) {
    return []
  }
  return pieces.map((piece) => ({
    reference: piece?.reference ?? '',
    typePieceId: piece?.typePieceId ?? piece?.typePiece?.id ?? '',
    typePieceLabel: piece?.typePieceLabel ?? piece?.typePiece?.name ?? '',
    familyCode: piece?.familyCode ?? piece?.typePiece?.code ?? '',
    role: piece?.role ?? '',
    ...(piece?.quantity !== undefined && piece.quantity >= 1 ? { quantity: piece.quantity } : {}),
  }))
}

export const mapComponentProducts = (products: any[]): ComponentModelProduct[] => {
  if (!Array.isArray(products)) {
    return []
  }
  return products.map((product) => ({
    reference: product?.reference ?? '',
    typeProductId: product?.typeProductId ?? product?.typeProduct?.id ?? '',
    typeProductLabel: product?.typeProductLabel ?? product?.typeProduct?.name ?? '',
    familyCode: product?.familyCode ?? product?.typeProduct?.code ?? '',
    role: product?.role ?? '',
  }))
}

export const mapSubcomponents = (components: any[]): ComponentModelStructureNode[] => {
  if (!Array.isArray(components)) {
    return []
  }
  return components.map((component) => ({
    typeComposantId: component?.typeComposantId ?? component?.typeComposant?.id ?? '',
    typeComposantLabel: component?.typeComposantLabel ?? component?.typeComposant?.name ?? '',
    modelId: component?.modelId ?? '',
    familyCode: component?.familyCode ?? component?.typeComposant?.code ?? '',
    alias: component?.alias ?? component?.name ?? '',
    subcomponents: mapSubcomponents(
      Array.isArray(component?.subcomponents)
        ? component.subcomponents
        : component?.subComponents,
    ),
  }))
}
