/**
 * Machine detail — hierarchy & link management sub-composable.
 *
 * Handles machine hierarchy building, component/piece tree resolution,
 * flatten helpers, find-by-id utilities, and structure link CRUD.
 */

import { ref, computed } from 'vue'
import { useApi } from '~/composables/useApi'
import { useToast } from '~/composables/useToast'
import {
  resolveIdentifier,
} from '~/shared/utils/productDisplayUtils'
import {
  buildMachineHierarchyFromLinks,
  resolveLinkArray,
} from '~/composables/useMachineHierarchy'

type AnyRecord = Record<string, unknown>

interface MachineDetailHierarchyDeps {
  machineId: string
  machine: Ref<AnyRecord | null>
  constructeurs: Ref<unknown[]>
  findProductById: (id: string | null | undefined) => AnyRecord | null
  transformComponentCustomFields: (data: AnyRecord[]) => AnyRecord[]
  transformCustomFields: (data: AnyRecord[]) => AnyRecord[]
  syncMachineCustomFields: () => void
}

export function useMachineDetailHierarchy(deps: MachineDetailHierarchyDeps) {
  const {
    machineId,
    machine,
    constructeurs,
    findProductById,
    transformComponentCustomFields,
    transformCustomFields,
    syncMachineCustomFields,
  } = deps

  const { get, post: apiPost, delete: apiDel, patch: apiPatch } = useApi()
  const toast = useToast()

  // ---------------------------------------------------------------------------
  // State
  // ---------------------------------------------------------------------------

  const components = ref<AnyRecord[]>([])
  const pieces = ref<AnyRecord[]>([])
  const machineComponentLinks = ref<AnyRecord[]>([])
  const machinePieceLinks = ref<AnyRecord[]>([])
  const machineProductLinks = ref<AnyRecord[]>([])

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

  const flattenComponents = (list: AnyRecord[] = []): AnyRecord[] => {
    const result: AnyRecord[] = []
    const traverse = (items: AnyRecord[]) => {
      items.forEach((item) => {
        result.push(item)
        if (Array.isArray(item.subComponents) && item.subComponents.length) {
          traverse(item.subComponents as AnyRecord[])
        }
      })
    }
    traverse(list)
    return result
  }

  const findComponentById = (items: AnyRecord[] | undefined, id: string): AnyRecord | null => {
    for (const item of items || []) {
      if (item.id === id) return item
      const found = findComponentById(item.subComponents as AnyRecord[] | undefined, id)
      if (found) return found
    }
    return null
  }

  const findPieceById = (pieceId: string): AnyRecord | null => {
    const direct = pieces.value.find((p) => p.id === pieceId)
    if (direct) return direct

    const searchInComponents = (items: AnyRecord[]): AnyRecord | null => {
      for (const item of items || []) {
        const match = ((item.pieces as AnyRecord[]) || []).find((p) => p.id === pieceId)
        if (match) return match
        const nested = searchInComponents((item.subComponents as AnyRecord[]) || [])
        if (nested) return nested
      }
      return null
    }
    return searchInComponents(components.value)
  }

  // ---------------------------------------------------------------------------
  // Hierarchy & links
  // ---------------------------------------------------------------------------

  const applyMachineLinks = (source: AnyRecord): boolean => {
    const container = (source?.machine as AnyRecord) ?? null
    const componentLinksData =
      resolveLinkArray(source, ['componentLinks', 'machineComponentLinks']) ??
      resolveLinkArray(container, ['componentLinks', 'machineComponentLinks'])
    const pieceLinksData =
      resolveLinkArray(source, ['pieceLinks', 'machinePieceLinks']) ??
      resolveLinkArray(container, ['pieceLinks', 'machinePieceLinks'])
    const productLinksData =
      resolveLinkArray(source, ['productLinks', 'machineProductLinks']) ??
      resolveLinkArray(container, ['productLinks', 'machineProductLinks'])

    if (componentLinksData === null && pieceLinksData === null && productLinksData === null) {
      return false
    }

    const normalizedComponentLinks = (componentLinksData ?? []) as AnyRecord[]
    const normalizedPieceLinks = (pieceLinksData ?? []) as AnyRecord[]
    const normalizedProductLinks = (productLinksData ?? []) as AnyRecord[]

    machineComponentLinks.value = normalizedComponentLinks
    machinePieceLinks.value = normalizedPieceLinks
    machineProductLinks.value = normalizedProductLinks

    const { components: hierarchy, machinePieces: machineLevelPieces } =
      buildMachineHierarchyFromLinks(
        normalizedComponentLinks,
        normalizedPieceLinks,
        findProductById as any,
        constructeurs.value as any,
      )

    components.value = transformComponentCustomFields(hierarchy as AnyRecord[])
    pieces.value = transformCustomFields(machineLevelPieces as AnyRecord[])

    return true
  }

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

  const flattenedComponents = computed(() => flattenComponents(components.value))

  const machinePieces = computed(() => {
    return pieces.value.filter((piece) => {
      const parentLinkId = resolveIdentifier(
        piece.parentComponentLinkId,
        (piece.machinePieceLink as AnyRecord)?.parentComponentLinkId,
        piece.parentLinkId,
      )
      if (parentLinkId) return false
      return !piece.composantId
    })
  })

  // ---------------------------------------------------------------------------
  // Structure reload
  // ---------------------------------------------------------------------------

  const reloadMachineStructure = async () => {
    const result: any = await get(`/machines/${machineId}/structure`)
    if (result.success) {
      const machinePayload =
        result.data?.machine && typeof result.data.machine === 'object'
          ? result.data.machine
          : result.data
      if (machinePayload && typeof machinePayload === 'object') {
        machine.value = {
          ...machine.value,
          ...machinePayload,
          documents: machinePayload.documents || (machine.value as AnyRecord)?.documents || [],
          customFieldValues: machinePayload.customFieldValues || (machine.value as AnyRecord)?.customFieldValues || [],
        }
        const linksApplied = applyMachineLinks(result.data)
        if (linksApplied && machine.value) {
          machine.value.componentLinks = machineComponentLinks.value
          machine.value.pieceLinks = machinePieceLinks.value
          machine.value.productLinks = machineProductLinks.value
        }
        syncMachineCustomFields()
      }
    }
  }

  // ---------------------------------------------------------------------------
  // Structure link CRUD
  // ---------------------------------------------------------------------------

  const addComponentLink = async (composantId: string) => {
    const result: any = await apiPost('/machine_component_links', {
      machine: `/api/machines/${machineId}`,
      composant: `/api/composants/${composantId}`,
    })
    if (result.success) {
      toast.showSuccess('Composant ajouté à la machine')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de l\'ajout du composant')
    }
    return result
  }

  const removeComponentLink = async (linkId: string) => {
    const result: any = await apiDel(`/machine_component_links/${linkId}`)
    if (result.success) {
      toast.showSuccess('Composant retiré de la machine')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de la suppression du composant')
    }
    return result
  }

  const addPieceLink = async (pieceId: string, parentComponentLinkId?: string) => {
    const payload: any = {
      machine: `/api/machines/${machineId}`,
      piece: `/api/pieces/${pieceId}`,
    }
    if (parentComponentLinkId) {
      payload.parentLink = `/api/machine_component_links/${parentComponentLinkId}`
    }
    const result: any = await apiPost('/machine_piece_links', payload)
    if (result.success) {
      toast.showSuccess('Pièce ajoutée à la machine')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de l\'ajout de la pièce')
    }
    return result
  }

  const removePieceLink = async (linkId: string) => {
    const result: any = await apiDel(`/machine_piece_links/${linkId}`)
    if (result.success) {
      toast.showSuccess('Pièce retirée de la machine')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de la suppression de la pièce')
    }
    return result
  }

  const addProductLink = async (productId: string, parentComponentLinkId?: string, parentPieceLinkId?: string) => {
    const payload: any = {
      machine: `/api/machines/${machineId}`,
      product: `/api/products/${productId}`,
    }
    if (parentComponentLinkId) {
      payload.parentComponentLink = `/api/machine_component_links/${parentComponentLinkId}`
    }
    if (parentPieceLinkId) {
      payload.parentPieceLink = `/api/machine_piece_links/${parentPieceLinkId}`
    }
    const result: any = await apiPost('/machine_product_links', payload)
    if (result.success) {
      toast.showSuccess('Produit ajouté à la machine')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de l\'ajout du produit')
    }
    return result
  }

  const addComponentLinkCategoryOnly = async (modelTypeId: string) => {
    const result: any = await apiPost('/machine_component_links', {
      machine: `/api/machines/${machineId}`,
      modelType: `/api/model_types/${modelTypeId}`,
    })
    if (result.success) {
      toast.showSuccess('Catégorie ajoutée — item à remplir')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de l\'ajout')
    }
  }

  const addPieceLinkCategoryOnly = async (modelTypeId: string) => {
    const result: any = await apiPost('/machine_piece_links', {
      machine: `/api/machines/${machineId}`,
      modelType: `/api/model_types/${modelTypeId}`,
    })
    if (result.success) {
      toast.showSuccess('Catégorie ajoutée — item à remplir')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de l\'ajout')
    }
  }

  const addProductLinkCategoryOnly = async (modelTypeId: string) => {
    const result: any = await apiPost('/machine_product_links', {
      machine: `/api/machines/${machineId}`,
      modelType: `/api/model_types/${modelTypeId}`,
    })
    if (result.success) {
      toast.showSuccess('Catégorie ajoutée — item à remplir')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de l\'ajout')
    }
  }

  const fillEntityLink = async (linkId: string, entityId: string, entityKind: string) => {
    let endpoint = ''
    let payload: Record<string, string> = {}

    if (entityKind === 'component') {
      endpoint = `/machine_component_links/${linkId}`
      payload = { composant: `/api/composants/${entityId}` }
    } else if (entityKind === 'piece') {
      endpoint = `/machine_piece_links/${linkId}`
      payload = { piece: `/api/pieces/${entityId}` }
    } else {
      endpoint = `/machine_product_links/${linkId}`
      payload = { product: `/api/products/${entityId}` }
    }

    const result: any = await apiPatch(endpoint, payload)
    if (result.success) {
      toast.showSuccess('Item associé avec succès')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de l\'association')
    }
  }

  const removeProductLink = async (linkId: string) => {
    const result: any = await apiDel(`/machine_product_links/${linkId}`)
    if (result.success) {
      toast.showSuccess('Produit retiré de la machine')
      await reloadMachineStructure()
    } else {
      toast.showError('Erreur lors de la suppression du produit')
    }
    return result
  }

  return {
    // State
    components,
    pieces,
    machineComponentLinks,
    machinePieceLinks,
    machineProductLinks,

    // Computed
    flattenedComponents,
    machinePieces,

    // Helpers
    flattenComponents,
    findComponentById,
    findPieceById,

    // Hierarchy
    applyMachineLinks,

    // Structure link management
    reloadMachineStructure,
    addComponentLink,
    removeComponentLink,
    addPieceLink,
    removePieceLink,
    addProductLink,
    addComponentLinkCategoryOnly,
    addPieceLinkCategoryOnly,
    addProductLinkCategoryOnly,
    fillEntityLink,
    removeProductLink,
  }
}
