/**
 * Machine detail — product display sub-composable.
 *
 * Handles product resolution, display helpers, supplier info,
 * and machine-level direct product links.
 */

import { computed } from 'vue'
import { useProducts } from '~/composables/useProducts'
import {
  resolveProductReference as _resolveProductReference,
  getProductDisplay as _getProductDisplay,
  getProductSuppliersLabel,
  getProductPriceLabel,
} from '~/shared/utils/productDisplayUtils'
import {
  resolveConstructeurs,
  uniqueConstructeurIds,
} from '~/shared/constructeurUtils'

type AnyRecord = Record<string, unknown>

interface MachineDetailProductsDeps {
  machineProductLinks: Ref<AnyRecord[]>
  productDocumentsMap: Ref<Map<string, AnyRecord[]>>
  constructeurs: Ref<unknown[]>
}

export function useMachineDetailProducts(deps: MachineDetailProductsDeps) {
  const { machineProductLinks, productDocumentsMap, constructeurs } = deps
  const { products, loadProducts } = useProducts()

  // ---------------------------------------------------------------------------
  // Computed
  // ---------------------------------------------------------------------------

  const productInventory = computed(() => products.value || [])

  const productById = computed(() => {
    const map = new Map<string, AnyRecord>()
    ;(productInventory.value as AnyRecord[]).forEach((product: AnyRecord) => {
      if (product?.id) map.set(product.id as string, product)
    })
    return map
  })

  // ---------------------------------------------------------------------------
  // Helpers
  // ---------------------------------------------------------------------------

  const findProductById = (productId: string | null | undefined): AnyRecord | null => {
    if (!productId) return null
    return productById.value.get(productId) || null
  }

  const resolveProductReference = (source: AnyRecord) =>
    _resolveProductReference(source, findProductById as any)
  const getProductDisplay = (source: AnyRecord) =>
    _getProductDisplay(source, findProductById as any)

  // ---------------------------------------------------------------------------
  // Machine direct products
  // ---------------------------------------------------------------------------

  const machineDirectProducts = computed(() => {
    return machineProductLinks.value.map((link) => {
      const productObj = link.product as AnyRecord | string | null
      let resolved: AnyRecord | null = null
      let productId: string | null = null

      if (typeof productObj === 'string') {
        productId = productObj.split('/').pop() || null
        resolved = productId ? findProductById(productId) : null
      } else if (productObj && typeof productObj === 'object') {
        productId = (productObj as AnyRecord)?.id as string | null
        // Prefer the embedded product from the structure endpoint — it has richer
        // data (typeProduct as object, supplierPrice, constructeurs) than the
        // global products cache which may store typeProduct as an IRI string.
        const cached = productId ? findProductById(productId) : null
        resolved = productObj as AnyRecord
        if (cached) {
          // Merge: use embedded as base, overlay any non-null cached fields
          resolved = { ...resolved, ...Object.fromEntries(
            Object.entries(cached as AnyRecord).filter(([, v]) => v != null && v !== ''),
          ) }
          // But always prefer the embedded typeProduct when it's an object
          if (productObj.typeProduct && typeof productObj.typeProduct === 'object') {
            resolved.typeProduct = productObj.typeProduct
          }
        }
      }

      const cIds = uniqueConstructeurIds(
        resolved?.constructeurs,
        resolved?.constructeurIds,
      )
      const resolvedConstructeurs = resolveConstructeurs(
        cIds,
        resolved?.constructeurs as any[] || [],
        constructeurs.value as any,
      )

      return {
        id: (resolved?.id as string) || productId || null,
        linkId: (link.id as string) || (typeof link['@id'] === 'string' ? link['@id'].split('/').pop() : null) || null,
        name: (resolved?.name as string) || (link.modelType as AnyRecord)?.name as string || 'Produit inconnu',
        reference: (resolved?.reference as string) || null,
        supplierLabel: resolvedConstructeurs.length
          ? resolvedConstructeurs.map((c) => c.name).filter(Boolean).join(', ') || null
          : getProductSuppliersLabel(resolved),
        priceLabel: resolved ? getProductPriceLabel(resolved) : null,
        groupLabel: ((resolved?.typeProduct as AnyRecord)?.name as string) || '',
        documents: productId ? (productDocumentsMap.value.get(productId) || []) : [],
        pendingEntity: (link.pendingEntity as boolean) || false,
        modelTypeId: (link.modelTypeId as string) || null,
        modelType: (link.modelType as string) || null,
      }
    })
  })

  return {
    // Computed
    productInventory,
    productById,
    machineDirectProducts,

    // Helpers
    findProductById,
    resolveProductReference,
    getProductDisplay,

    // Loading
    loadProducts,
  }
}
