<template>
  <div class="space-y-4">
    <DocumentPreviewModal
      :document="previewDocument"
      :visible="previewVisible"
      @close="closePreview"
    />

    <!-- Component Header -->
    <div class="flex items-start justify-between p-4 bg-base-200 rounded-lg">
      <div class="flex items-start gap-3 w-full">
        <button
          type="button"
          class="btn btn-ghost btn-sm btn-circle shrink-0 transition-transform"
          :class="{ 'rotate-90': !isCollapsed }"
          :aria-expanded="!isCollapsed"
          :title="isCollapsed ? 'Déplier les détails du composant' : 'Replier les détails du composant'"
          @click="toggleCollapse"
        >
          <IconLucideChevronRight class="w-5 h-5 transition-transform" aria-hidden="true" />
          <span class="sr-only">{{ isCollapsed ? 'Déplier' : 'Replier' }} le composant</span>
        </button>
        <div class="flex-1">
          <h3 class="text-lg font-semibold">
            {{ component.name }}
          </h3>
          <div class="flex flex-wrap gap-2 mt-2">
            <span
              v-if="component.skeletonOnly"
              class="badge badge-warning badge-sm"
            >
              Défini dans le catalogue
            </span>
            <span v-if="component.reference" class="badge badge-outline badge-sm">{{ component.reference }}</span>
            <template v-if="componentConstructeursDisplay.length">
              <span
                v-for="constructeur in componentConstructeursDisplay"
                :key="constructeur.id"
                class="badge badge-outline badge-sm"
              >
                {{ constructeur.name }}
              </span>
            </template>
            <span v-if="component.prix" class="badge badge-primary badge-sm">{{ component.prix }}€</span>
            <span
              v-if="component.typeMachineComponentRequirement"
              class="badge badge-outline badge-sm"
            >
              Groupe : {{ component.typeMachineComponentRequirement.label || component.typeMachineComponentRequirement.typeComposant?.name || 'Non défini' }}
            </span>
          </div>
        </div>
      </div>
    </div>

    <div v-show="!isCollapsed" class="space-y-4">
      <!-- Component Info Display - Editable or Read-only -->
      <div class="p-4 bg-base-100 border border-gray-200 rounded-lg">
        <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
          <div class="form-control">
            <label class="label"><span class="label-text font-medium">Nom</span></label>
            <input
              v-if="isEditMode"
              v-model="component.name"
              type="text"
              class="input input-bordered input-sm"
              @blur="updateComponent"
            >
            <div v-else class="input input-bordered input-sm bg-base-200">
              {{ component.name }}
            </div>
          </div>
          <div class="form-control">
            <label class="label"><span class="label-text font-medium">Référence</span></label>
            <input
              v-if="isEditMode"
              v-model="component.reference"
              type="text"
              class="input input-bordered input-sm"
              @blur="updateComponent"
            >
            <div v-else class="input input-bordered input-sm bg-base-200">
              {{ component.reference || 'Non définie' }}
            </div>
          </div>
          <div class="form-control">
            <label class="label"><span class="label-text font-medium">Prix</span></label>
            <input
              v-if="isEditMode"
              v-model="component.prix"
              type="number"
              step="0.01"
              class="input input-bordered input-sm"
              @blur="updateComponent"
            >
            <div v-else class="input input-bordered input-sm bg-base-200">
              {{ component.prix ? `${component.prix}€` : 'Non défini' }}
            </div>
          </div>
          <div class="form-control">
            <label class="label"><span class="label-text font-medium">Constructeur</span></label>
            <ConstructeurSelect
              v-if="isEditMode"
              class="w-full"
              :model-value="componentConstructeurIds"
              @update:model-value="handleConstructeurChange"
            />
            <div v-else class="input input-bordered input-sm bg-base-200">
              <div v-if="componentConstructeursDisplay.length" class="space-y-1">
                <div
                  v-for="constructeur in componentConstructeursDisplay"
                  :key="constructeur.id"
                  class="flex flex-col"
                >
                  <span class="font-medium">{{ constructeur.name }}</span>
                  <span
                    v-if="formatConstructeurContact(constructeur)"
                    class="text-xs text-gray-500"
                  >
                    {{ formatConstructeurContact(constructeur) }}
                  </span>
                </div>
              </div>
              <span v-else class="font-medium">Non défini</span>
            </div>
          </div>
        </div>

      </div>

      <!-- Custom Fields Display - Editable or Read-only -->
      <div v-if="displayedCustomFields.length" class="mt-4 pt-4 border-t border-gray-200">
        <h4 class="font-semibold text-sm text-gray-700 mb-3">
          Champs personnalisés
        </h4>
        <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
          <div
            v-for="(field, index) in displayedCustomFields"
            :key="resolveFieldKey(field, index)"
            class="form-control"
          >
            <label class="label">
              <span class="label-text text-sm">{{ resolveFieldName(field) }}</span>
              <span v-if="resolveFieldRequired(field)" class="label-text-alt text-error">*</span>
            </label>
            <template v-if="isEditMode && !resolveFieldReadOnly(field)">
              <input
                v-if="resolveFieldType(field) === 'text'"
                v-model="field.value"
                type="text"
                class="input input-bordered input-sm"
                :required="resolveFieldRequired(field)"
                @blur="updateComponentCustomField(field)"
              >
              <input
                v-else-if="resolveFieldType(field) === 'number'"
                v-model="field.value"
                type="number"
                class="input input-bordered input-sm"
                :required="resolveFieldRequired(field)"
                @blur="updateComponentCustomField(field)"
              >
              <select
                v-else-if="resolveFieldType(field) === 'select'"
                v-model="field.value"
                class="select select-bordered select-sm"
                :required="resolveFieldRequired(field)"
                @change="updateComponentCustomField(field)"
              >
                <option value="">
                  Sélectionner...
                </option>
                <option v-for="option in resolveFieldOptions(field)" :key="option" :value="option">
                  {{ option }}
                </option>
              </select>
              <div v-else-if="resolveFieldType(field) === 'boolean'" class="flex items-center gap-2">
                <input
                  v-model="field.value"
                  type="checkbox"
                  class="checkbox checkbox-sm"
                  true-value="true"
                  false-value="false"
                  @change="updateComponentCustomField(field)"
                >
                <span class="text-sm">{{ String(field.value).toLowerCase() === 'true' ? 'Oui' : 'Non' }}</span>
              </div>
              <input
                v-else-if="resolveFieldType(field) === 'date'"
                v-model="field.value"
                type="date"
                class="input input-bordered input-sm"
                :required="resolveFieldRequired(field)"
                @blur="updateComponentCustomField(field)"
              >
            </template>
            <template v-else>
              <div class="input input-bordered input-sm bg-base-200">
                {{ formatFieldDisplayValue(field) }}
              </div>
            </template>
          </div>
        </div>
      </div>

      <div class="mt-4 pt-4 border-t border-gray-200 space-y-3">
        <div class="flex items-center justify-between">
          <h4 class="font-semibold text-sm text-gray-700">
            Documents
          </h4>
          <span v-if="isEditMode && selectedFiles.length" class="badge badge-outline">
            {{ selectedFiles.length }} fichier{{ selectedFiles.length > 1 ? 's' : '' }} sélectionné{{ selectedFiles.length > 1 ? 's' : '' }}
          </span>
        </div>

        <p v-if="loadingDocuments" class="text-xs text-gray-500">
          Chargement des documents...
        </p>

        <DocumentUpload
          v-if="isEditMode"
          v-model="selectedFiles"
          title="Déposer des fichiers pour ce composant"
          subtitle="Formats acceptés : PDF, images, documents..."
          @files-added="handleFilesAdded"
        />

        <div v-if="componentDocuments.length" class="space-y-2">
        <div
          v-for="document in componentDocuments"
          :key="document.id"
          class="flex items-center justify-between rounded border border-base-200 bg-base-100 px-3 py-2"
        >
          <div class="flex items-center gap-3 text-sm">
            <div
              class="flex-shrink-0 overflow-hidden rounded-md border border-base-200 bg-base-200/70 flex items-center justify-center"
              :class="documentThumbnailClass(document)"
            >
              <img
                v-if="isImageDocument(document) && document.path"
                :src="document.path"
                class="h-full w-full object-cover"
                :alt="`Aperçu de ${document.name}`"
              >
              <iframe
                v-else-if="shouldInlinePdf(document)"
                :src="documentPreviewSrc(document)"
                class="h-full w-full border-0 bg-white"
                title="Aperçu PDF"
              />
              <component
                v-else
                :is="documentIcon(document).component"
                class="h-6 w-6"
                :class="documentIcon(document).colorClass"
                  aria-hidden="true"
                />
              </div>
              <div>
                <div class="font-medium">
                  {{ document.name }}
                </div>
                <div class="text-xs text-gray-500">
                  {{ document.mimeType || 'Inconnu' }} • {{ formatSize(document.size) }}
                </div>
              </div>
            </div>
            <div class="flex items-center gap-2">
              <button
                type="button"
                class="btn btn-ghost btn-xs"
                :disabled="!canPreviewDocument(document)"
                :title="canPreviewDocument(document) ? 'Consulter le document' : 'Aucun aperçu disponible pour ce type'"
                @click="openPreview(document)"
              >
                Consulter
              </button>
              <button type="button" class="btn btn-ghost btn-xs" @click="downloadDocument(document)">
                Télécharger
              </button>
              <button
                v-if="isEditMode"
                type="button"
                class="btn btn-error btn-xs"
                :disabled="uploadingDocuments"
                @click="removeDocument(document.id)"
              >
                Supprimer
              </button>
            </div>
          </div>
        </div>
        <p v-else-if="!loadingDocuments" class="text-xs text-gray-500">
          Aucun document lié à ce composant.
        </p>
      </div>

      <!-- Component Pieces -->
      <div v-if="component.pieces && component.pieces.length > 0" class="space-y-2">
        <h4 class="font-semibold text-gray-700">
          Pièces du composant
        </h4>
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
          <PieceItem
            v-for="piece in component.pieces"
            :key="piece.id"
            :piece="piece"
            :is-edit-mode="isEditMode && !piece.skeletonOnly"
            
            @update="updatePiece"
            @edit="editPiece"
            @custom-field-update="updatePieceCustomField"
          />
        </div>
      </div>

      <!-- Sub Components -->
      <div v-if="childComponents.length > 0" class="space-y-3">
        <h4 class="font-semibold text-gray-700">
          Sous-composants
        </h4>
        <div class="space-y-3 pl-4 border-l-2 border-gray-200">
          <ComponentItem
            v-for="subComponent in childComponents"
            :key="subComponent.id"
            :component="subComponent"
            :is-edit-mode="isEditMode && !subComponent.skeletonOnly"
            :collapse-all="collapseAll"
            :toggle-token="toggleToken"
            @update="$emit('update', $event)"
            @edit-piece="$emit('edit-piece', $event)"
            @custom-field-update="$emit('custom-field-update', $event)"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, computed } from 'vue'
