<template>
  <main class="container mx-auto px-6 py-8">
    <!-- Loading State -->
    <div v-if="loading" class="flex justify-center items-center py-12">
      <span class="loading loading-spinner loading-lg"></span>
    </div>

    <!-- Machine Details -->
    <div v-else-if="machine" ref="printAreaRef" class="space-y-8">
      <DocumentPreviewModal
        :document="previewDocument"
        :visible="previewVisible"
        @close="closePreview"
      />

      <!-- Header with Edit Button -->
      <div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
        <h1 class="text-3xl font-bold">Détails de la machine</h1>
        <div class="flex items-center gap-2 print:hidden" data-print-hide>
          <button 
            @click="toggleEditMode" 
            class="btn btn-primary btn-sm"
            :class="{ 'btn-outline': isEditMode }"
          >
            <IconLucideSquarePen
              v-if="!isEditMode"
              class="w-4 h-4 mr-2"
              aria-hidden="true"
            />
            <IconLucideCheck
              v-else
              class="w-4 h-4 mr-2"
              aria-hidden="true"
            />
            <span class="text-sm">
              {{ isEditMode ? 'Quitter le mode édition' : 'Activer le mode édition' }}
            </span>
          </button>

          <button
            type="button"
            class="btn btn-ghost btn-sm"
            @click="toggleAllComponents"
          >
            <IconLucideChevronDown
              class="w-4 h-4 mr-2 transform transition-transform"
              :class="componentsCollapsed ? '-rotate-90' : 'rotate-0'"
              aria-hidden="true"
            />
            <span class="text-sm">
              {{ componentsCollapsed ? 'Tout déplier' : 'Tout replier' }}
            </span>
          </button>

          <button
            type="button"
            class="btn btn-outline btn-sm"
            @click="openPrintModal"
          >
            <IconLucidePrinter class="w-4 h-4 mr-2" aria-hidden="true" />
            <span class="text-sm">Imprimer</span>
          </button>
        </div>

        <!-- Components Tree -->
        <ComponentHierarchy 
          :components="components"
          :is-edit-mode="isEditMode"
          :collapse-all="componentsCollapsed"
          :toggle-token="collapseToggleToken"
          @update="updateComponent"
          @edit-piece="updatePieceFromComponent"
        />
      </div>

      <!-- Machine Pieces Section -->
      <div class="card bg-base-100 shadow-lg">
        <div class="card-body">
          <div class="flex justify-between items-center mb-4">
            <h2 class="card-title">Pièces de la machine</h2>
          </div>

          <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            <PieceItem 
              v-for="piece in machinePieces" 
              :key="piece.id"
              :piece="piece"
              :is-edit-mode="isEditMode"
              @update="updatePieceInfo"
              @edit="editPiece"
              @custom-field-update="updatePieceCustomField"
            />
          </div>
        </div>
      </div>
    </div>

    <!-- Error State -->
    <div v-else class="text-center py-12">
      <div class="max-w-md mx-auto">
        <IconLucideAlertTriangle class="w-16 h-16 mx-auto text-gray-400 mb-4" aria-hidden="true" />
        <h3 class="text-lg font-medium text-gray-900 mb-2">Machine non trouvée</h3>
        <p class="text-gray-500 mb-4">La machine avec l'ID "{{ machineId }}" n'existe pas ou a été supprimée.</p>
        <NuxtLink to="/machines" class="btn btn-primary">
          Retour aux machines
        </NuxtLink>
      </div>
    </div>
  </main>

  <MachinePrintSelectionModal
    :open="printModalOpen"
    :selection="printSelection"
    :components="components"
    :pieces="machinePieces"
    @close="closePrintModal"
    @confirm="handlePrintConfirm"
    @select-all="setAllPrintSelection(true)"
    @deselect-all="setAllPrintSelection(false)"
  />
</template>