import PieceItem from './PieceItem.vue'
import DocumentUpload from './DocumentUpload.vue'
import ConstructeurSelect from './ConstructeurSelect.vue'
import { useDocuments } from '~/composables/useDocuments'
import { getFileIcon } from '~/utils/fileIcons'
import { canPreviewDocument, isImageDocument, isPdfDocument } from '~/utils/documentPreview'
import DocumentPreviewModal from '~/components/DocumentPreviewModal.vue'
import IconLucideChevronRight from '~icons/lucide/chevron-right'
import { useCustomFields } from '~/composables/useCustomFields'
import { useToast } from '~/composables/useToast'
import { useConstructeurs } from '~/composables/useConstructeurs'
import {
  formatConstructeurContact as formatConstructeurContactSummary,
  resolveConstructeurs,
  uniqueConstructeurIds,
} from '~/shared/constructeurUtils'

const props = defineProps({
  component: {
    type: Object,
    required: true
  },
  isEditMode: {
    type: Boolean,
    default: false
  },
  collapseAll: {
    type: Boolean,
    default: true
  },
  toggleToken: {
    type: Number,
    default: 0
  }
})

const emit = defineEmits([
  'update',
  'edit-piece',
  'custom-field-update'
])

const isCollapsed = ref(true)
const selectedFiles = ref([])
const uploadingDocuments = ref(false)
const loadingDocuments = ref(false)
const documentsLoaded = ref(!!(props.component.documents && props.component.documents.length))
const componentDocuments = computed(() => props.component.documents || [])
const documentIcon = doc => getFileIcon({ name: doc.filename || doc.name, mime: doc.mimeType })
const previewDocument = ref(null)
const previewVisible = ref(false)
const PDF_PREVIEW_MAX_BYTES = 5 * 1024 * 1024
const shouldInlinePdf = (document) => {
  if (!document || !isPdfDocument(document) || !document.path) {
    return false
  }
  if (typeof document.size === 'number' && document.size > PDF_PREVIEW_MAX_BYTES) {
    return false
  }
  return true
}
const appendPdfViewerParams = (src) => {
  if (!src || src.startsWith('data:')) {
    return src || ''
  }
  if (src.includes('#')) {
    return `${src}&toolbar=0&navpanes=0`
  }
  return `${src}#toolbar=0&navpanes=0`
}
const documentPreviewSrc = (document) => {
  if (!document?.path) {
    return ''
  }
  if (isPdfDocument(document)) {
    return appendPdfViewerParams(document.path)
  }
  return document.path
}
const documentThumbnailClass = (document) => {
  if (shouldInlinePdf(document) || (isImageDocument(document) && document?.path)) {
    return 'h-24 w-20'
  }
  return 'h-16 w-16'
}

const childComponents = computed(() => {
  const list = props.component.subcomponents || props.component.subComponents || []
  return Array.isArray(list) ? list : []
})

const { constructeurs } = useConstructeurs()

const componentConstructeurIds = computed(() =>
  uniqueConstructeurIds(
    props.component,
    Array.isArray(props.component.constructeurs) ? props.component.constructeurs : [],
    props.component.constructeur ? [props.component.constructeur] : [],
  ),
)

const componentConstructeursDisplay = computed(() =>
  resolveConstructeurs(
    componentConstructeurIds.value,
    Array.isArray(props.component.constructeurs) ? props.component.constructeurs : [],
    props.component.constructeur ? [props.component.constructeur] : [],
    constructeurs.value,
  ),
)

const formatConstructeurContact = (constructeur) =>
  formatConstructeurContactSummary(constructeur)

const extractStructureCustomFields = (structure) => {
  if (!structure || typeof structure !== 'object') {
    return []
  }
  const customFields = structure.customFields
  return Array.isArray(customFields) ? customFields : []
}

function fieldKeyFromNameAndType(name, type) {
  const normalizedName = typeof name === 'string' ? name.trim() : ''
  const normalizedType = typeof type === 'string' ? type : ''
  return normalizedName ? `${normalizedName}::${normalizedType}` : null
}