<script setup>
import { ref, reactive, onMounted, computed, watch, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { useMachines } from '~/composables/useMachines'
import { useComposants } from '~/composables/useComposants'
import { usePieces } from '~/composables/usePieces'
import { useCustomFields } from '~/composables/useCustomFields'
import { useApi } from '~/composables/useApi'
import { useToast } from '~/composables/useToast'
import { useDocuments } from '~/composables/useDocuments'
import { getFileIcon } from '~/utils/fileIcons'
import { canPreviewDocument } from '~/utils/documentPreview'
import ComponentHierarchy from '~/components/ComponentHierarchy.vue'
import DocumentUpload from '~/components/DocumentUpload.vue'
import ConstructeurSelect from '~/components/ConstructeurSelect.vue'
import { useConstructeurs } from '~/composables/useConstructeurs'
import DocumentPreviewModal from '~/components/DocumentPreviewModal.vue'
import PageHero from '~/components/PageHero.vue'
import MachinePrintSelectionModal from '~/components/MachinePrintSelectionModal.vue'
import { buildMachinePrintContext, buildMachinePrintHtml } from '~/utils/printTemplates/machineReport'
import IconLucideAlertTriangle from '~icons/lucide/alert-triangle'
import IconLucideSquarePen from '~icons/lucide/square-pen'
import IconLucideCheck from '~icons/lucide/check'
import IconLucideChevronDown from '~icons/lucide/chevron-down'
import IconLucidePrinter from '~icons/lucide/printer'

const route = useRoute()
const machineId = route.params.id

// Vérifier que l'ID est valide
if (!machineId) {
  console.error('ID de machine manquant')
}

// Composables
const { updateMachine: updateMachineApi } = useMachines()
const { 
  getComposantsByMachine, 
  updateComposant: updateComposantApi 
} = useComposants()
const { 
  getPiecesByMachine, 
  updatePiece: updatePieceApi 
} = usePieces()

const { upsertCustomFieldValue } = useCustomFields()
const { 
  uploadDocuments,
  deleteDocument,
  loadDocumentsByMachine,
  loadDocumentsByComponent,
  loadDocumentsByPiece
} = useDocuments()

// Data
const loading = ref(true)
const machine = ref(null)
const components = ref([])
const pieces = ref([])
const printAreaRef = ref(null)

const { constructeurs, loadConstructeurs } = useConstructeurs()

// Champs de la machine
const machineName = ref('')
const machineReference = ref('')
const machineEmplacement = ref('')
const machineConstructeurId = ref(null)
const machineConstructeurDisplay = computed(() => {
  const id = machineConstructeurId.value || machine.value?.constructeur?.id || machine.value?.constructeurId
  if (!id) return machine.value?.constructeur || null
  return constructeurs.value.find(item => item.id === id) || machine.value?.constructeur || null
})

// Valeurs des champs personnalisés de la machine
const machineCustomFieldValues = reactive({})

const machineDocumentFiles = ref([])
const machineDocumentsUploading = ref(false)
const machineDocumentsLoaded = ref(false)
const previewDocument = ref(null)
const previewVisible = ref(false)
const printModalOpen = ref(false)
const printSelection = reactive({
  machine: {
    info: true,
    customFields: true,
    documents: true,
  },
  components: {},
  pieces: {},
})

const handleMachineConstructeurChange = async (value) => {
  machineConstructeurId.value = value
  await updateMachineInfo()
}

// Mode d'édition
const isEditMode = ref(false)
const debug = ref(false) // Ajout de debug pour afficher les infos de debug

// Gestion du pliage global des composants
const componentsCollapsed = ref(true)
const collapseToggleToken = ref(0)

const toggleAllComponents = () => {
  componentsCollapsed.value = !componentsCollapsed.value
  collapseToggleToken.value += 1
}

const collapseAllComponents = () => {
  componentsCollapsed.value = true
  collapseToggleToken.value += 1
}

// Méthodes pour initialiser les champs
const initMachineFields = () => {
  if (machine.value) {
    machineName.value = machine.value.name || ''
    machineReference.value = machine.value.reference || ''
    machineEmplacement.value = machine.value.emplacement || ''
    machineConstructeurId.value = machine.value.constructeurId || machine.value.constructeur?.id || null
  }
}

// Fonctions pour générer des IDs uniques
const getMachineFieldId = (fieldName) => {
  return machine.value ? `machine-${fieldName}-${machine.value.id}` : `machine-${fieldName}`
}

// Computed
const machinePieces = computed(() => {
  const filteredPieces = pieces.value.filter(piece => !piece.composantId)
  console.log('machinePieces computed:', filteredPieces)
  return filteredPieces
})

const machineDocumentsList = computed(() => machine.value?.documents || [])
const documentIcon = (doc) => getFileIcon({ name: doc.filename || doc.name, mime: doc.mimeType })

const allComponents = computed(() => {
  return components.value
})

const subComponents = (parentId) => {
  return components.value.filter(comp => comp.parentComposantId === parentId)
}

const componentPieces = (composantId) => {
  return pieces.value.filter(piece => piece.composantId === composantId)
}

const refreshMachineDocuments = async () => {
  if (!machine.value?.id) return
  const result = await loadDocumentsByMachine(machine.value.id, { updateStore: false })
  if (result.success && machine.value) {
    machine.value.documents = result.data || []
    machineDocumentsLoaded.value = true
  }
}

const handleMachineFilesAdded = async (files) => {
  if (!files.length || !machine.value?.id) return
  machineDocumentsUploading.value = true
  try {
    const result = await uploadDocuments(
      {
        files,
        context: { machineId: machine.value.id }
      },
      { updateStore: false }
    )

    if (result.success && machine.value) {
      const newDocs = result.data || []
      machine.value.documents = [...newDocs, ...(machine.value.documents || [])]
      machineDocumentFiles.value = []
    }
  } finally {
    machineDocumentsUploading.value = false
  }
}

const removeMachineDocument = async (documentId) => {
  if (!documentId) return
  const result = await deleteDocument(documentId, { updateStore: false })
  if (result.success && machine.value) {
    machine.value.documents = (machine.value.documents || []).filter(doc => doc.id !== documentId)
  }
}

const downloadDocument = (doc) => {
  if (!doc?.path) return

  if (doc.path.startsWith('data:')) {
    const link = document.createElement('a')
    link.href = doc.path
    link.download = doc.filename || doc.name || 'document'
    link.click()
    return
  }

  window.open(doc.path, '_blank')
}

const openPreview = (doc) => {
  if (!canPreviewDocument(doc)) return
  previewDocument.value = doc
  previewVisible.value = true
}

const closePreview = () => {
  previewVisible.value = false
  previewDocument.value = null
}

const ensurePrintSelectionEntries = () => {
  printSelection.machine.info ??= true
  printSelection.machine.customFields ??= true
  printSelection.machine.documents ??= true

  const ensureComponent = (component) => {
    if (component?.id !== undefined && printSelection.components[component.id] === undefined) {
      printSelection.components[component.id] = true
    }
    ;(component.pieces || []).forEach((piece) => {
      if (piece?.id !== undefined && printSelection.pieces[piece.id] === undefined) {
        printSelection.pieces[piece.id] = true
      }
    })
    ;(component.subComponents || []).forEach(ensureComponent)
  }

  components.value.forEach(ensureComponent)
  machinePieces.value.forEach((piece) => {
    if (piece?.id !== undefined && printSelection.pieces[piece.id] === undefined) {
      printSelection.pieces[piece.id] = true
    }
  })
}

const setAllPrintSelection = (value) => {
  ensurePrintSelectionEntries()
  printSelection.machine.info = value
  printSelection.machine.customFields = value
  printSelection.machine.documents = value
  Object.keys(printSelection.components).forEach((key) => {
    printSelection.components[key] = value
  })
  Object.keys(printSelection.pieces).forEach((key) => {
    printSelection.pieces[key] = value
  })
}

const openPrintModal = () => {
  ensurePrintSelectionEntries()
  printModalOpen.value = true
}

const closePrintModal = () => {
  printModalOpen.value = false
}

const handlePrintConfirm = async () => {
  closePrintModal()
  await nextTick()
  printMachine(printSelection)
}


const printMachine = (currentSelection = printSelection) => {
  if (typeof window === 'undefined') return

  const context = buildMachinePrintContext({
    machine: machine.value,
    machineName: machineName.value,
    machineReference: machineReference.value,
    machineEmplacement: machineEmplacement.value,
    machinePieces: machinePieces.value,
    components: components.value,
    selection: currentSelection,
  })
  const styles = Array.from(document.querySelectorAll('link[rel="stylesheet"], style'))
    .map(node => node.outerHTML)
    .join('')

  const htmlContent = buildMachinePrintHtml(context, styles)

  const iframe = document.createElement('iframe')
  iframe.style.position = 'fixed'
  iframe.style.right = '0'
  iframe.style.bottom = '0'
  iframe.style.width = '0'
  iframe.style.height = '0'
  iframe.style.border = '0'
  iframe.setAttribute('title', 'print-frame')
  document.body.appendChild(iframe)

  const iframeWindow = iframe.contentWindow
  const iframeDocument = iframe.contentDocument || iframeWindow?.document
  if (!iframeDocument || !iframeWindow) {
    iframe.remove()
    return
  }

  iframeDocument.open()
  iframeDocument.write(htmlContent)
  iframeDocument.close()

  const triggerPrint = () => {
    iframeWindow.focus()
    iframeWindow.print()
    setTimeout(() => {
      iframe.remove()
    }, 1000)
  }

  if (iframeDocument.readyState === 'complete') {
    setTimeout(triggerPrint, 50)
  } else {
    iframe.onload = () => setTimeout(triggerPrint, 50)
  }
}

const formatSize = (size) => {
  if (size === undefined || size === null) return '—'
  if (size === 0) return '0 B'
  const units = ['B', 'KB', 'MB', 'GB']
  const index = Math.min(units.length - 1, Math.floor(Math.log(size) / Math.log(1024)))
  const formatted = size / Math.pow(1024, index)
  return `${formatted.toFixed(1)} ${units[index]}`
}

// Transform custom field values to custom fields format
const transformCustomFields = (pieces) => {
  return pieces.map(piece => {
    const customFields = piece.customFieldValues?.map(cfv => ({
      id: cfv.customField.id,
      name: cfv.customField.name,
      type: cfv.customField.type,
      required: cfv.customField.required,
      defaultValue: cfv.customField.defaultValue,
      options: cfv.customField.options || [],
      value: cfv.value
    })) || []
    
    return {
      ...piece,
      customFields,
      documents: piece.documents || [],
      constructeur: piece.constructeur || null,
      constructeurId: piece.constructeurId || piece.constructeur?.id || null,
    }
  })
}

// Transform custom fields for components (now handles nested structure)
const transformComponentCustomFields = (componentsData) => {
  console.log('transformComponentCustomFields called with:', componentsData)
  
  return componentsData.map(component => {
    console.log('Processing component:', component.name, 'with sousComposants:', component.sousComposants?.length || 0)
    
    // Transform custom fields for the current component
    const customFields = component.customFieldValues?.map(cfv => ({
      id: cfv.customField.id,
      name: cfv.customField.name,
      type: cfv.customField.type,
      required: cfv.customField.required,
      defaultValue: cfv.customField.defaultValue,
      options: cfv.customField.options || [],
      value: cfv.value
    })) || [];
    
    // Transform pieces for the current component
    const pieces = component.pieces ? transformCustomFields(component.pieces) : [];
    
    // Recursively transform sub-components (using 'sousComposants' from backend)
    const subComponents = component.sousComposants ? transformComponentCustomFields(component.sousComposants) : [];
    
    const result = {
      ...component,
      customFields, // Use customFields for frontend display
      pieces,
      subComponents, // Use the transformed sousComposants as subComponents
      documents: component.documents || [],
      constructeur: component.constructeur || null,
      constructeurId: component.constructeurId || component.constructeur?.id || null,
    };
    
    console.log('Transformed component:', result.name, 'with subComponents:', result.subComponents?.length || 0)
    return result;
  });
};

// Methods
const loadMachineData = async () => {
  loading.value = true
  try {
    console.log('Début du chargement des données pour machineId:', machineId)
    
    // Load specific machine directly from API
    const { apiCall } = useApi()
    console.log('Appel API pour machine:', machineId)
    const machineResult = await apiCall(`/machines/${machineId}`, { method: 'GET' })
    console.log('Résultat machine complet:', machineResult)
    console.log('machineResult.success:', machineResult.success)
    console.log('machineResult.data:', machineResult.data)
    console.log('machineResult.error:', machineResult.error)
    console.log('Machine customFieldValues:', machineResult.data?.customFieldValues)
    console.log('Nombre de champs personnalisés:', machineResult.data?.customFieldValues?.length)
    
    if (machineResult.success) {
      machine.value = machineResult.data
      machine.value.documents = machine.value.documents || []
      machineDocumentsLoaded.value = !!(machine.value.documents?.length)
      console.log('Machine trouvée et assignée:', machine.value)
    } else {
      console.error('Machine non trouvée:', machineId)
      console.error('Erreur API:', machineResult.error)
      loading.value = false
      return
    }
    
    // Initialize machine fields
    initMachineFields()
    console.log('Champs machine initialisés')
    console.log('Machine après initialisation:', machine.value)
    console.log('Machine name:', machineName.value)
    console.log('Machine reference:', machineReference.value)
    
    // Load components with hierarchy
    console.log('Chargement des composants avec hiérarchie...')
    const componentsResult = await apiCall(`/composants/hierarchy/${machineId}`, { method: 'GET' })
    console.log('Résultat composants:', componentsResult)
    console.log('Structure des données reçues:', JSON.stringify(componentsResult.data, null, 2))
    if (componentsResult.success) {
      console.log('Transformation des composants...')
      components.value = transformComponentCustomFields(componentsResult.data)
      console.log('Composants chargés:', components.value.length)
      console.log('Composants transformés:', components.value)
      collapseAllComponents()
      
      // Debug: afficher la hiérarchie
      console.log('=== HIÉRARCHIE DES COMPOSANTS ===')
      components.value.forEach(comp => {
        console.log(`Composant: ${comp.name} (ID: ${comp.id}, Parent: ${comp.parentComposantId})`)
        if (comp.subComponents && comp.subComponents.length > 0) {
          console.log(`  Sous-composants: ${comp.subComponents.map(sc => sc.name).join(', ')}`)
        }
      })
      console.log('=== FIN HIÉRARCHIE ===')
    } else {
      console.error('Erreur lors du chargement des composants:', componentsResult.error)
    }
    
    // Load pieces from machine response instead of separate API call
    if (machine.value && machine.value.pieces) {
      // Transformer les champs personnalisés
      pieces.value = transformCustomFields(machine.value.pieces)
      console.log('Pièces transformées:', pieces.value)
      console.log('Pièces chargées:', pieces.value.length)
    } else {
      console.log('Aucune pièce trouvée dans la réponse de la machine')
    }

    if (!machineDocumentsLoaded.value) {
      await refreshMachineDocuments()
    }

    console.log('Chargement terminé avec succès')
  } catch (error) {
    console.error('Erreur lors du chargement des données:', error)
  } finally {
    loading.value = false
    console.log('Loading terminé, loading.value =', loading.value)
  }
}

const updateMachineInfo = async () => {
  if (!machine.value) return
  
  try {
    const result = await updateMachineApi(machine.value.id, {
      name: machineName.value,
      reference: machineReference.value,
      emplacement: machineEmplacement.value,
      constructeurId: machineConstructeurId.value || null
    })
    if (result.success) {
      machine.value = result.data
      machineConstructeurId.value = result.data.constructeurId || result.data.constructeur?.id || null
    }
  } catch (error) {
    console.error('Erreur lors de la mise à jour de la machine:', error)
  }
}

const updateComponent = async (updatedComponent) => {
  try {
    const prixValue = updatedComponent.prix
    const result = await updateComposantApi(updatedComponent.id, {
      name: updatedComponent.name,
      reference: updatedComponent.reference,
      constructeurId: updatedComponent.constructeurId || updatedComponent.constructeur?.id || null,
      emplacement: updatedComponent.emplacement,
      prix: prixValue && prixValue !== '' ? parseFloat(prixValue) : null
    })
    if (result.success) {
      Object.assign(updatedComponent, result.data)
    }
  } catch (error) {
    console.error('Erreur lors de la mise à jour du composant:', error)
  }
}

const updatePieceFromComponent = async (updatedPiece) => {
  try {
    const result = await updatePieceApi(updatedPiece.id, {
      name: updatedPiece.name,
      reference: updatedPiece.reference,
      constructeurId: updatedPiece.constructeurId || updatedPiece.constructeur?.id || null,
      emplacement: updatedPiece.emplacement,
      prix: updatedPiece.prix && updatedPiece.prix !== '' ? parseFloat(updatedPiece.prix) : null
    })
    if (result.success) {
      Object.assign(updatedPiece, result.data)
      // Si la pièce a des champs personnalisés mis à jour, les traiter
      if (updatedPiece.customFields) {
        for (const field of updatedPiece.customFields) {
          if (field.value !== undefined) {
            await upsertCustomFieldValue(
              field.id,
              'piece',
              updatedPiece.id,
              field.value
            )
          }
        }
      }
    }
  } catch (error) {
    console.error('Erreur lors de la mise à jour de la pièce:', error)
  }
}

const updatePieceInfo = async (updatedPiece) => {
  try {
    const result = await updatePieceApi(updatedPiece.id, {
      name: updatedPiece.name,
      reference: updatedPiece.reference,
      constructeurId: updatedPiece.constructeurId || updatedPiece.constructeur?.id || null,
      emplacement: updatedPiece.emplacement,
      prix: updatedPiece.prix && updatedPiece.prix !== '' ? parseFloat(updatedPiece.prix) : null
    })
    if (result.success) {
      Object.assign(updatedPiece, result.data)
    }
  } catch (error) {
    console.error('Erreur lors de la mise à jour de la pièce:', error)
  }
}

// Méthodes pour les champs personnalisés de la machine
const setMachineCustomFieldValue = (fieldValueId, value) => {
  const fieldValue = machine.value?.customFieldValues?.find(fv => fv.id === fieldValueId)
  if (fieldValue) {
    fieldValue.value = value
  }
}

const updateMachineCustomField = async (fieldValueId) => {
  const fieldValue = machine.value?.customFieldValues?.find(fv => fv.id === fieldValueId)
  if (fieldValue) {
    const { updateCustomFieldValue } = useCustomFields()
    const { showSuccess, showError } = useToast()
    
    const result = await updateCustomFieldValue(fieldValueId, { value: fieldValue.value })
    if (result.success) {
      showSuccess(`Champ "${fieldValue.customField.name}" de la machine mis à jour avec succès`)
    } else {
      showError(`Erreur lors de la mise à jour du champ "${fieldValue.customField.name}"`)
    }
  }
}

const updatePieceCustomField = async (fieldUpdate) => {
  const { showSuccess, showError } = useToast()
  
  try {
    const result = await upsertCustomFieldValue(
      fieldUpdate.fieldId,
      'piece',
      fieldUpdate.pieceId,
      fieldUpdate.value
    )
    if (result.success) {
      showSuccess(`Champ personnalisé mis à jour avec succès`)
    } else {
      showError(`Erreur lors de la mise à jour du champ personnalisé`)
    }
  } catch (error) {
    showError(`Erreur lors de la mise à jour du champ personnalisé`)
    console.error('Erreur lors de la mise à jour du champ personnalisé:', error)
  }
}

const editComponent = (component) => {
  // TODO: Implement edit modal
  console.log('Edit component:', component)
}

const editPiece = (piece) => {
  // TODO: Implement edit modal
  console.log('Edit piece:', piece)
}

const toggleEditMode = () => {
  isEditMode.value = !isEditMode.value
  debug.value = !debug.value // Inversez la valeur de debug
  if (isEditMode.value && !machineDocumentsLoaded.value) {
    refreshMachineDocuments()
  }
}

watch(
  () => [components.value.length, machinePieces.value.length],
  () => {
    ensurePrintSelectionEntries()
  },
  { immediate: true }
)

// Lifecycle
onMounted(() => {
  loadMachineData()
  if (!constructeurs.value.length) {
    loadConstructeurs()
  }

  // Vérifier si on doit activer le mode édition depuis l'URL
  const route = useRoute()
  if (route.query.edit === 'true') {
    isEditMode.value = true
    console.log('Mode édition activé depuis l\'URL')
  }
})
</script> 