function deduplicateFieldDefinitions(definitions) {
  const result = []
  const seen = new Set()

  ;(Array.isArray(definitions) ? definitions : []).forEach((field) => {
    if (!field || typeof field !== 'object') {
      return
    }
    const id =
      field.id ??
      field.customFieldId ??
      field.customField?.id ??
      null
    const nameKey = fieldKeyFromNameAndType(field.name, field.type)
    if (!id && !nameKey) {
      return
    }
    const key = id || nameKey
    if (key && seen.has(key)) {
      return
    }
    if (key) {
      seen.add(key)
    }
    result.push(field)
  })

  return result
}

function mergeFieldDefinitionsWithValues(definitions, values) {
  const definitionList = Array.isArray(definitions) ? definitions : []
  const valueList = Array.isArray(values) ? values : []

  const valueMap = new Map()
  valueList.forEach((entry) => {
    if (!entry || typeof entry !== 'object') {
      return
    }
    const fieldId = entry.customField?.id ?? entry.customFieldId ?? null
    if (fieldId) {
      valueMap.set(fieldId, entry)
    }
    const nameKey = fieldKeyFromNameAndType(entry.customField?.name, entry.customField?.type)
    if (nameKey) {
      valueMap.set(nameKey, entry)
    }
  })

  const merged = definitionList.map((field) => {
    if (!field || typeof field !== 'object') {
      return field
    }

    const fieldId = ensureCustomFieldId(field)
    const nameKey = fieldKeyFromNameAndType(resolveFieldName(field), resolveFieldType(field))

    const matchedValue =
      (fieldId ? valueMap.get(fieldId) : undefined) ??
      (nameKey ? valueMap.get(nameKey) : undefined)

    if (!matchedValue) {
      return {
        ...field,
        value: field?.value ?? ''
      }
    }

    return {
      ...field,
      customFieldValueId: matchedValue.id ?? field.customFieldValueId ?? null,
      customFieldId:
        matchedValue.customField?.id ??
        matchedValue.customFieldId ??
        fieldId ??
        null,
      customField: matchedValue.customField ?? field.customField ?? null,
      value: matchedValue.value ?? field.value ?? ''
    }
  })

  valueList.forEach((entry) => {
    if (!entry || typeof entry !== 'object') {
      return
    }

    const fieldId = entry.customField?.id ?? entry.customFieldId ?? null
    const nameKey = fieldKeyFromNameAndType(entry.customField?.name, entry.customField?.type)

    const exists = merged.some((field) => {
      if (!field || typeof field !== 'object') {
        return false
      }
      if (field.customFieldValueId && field.customFieldValueId === entry.id) {
        return true
      }
      const existingId = ensureCustomFieldId(field)
      if (fieldId && existingId && existingId === fieldId) {
        return true
      }
      if (!fieldId && nameKey) {
        return (
          fieldKeyFromNameAndType(resolveFieldName(field), resolveFieldType(field)) === nameKey
        )
      }
      return false
    })

    if (!exists) {
      merged.push({
        customFieldValueId: entry.id ?? null,
        customFieldId: fieldId,
        name: entry.customField?.name ?? '',
        type: entry.customField?.type ?? 'text',
        required: entry.customField?.required ?? false,
        options: entry.customField?.options ?? [],
        value: entry.value ?? '',
        customField: entry.customField ?? null
      })
    }
  })

  return merged
}

function dedupeMergedFields(fields) {
  if (!Array.isArray(fields) || fields.length <= 1) {
    return Array.isArray(fields) ? fields : []
  }

  const seen = new Map()
  const result = []

  fields.forEach((field) => {
    if (!field || typeof field !== 'object') {
      return
    }

    const rawName = resolveFieldName(field)
    const normalizedName = typeof rawName === 'string' ? rawName.trim() : ''
    if (!normalizedName) {
      return
    }
    field.name = normalizedName
    field.type = resolveFieldType(field)

    const fieldId = ensureCustomFieldId(field)
    const nameKey = fieldKeyFromNameAndType(normalizedName, field.type)
    const key = fieldId || nameKey

    if (!key) {
      result.push(field)
      return
    }

    const existing = seen.get(key)
    if (!existing) {
      seen.set(key, field)
      result.push(field)
      return
    }

    const existingHasValue =
      existing.value !== undefined &&
      existing.value !== null &&
      String(existing.value).trim().length > 0

    const incomingHasValue =
      field.value !== undefined &&
      field.value !== null &&
      String(field.value).trim().length > 0

    if (!existingHasValue && incomingHasValue) {
      Object.assign(existing, field)
      seen.set(key, existing)
    }
  })

  return result
}

const componentDefinitionSources = computed(() => {
  const requirement = props.component.typeMachineComponentRequirement || {}
  const type = requirement.typeComposant || props.component.typeComposant || {}

  const definitions = []
  const pushFields = (collection) => {
    if (Array.isArray(collection)) {
      definitions.push(...collection)
    }
  }

  pushFields(props.component.customFields)
  pushFields(props.component.definition?.customFields)
  pushFields(type.customFields)
  pushFields(requirement.customFields)
  pushFields(requirement.definition?.customFields)

  ;[
    props.component.definition?.structure,
    type.structure,
    type.componentSkeleton,
    requirement.structure,
    requirement.componentSkeleton,
  ].forEach((structure) => {
    const fields = extractStructureCustomFields(structure)
    if (fields.length) {
      definitions.push(...fields)
    }
  })

  return deduplicateFieldDefinitions(definitions)
})

const displayedCustomFields = computed(() =>
  dedupeMergedFields(
    mergeFieldDefinitionsWithValues(
      componentDefinitionSources.value,
      props.component.customFieldValues,
    ),
  ),
)

const candidateCustomFields = computed(() => {
  const map = new Map()
  const register = (collection) => {
    if (!Array.isArray(collection)) {
      return
    }
    collection.forEach((item) => {
      if (!item || typeof item !== 'object') {
        return
      }
      const id = item.id || item.customFieldId
      const name = typeof item.name === 'string' ? item.name : null
      const key = id || (name ? `${name}::${item.type ?? ''}` : null)
      if (!key || map.has(key)) {
        return
      }
      map.set(key, item)
    })
  }

  register(props.component.customFieldValues?.map((value) => value?.customField))
  register(componentDefinitionSources.value)

  return Array.from(map.values())
})

watch(
  candidateCustomFields,
  () => {
    displayedCustomFields.value.forEach((field) => ensureCustomFieldId(field))
  },
  { immediate: true, deep: true }
)

watch(
  displayedCustomFields,
  (fields) => {
    (fields || []).forEach((field) => ensureCustomFieldId(field))
  },
  { immediate: true, deep: true }
)

const handleConstructeurChange = async (value) => {
  const ids = uniqueConstructeurIds(value)

  props.component.constructeurIds = [...ids]
  props.component.constructeurId = null
  props.component.constructeur = null
  props.component.constructeurs = resolveConstructeurs(
    ids,
    constructeurs.value,
    Array.isArray(props.component.constructeurs) ? props.component.constructeurs : [],
  )

  await updateComponent()
}

const { uploadDocuments, deleteDocument, loadDocumentsByComponent } = useDocuments()
const {
  updateCustomFieldValue: updateComponentCustomFieldValueApi,
  upsertCustomFieldValue: upsertComponentCustomFieldValue,
} = useCustomFields()
const { showSuccess, showError } = useToast()

watch(
  () => props.toggleToken,
  () => {
    isCollapsed.value = props.collapseAll
    if (!isCollapsed.value) {
      ensureDocumentsLoaded()
    }
  },
  { immediate: true }
)

watch(
  () => props.component.documents,
  (docs) => {
    documentsLoaded.value = !!(docs && docs.length)
  }
)

const toggleCollapse = () => {
  isCollapsed.value = !isCollapsed.value
  if (!isCollapsed.value) {
    ensureDocumentsLoaded()
  }
}

const updateComponent = () => {
  emit('update', {
    ...props.component,
    constructeurIds: componentConstructeurIds.value,
  })
}

function resolveFieldKey(field, index) {
  return field?.id
    ?? field?.customFieldValueId
    ?? field?.customFieldId
    ?? field?.name
    ?? `field-${index}`
}

function resolveFieldId(field) {
  return field?.customFieldValueId ?? null
}

function resolveFieldName(field) {
  return field?.name ?? 'Champ'
}

function resolveFieldType(field) {
  return field?.type ?? 'text'
}

function resolveFieldOptions(field) {
  return field?.options ?? []
}

function resolveFieldRequired(field) {
  return !!field?.required
}

function resolveFieldReadOnly(field) {
  return !!field?.readOnly
}

function buildCustomFieldMetadata(field) {
  return {
    customFieldName: resolveFieldName(field),
    customFieldType: resolveFieldType(field),
    customFieldRequired: resolveFieldRequired(field),
    customFieldOptions: resolveFieldOptions(field)
  }
}

function resolveCustomFieldId(field) {
  return field?.customFieldId ?? field?.id ?? field?.customField?.id ?? null
}

function ensureCustomFieldId(field) {
  const existingId = resolveCustomFieldId(field)
  if (existingId) {
    return existingId
  }

  const name = resolveFieldName(field)
  if (!name || name === 'Champ') {
    return null
  }

  const matches = candidateCustomFields.value.filter((candidate) => {
    if (!candidate || typeof candidate !== 'object') {
      return false
    }
    const candidateId = candidate.id || candidate.customFieldId
    if (candidateId && (candidateId === field?.id || candidateId === field?.customFieldId)) {
      return true
    }
    return typeof candidate.name === 'string' && candidate.name === name
  })

  if (matches.length) {
    const withId = matches.find((candidate) => candidate?.id || candidate?.customFieldId) || matches[0]
    const id = withId?.id || withId?.customFieldId || null
    if (id) {
      field.customFieldId = id
    }
    if (!field.customField && typeof withId === 'object') {
      field.customField = withId
    }
    return id
  }

  return null
}

watch(
  candidateCustomFields,
  () => {
    displayedCustomFields.value.forEach((field) => ensureCustomFieldId(field))
  },
  { immediate: true, deep: true }
)

watch(
  displayedCustomFields,
  (fields) => {
    (fields || []).forEach((field) => ensureCustomFieldId(field))
  },
  { immediate: true, deep: true }
)
const formatFieldDisplayValue = (field) => {
  const type = resolveFieldType(field)
  const rawValue = field?.value ?? ''
  if (type === 'boolean') {
    const normalized = String(rawValue).toLowerCase()
    if (normalized === 'true') return 'Oui'
    if (normalized === 'false') return 'Non'
  }
  return rawValue || 'Non défini'
}

const updateComponentCustomField = async (field) => {
  if (!field || resolveFieldReadOnly(field)) {
    return
  }

  const fieldValueId = resolveFieldId(field)
  if (fieldValueId) {
    const result = await updateComponentCustomFieldValueApi(fieldValueId, { value: field.value ?? '' })
    if (result.success) {
      const existingValue = props.component.customFieldValues?.find((value) => value.id === fieldValueId)
      if (existingValue?.customField?.id) {
        field.customFieldId = existingValue.customField.id
        field.customField = existingValue.customField
      }
      showSuccess(`Champ "${resolveFieldName(field)}" mis à jour avec succès`)
    } else {
      showError(`Erreur lors de la mise à jour du champ "${resolveFieldName(field)}"`)
    }
    return
  }

  const customFieldId = ensureCustomFieldId(field)
  const fieldName = resolveFieldName(field)
  if (!props.component?.id) {
    showError('Impossible de créer la valeur pour ce champ de composant')
    return
  }

  if (!customFieldId && (!fieldName || fieldName === 'Champ')) {
    showError('Impossible de créer la valeur pour ce champ de composant')
    return
  }

  const metadata = customFieldId ? undefined : buildCustomFieldMetadata(field)

  const result = await upsertComponentCustomFieldValue(
    customFieldId,
    'composant',
    props.component.id,
    field.value ?? '',
    metadata,
  )

  if (result.success) {
    const newValue = result.data
    if (newValue?.id) {
      field.customFieldValueId = newValue.id
      field.value = newValue.value ?? field.value ?? ''
      if (newValue.customField?.id) {
        field.customFieldId = newValue.customField.id
        field.customField = newValue.customField
      }

      if (Array.isArray(props.component.customFieldValues)) {
        const index = props.component.customFieldValues.findIndex((value) => value.id === newValue.id)
        if (index !== -1) {
          props.component.customFieldValues.splice(index, 1, newValue)
        } else {
          props.component.customFieldValues.push(newValue)
        }
      } else {
        props.component.customFieldValues = [newValue]
      }
    }
    showSuccess(`Champ "${resolveFieldName(field)}" créé avec succès`)

    const definitions = Array.isArray(props.component.customFields)
      ? [...props.component.customFields]
      : []
    const fieldIdentifier = ensureCustomFieldId(field)
    const existingIndex = definitions.findIndex((definition) => {
      const definitionId = ensureCustomFieldId(definition)
      if (fieldIdentifier && definitionId) {
        return definitionId === fieldIdentifier
      }
      return definition?.name === resolveFieldName(field)
    })

    const updatedDefinition = {
      ...(existingIndex !== -1 ? definitions[existingIndex] : {}),
      customFieldValueId: field.customFieldValueId,
      customFieldId: fieldIdentifier,
      name: resolveFieldName(field),
      type: resolveFieldType(field),
      required: resolveFieldRequired(field),
      options: resolveFieldOptions(field),
      value: field.value ?? '',
      customField: field.customField ?? null,
    }

    if (existingIndex !== -1) {
      definitions.splice(existingIndex, 1, updatedDefinition)
    } else {
      definitions.push(updatedDefinition)
    }

    props.component.customFields = definitions
  } else {
    showError(`Erreur lors de la sauvegarde du champ "${resolveFieldName(field)}"`)
  }
}

const updatePiece = (updatedPiece) => {
  emit('edit-piece', updatedPiece)
}

const editPiece = (piece) => {
  emit('edit-piece', piece)
}

const updatePieceCustomField = (fieldUpdate) => {
  emit('custom-field-update', fieldUpdate)
  emit('edit-piece', { ...fieldUpdate, type: 'custom-field-update' })
}

const ensureDocumentsLoaded = async () => {
  if (documentsLoaded.value || !props.component?.id) { return }
  await refreshDocuments()
}

const refreshDocuments = async () => {
  loadingDocuments.value = true
  try {
    const result = await loadDocumentsByComponent(props.component.id, { updateStore: false })
    if (result.success) {
      props.component.documents = result.data || []
      documentsLoaded.value = true
    }
  } finally {
    loadingDocuments.value = false
  }
}

const handleFilesAdded = async (files) => {
  if (!files.length || !props.component?.id) { return }
  uploadingDocuments.value = true
  try {
    const result = await uploadDocuments(
      {
        files,
        context: { composantId: props.component.id }
      },
      { updateStore: false }
    )

    if (result.success) {
      const newDocs = result.data || []
      props.component.documents = [...newDocs, ...(props.component.documents || [])]
      documentsLoaded.value = true
      selectedFiles.value = []
    }
  } finally {
    uploadingDocuments.value = false
  }
}

const removeDocument = async (documentId) => {
  if (!documentId) { return }
  const result = await deleteDocument(documentId, { updateStore: false })
  if (result.success) {
    props.component.documents = (props.component.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 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]}`
}
</script>
