<template>
  <div>
    <DocumentPreviewModal
      :document="previewDocument"
      :visible="previewVisible"
      :documents="productDocuments"
      @close="closePreview"
    />
    <DocumentEditModal
      :visible="editModalVisible"
      :document="editingDocument"
      @close="editModalVisible = false"
      @updated="handleDocumentUpdated"
    />
    <main class="container mx-auto px-6 py-10">
      <div v-if="loading" class="flex flex-col items-center gap-4 py-20 text-center">
        <span class="loading loading-spinner loading-lg" aria-hidden="true" />
        <p class="text-sm text-base-content/70">Chargement du produit…</p>
      </div>

      <div v-else-if="!product" class="max-w-xl mx-auto">
        <div class="alert alert-error shadow-lg">
          <div>
            <h2 class="font-semibold text-lg">Produit introuvable</h2>
            <p class="text-sm text-base-content/80">
              Nous n'avons pas pu trouver le produit demandé. Il a peut-être été supprimé.
            </p>
          </div>
        </div>
        <button type="button" class="btn btn-primary mt-6" @click="$router.back()">
          Retour au catalogue
        </button>
      </div>

      <section v-else class="card border border-base-200 bg-base-100 shadow-sm max-w-5xl mx-auto">
        <div class="card-body space-y-6">
          <DetailHeader
            :title="isEditMode ? 'Modifier le produit' : product.name"
            :subtitle="isEditMode ? 'Ajustez les informations du produit et ses champs personnalisés.' : undefined"
            :is-edit-mode="isEditMode"
            :can-edit="canEdit"
            back-link="/catalogues/produits"
            @toggle-edit="isEditMode = !isEditMode"
          />

          <EntityTabs
            v-model="activeTab"
            :tabs="entityTabs"
            aria-label="Sections du produit"
          >
            <template #tab-general>
              <div class="space-y-6">
                <!-- Catégorie (always shown) -->
                <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
                  <div class="form-control">
                    <label class="label">
                      <span class="label-text">Catégorie de produit</span>
                    </label>
                    <template v-if="isEditMode">
                      <div class="flex items-center gap-2">
                        <input
                          :value="product?.typeProduct?.name || 'Catégorie inconnue'"
                          type="text"
                          class="input input-bordered input-sm md:input-md bg-base-200 flex-1"
                          disabled
                        >
                        <NuxtLink
                          v-if="product?.typeProduct?.id"
                          :to="`/product-category/${product.typeProduct.id}/edit`"
                          class="btn btn-ghost btn-sm"
                          title="Voir la catégorie"
                        >
                          <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
                            <path d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z" />
                            <path d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z" />
                          </svg>
                        </NuxtLink>
                      </div>
                      <p class="text-xs text-base-content/60 mt-1">
                        La catégorie d'origine ne peut pas être modifiée depuis cette page.
                      </p>
                    </template>
                    <p v-else class="text-sm font-medium text-base-content py-1">
                      {{ product?.typeProduct?.name || '—' }}
                    </p>
                  </div>
                </div>

                <!-- Nom (always shown) -->
                <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
                  <div class="form-control">
                    <label class="label">
                      <span class="label-text">Nom du produit</span>
                    </label>
                    <input
                      v-if="isEditMode"
                      v-model="editionForm.name"
                      type="text"
                      class="input input-bordered input-sm md:input-md"
                      :disabled="!canEdit || saving"
                      placeholder="Nom affiché dans le catalogue"
                      required
                    >
                    <p v-else class="text-sm font-medium text-base-content py-1">
                      {{ product.name }}
                    </p>
                  </div>
                </div>

                <!-- Référence + Fournisseurs (if value or edit mode) -->
                <div
                  v-if="isEditMode || product.reference || editionForm.constructeurIds.length"
                  class="grid grid-cols-1 gap-4 md:grid-cols-2"
                >
                  <div v-if="isEditMode || product.reference" class="form-control">
                    <label class="label">
                      <span class="label-text">Référence</span>
                    </label>
                    <input
                      v-if="isEditMode"
                      v-model="editionForm.reference"
                      type="text"
                      class="input input-bordered input-sm md:input-md"
                      :disabled="!canEdit || saving"
                      placeholder="Référence interne ou fournisseur"
                    >
                    <p v-else class="text-sm font-medium text-base-content py-1">
                      {{ product.reference }}
                    </p>
                  </div>

                  <div v-if="isEditMode || editionForm.constructeurIds.length" class="form-control">
                    <label class="label">
                      <span class="label-text">Fournisseurs</span>
                    </label>
                    <ConstructeurSelect
                      v-if="isEditMode"
                      v-model="editionForm.constructeurIds"
                      class="w-full"
                      :disabled="!canEdit || saving"
                      placeholder="Rechercher un ou plusieurs fournisseurs..."
                      :initial-options="product?.constructeurs || []"
                    />
                    <div v-else class="flex flex-wrap gap-2">
                      <span
                        v-for="id in editionForm.constructeurIds"
                        :key="id"
                        class="badge badge-outline"
                      >
                        {{ getConstructeurById(id)?.name || id }}
                      </span>
                    </div>
                  </div>
                </div>

                <!-- Constructeur links table -->
                <ConstructeurLinksTable
                  v-if="isEditMode && constructeurLinks.length"
                  v-model="constructeurLinks"
                />
                <ConstructeurLinksTable
                  v-else-if="!isEditMode && constructeurLinks.length"
                  :model-value="constructeurLinks"
                  :readonly="true"
                />

                <!-- Prix fournisseur (if value or edit mode) -->
                <div v-if="isEditMode || product.supplierPrice" class="grid grid-cols-1 gap-4 md:grid-cols-2">
                  <div class="form-control">
                    <label class="label">
                      <span class="label-text">Prix fournisseur indicatif (€)</span>
                    </label>
                    <input
                      v-if="isEditMode"
                      v-model="editionForm.supplierPrice"
                      type="number"
                      step="0.01"
                      min="0"
                      class="input input-bordered input-sm md:input-md"
                      :disabled="!canEdit || saving"
                      placeholder="Valeur indicatrice"
                    >
                    <p v-else class="text-sm font-medium text-base-content py-1">
                      {{ product.supplierPrice }} €
                    </p>
                  </div>
                </div>

                <!-- Structure preview (edit mode only) -->
                <div v-if="isEditMode && structurePreview" class="space-y-3 rounded-lg border border-base-200 bg-base-200/40 p-4">
                  <div class="flex items-center justify-between gap-4">
                    <div>
                      <h2 class="font-semibold text-base-content">Champs définis par la catégorie</h2>
                      <p class="text-xs text-base-content/70">
                        {{ productType?.description || 'Le squelette de catégorie contrôle les champs personnalisés disponibles.' }}
                      </p>
                    </div>
                    <span class="badge badge-outline">{{ structurePreview }}</span>
                  </div>
                </div>

                <UsedInSection entity-type="products" :entity-id="product?.id ?? null" />
              </div>
            </template>

            <template #tab-documents>
              <div class="space-y-6">
                <!-- Documents -->
                <div class="space-y-4 rounded-lg border border-base-200 bg-base-200/40 p-4">
                  <header class="flex flex-col gap-1 md:flex-row md:items-center md:justify-between">
                    <div>
                      <h2 class="font-semibold text-base-content">Documents</h2>
                      <p class="text-xs text-base-content/70">
                        {{ isEditMode ? 'Gérez les documents associés à ce produit.' : 'Documents associés à ce produit.' }}
                      </p>
                    </div>
                    <span v-if="isEditMode && selectedFiles.length" class="badge badge-outline">
                      {{ selectedFiles.length }} document{{ selectedFiles.length > 1 ? 's' : '' }} prêt{{ selectedFiles.length > 1 ? 's' : '' }} à être ajouté{{ selectedFiles.length > 1 ? 's' : '' }}
                    </span>
                  </header>
                  <template v-if="isEditMode">
                    <div :class="{ 'pointer-events-none opacity-60': !canEdit || saving || uploadingDocuments }">
                      <DocumentUpload
                        v-model="selectedFiles"
                        title="Déposer vos fichiers"
                        subtitle="Formats acceptés : PDF, images, documents…"
                        @files-added="handleFilesAdded"
                      />
                    </div>
                    <p v-if="uploadingDocuments" class="text-xs text-base-content/70">
                      Téléversement des documents en cours…
                    </p>
                    <p v-else-if="loadingDocuments" class="text-xs text-base-content/70">
                      Chargement des documents en cours…
                    </p>
                    <DocumentListInline
                      v-else
                      :documents="productDocuments"
                      :can-delete="canEdit"
                      :can-edit="true"
                      :delete-disabled="uploadingDocuments || saving"
                      empty-text="Aucun document n'est associé à ce produit pour le moment."
                      @preview="openPreview"
                      @edit="openEditModal"
                      @delete="removeDocument"
                    />
                  </template>
                  <template v-else>
                    <p v-if="loadingDocuments" class="text-xs text-base-content/70">
                      Chargement des documents en cours…
                    </p>
                    <DocumentListInline
                      v-else
                      :documents="productDocuments"
                      :can-delete="false"
                      :can-edit="false"
                      empty-text="Aucun document n'est associé à ce produit pour le moment."
                      @preview="openPreview"
                    />
                  </template>
                </div>
              </div>
            </template>

            <template #tab-custom-fields>
              <div class="space-y-6">
                <!-- Custom fields -->
                <div v-if="visibleCustomFields.length" class="space-y-4 rounded-lg border border-base-200 bg-base-200/40 p-4">
                  <header class="space-y-1">
                    <h2 class="font-semibold text-base-content">Champs personnalisés</h2>
                    <p v-if="isEditMode" class="text-xs text-base-content/70">
                      Mettez à jour les valeurs propres à ce produit.
                    </p>
                  </header>
                  <template v-if="isEditMode">
                    <CustomFieldInputGrid :fields="customFieldInputs" :disabled="!canEdit || saving" />
                    <p v-if="hasRequiredCustomFields && !requiredCustomFieldsFilled" class="text-xs text-warning">
                      Certains champs personnalisés sont obligatoires. Veuillez les renseigner avant de valider.
                    </p>
                  </template>
                  <template v-else>
                    <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
                      <div
                        v-for="field in visibleCustomFields"
                        :key="field.customFieldValueId || field.customFieldId || field.name"
                        class="form-control"
                      >
                        <label class="label">
                          <span class="label-text text-sm">{{ field.name }}</span>
                        </label>
                        <p class="text-sm font-medium text-base-content py-1">
                          {{ field.value }}
                        </p>
                      </div>
                    </div>
                  </template>
                </div>
                <p v-else class="text-sm text-base-content/60">
                  Aucun champ personnalisé n'est défini pour ce produit.
                </p>
              </div>
            </template>

            <template #tab-history>
              <div class="space-y-6">
                <EntityHistorySection
                  :entries="history"
                  :loading="historyLoading"
                  :error="historyError"
                  :field-labels="historyFieldLabels"
                />

                <EntityVersionList
                  entity-type="product"
                  :entity-id="String(route.params.id)"
                  :field-labels="historyFieldLabels"
                  :refresh-key="versionRefreshKey"
                  @restored="loadProduct()"
                />

                <!-- Comments -->
                <div class="mt-4">
                  <CommentSection
                    entity-type="product"
                    :entity-id="String(route.params.id)"
                    :entity-name="product?.name"
                    show-resolved
                  />
                </div>
              </div>
            </template>
          </EntityTabs>

          <!-- Save buttons (edit mode only) -->
          <div v-if="isEditMode" class="flex flex-col gap-3 md:flex-row md:justify-end">
            <button type="button" class="btn btn-ghost" :class="{ 'btn-disabled': saving }" @click="isEditMode = false">
              Annuler
            </button>
            <button type="button" class="btn btn-primary" :disabled="!canSubmit" @click="submitEdition">
              <span v-if="saving" class="loading loading-spinner loading-sm mr-2" />
              Enregistrer les modifications
            </button>
          </div>
          <p v-if="isEditMode && hasRequiredCustomFields && !requiredCustomFieldsFilled" class="text-xs text-error text-right">
            Merci de renseigner tous les champs personnalisés obligatoires.
          </p>
        </div>
      </section>
    </main>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { navigateTo, useRoute } from '#imports'
import ConstructeurSelect from '~/components/ConstructeurSelect.vue'
import DocumentUpload from '~/components/DocumentUpload.vue'
import DocumentPreviewModal from '~/components/DocumentPreviewModal.vue'
import { useProducts } from '~/composables/useProducts'
import { useToast } from '~/composables/useToast'
import { humanizeError } from '~/shared/utils/errorMessages'
import { useDocuments } from '~/composables/useDocuments'
import { useConstructeurs } from '~/composables/useConstructeurs'
import { useConstructeurLinks } from '~/composables/useConstructeurLinks'
import { useEntityHistory } from '~/composables/useEntityHistory'
import { usePermissions } from '~/composables/usePermissions'
import { formatProductStructurePreview, normalizeProductStructureForSave } from '~/shared/modelUtils'
import { constructeurIdsFromLinks } from '~/shared/constructeurUtils'
import type { ConstructeurLinkEntry } from '~/shared/constructeurUtils'
import { getModelType } from '~/services/modelTypes'
import type { ProductModelStructure } from '~/shared/types/inventory'
import { canPreviewDocument } from '~/utils/documentPreview'
import { useCustomFieldInputs, type CustomFieldEntityType } from '~/composables/useCustomFieldInputs'

const { canEdit } = usePermissions()
const route = useRoute()
const toast = useToast()
const { getProduct, updateProduct } = useProducts()
const {
  loadDocumentsByProduct,
  uploadDocuments: uploadProductDocuments,
  deleteDocument: deleteProductDocument,
  updateDocument,
} = useDocuments()
const { ensureConstructeurs, getConstructeurById } = useConstructeurs()
const { fetchLinks, syncLinks } = useConstructeurLinks()
const {
  history,
  loading: historyLoading,
  error: historyError,
  loadHistory,
} = useEntityHistory('product')

const isEditMode = ref(false)
const versionRefreshKey = ref(0)

const constructeurLinks = ref<ConstructeurLinkEntry[]>([])
const originalConstructeurLinks = ref<ConstructeurLinkEntry[]>([])

const product = ref<any | null>(null)
const productType = ref<any | null>(null)
const structure = ref<ProductModelStructure | null>(null)
const cfDefinitions = ref<any[]>([])
const cfValues = ref<any[]>([])
const entityId = computed(() => product.value?.id ?? null)
const {
  fields: customFieldInputs,
  requiredFilled: requiredCustomFieldsFilled,
  saveAll: saveAllCustomFields,
} = useCustomFieldInputs({
  definitions: cfDefinitions,
  values: cfValues,
  entityType: 'product' as CustomFieldEntityType,
  entityId,
  context: 'standalone',
})
const loading = ref(true)
const saving = ref(false)
const selectedFiles = ref<File[]>([])
const uploadingDocuments = ref(false)
const loadingDocuments = ref(false)
const productDocuments = ref<any[]>([])
const previewDocument = ref<any | null>(null)
const previewVisible = ref(false)
const editingDocument = ref<any | null>(null)
const editModalVisible = ref(false)

const historyFieldLabels: Record<string, string> = {
  name: 'Nom',
  reference: 'Référence',
  supplierPrice: 'Prix fournisseur',
  typeProduct: 'Catégorie',
  constructeurIds: 'Fournisseurs',
}

const refreshCustomFieldInputs = (
  structureOverride?: ProductModelStructure | null,
  valuesOverride?: any[] | null,
) => {
  const nextStructure = structureOverride ?? structure.value ?? null
  const nextValues = valuesOverride ?? product.value?.customFieldValues ?? null
  cfDefinitions.value = nextStructure?.customFields ?? []
  cfValues.value = Array.isArray(nextValues) ? nextValues : []
}

const editionForm = reactive({
  name: '' as string,
  reference: '' as string,
  constructeurIds: [] as string[],
  supplierPrice: '' as string,
})

const hasRequiredCustomFields = computed(() => customFieldInputs.value.some(f => f.required))

const canSubmit = computed(() =>
  Boolean(canEdit.value && product.value && editionForm.name.trim().length >= 2 && requiredCustomFieldsFilled.value && !saving.value),
)

const structurePreview = computed(() => formatProductStructurePreview(structure.value))

const visibleCustomFields = computed(() => {
  if (isEditMode.value) return customFieldInputs.value
  return customFieldInputs.value.filter(
    (f) => f.value !== null && f.value !== undefined && f.value !== '',
  )
})

const activeTab = ref((route.query.tab as string) || 'general')
watch(activeTab, (val) => {
  navigateTo({ query: { ...route.query, tab: val } }, { replace: true })
})

const entityTabs = computed(() => [
  { key: 'general', label: 'Général' },
  { key: 'documents', label: 'Documents', count: productDocuments.value.length },
  { key: 'custom-fields', label: 'Champs perso', count: visibleCustomFields.value.length },
  { key: 'history', label: 'Historique' },
])

const openPreview = (doc: any) => {
  if (!doc || !canPreviewDocument(doc)) return
  previewDocument.value = doc
  previewVisible.value = true
}
const closePreview = () => { previewVisible.value = false; previewDocument.value = null }

const openEditModal = (doc: any) => {
  editingDocument.value = doc
  editModalVisible.value = true
}
const handleDocumentUpdated = async (data: { name?: string; type?: string }) => {
  if (!editingDocument.value?.id) return
  const result = await updateDocument(editingDocument.value.id, data)
  if (result.success) {
    const idx = productDocuments.value.findIndex((d: any) => d.id === editingDocument.value?.id)
    if (idx !== -1) {
      productDocuments.value[idx] = { ...productDocuments.value[idx], ...data }
    }
  }
  editModalVisible.value = false
  editingDocument.value = null
}

const loadProduct = async () => {
  const id = route.params.id
  if (!id || typeof id !== 'string') {
    product.value = null
    loading.value = false
    return
  }
  const result = await getProduct(id)
  if (result.success && result.data) {
    product.value = result.data
    productDocuments.value = Array.isArray(result.data.documents) ? result.data.documents : []

    await loadProductType()

    const customValues = Array.isArray(result.data?.customFieldValues) ? result.data.customFieldValues : []
    refreshCustomFieldInputs(undefined, customValues)

    hydrateForm()

    loadHistory(result.data.id).catch(() => {})
  } else {
    product.value = null
  }
  loading.value = false
}

const refreshDocuments = async () => {
  if (!product.value?.id) {
    return
  }
  loadingDocuments.value = true
  try {
    const result = await loadDocumentsByProduct(product.value.id, { updateStore: false })
    if (result.success) {
      productDocuments.value = Array.isArray(result.data) ? result.data : []
    }
  } finally {
    loadingDocuments.value = false
  }
}

const removeDocument = async (documentId: string | number | null | undefined) => {
  if (!documentId) {
    return
  }
  const result = await deleteProductDocument(documentId, { updateStore: false })
  if (result.success) {
    productDocuments.value = productDocuments.value.filter((doc) => doc.id !== documentId)
    toast.showSuccess('Document supprimé')
  }
}

const handleFilesAdded = async (files: File[]) => {
  if (!files?.length || !product.value?.id) {
    return
  }
  uploadingDocuments.value = true
  try {
    const result = await uploadProductDocuments(
      {
        files,
        context: { productId: product.value.id },
      },
      { updateStore: false },
    )
    if (result.success) {
      selectedFiles.value = []
      await refreshDocuments()
      toast.showSuccess('Document(s) ajouté(s)')
    } else if (result.error) {
      toast.showError(result.error)
    }
  } finally {
    uploadingDocuments.value = false
  }
}

const loadProductType = async () => {
  const embedded = product.value?.typeProduct
  if (embedded && typeof embedded === 'object' && embedded.id) {
    const embeddedStructure = embedded.structure ?? null
    if (embeddedStructure) {
      productType.value = embedded
      structure.value = normalizeProductStructureForSave(embeddedStructure)
      return
    }
  }

  if (!product.value?.typeProductId) {
    productType.value = embedded ?? null
    structure.value = normalizeProductStructureForSave(embedded?.structure ?? null)
    return
  }
  try {
    const type = await getModelType(product.value.typeProductId)
    productType.value = type
    structure.value = normalizeProductStructureForSave(type?.structure ?? null)
  } catch (error) {
    console.error('Erreur lors du chargement du type de produit:', error)
    productType.value = embedded ?? null
    structure.value = normalizeProductStructureForSave(embedded?.structure ?? null)
  }
}

const hydrateForm = () => {
  if (!product.value) {
    return
  }
  editionForm.name = product.value.name || ''
  editionForm.reference = product.value.reference || ''
  // Load constructeur links
  fetchLinks('product', String(route.params.id)).then((links) => {
    constructeurLinks.value = links
    originalConstructeurLinks.value = links.map(l => ({ ...l }))
    editionForm.constructeurIds = constructeurIdsFromLinks(links)
    if (editionForm.constructeurIds.length) {
      void ensureConstructeurs(editionForm.constructeurIds)
    }
  })
  editionForm.supplierPrice = product.value.supplierPrice !== null && product.value.supplierPrice !== undefined
    ? String(product.value.supplierPrice)
    : ''
  refreshCustomFieldInputs(structure.value, product.value.customFieldValues)
}

watch(
  () => product.value?.documents,
  (docs) => {
    if (Array.isArray(docs)) {
      productDocuments.value = docs
    }
  },
  { immediate: true },
)

const submitEdition = async () => {
  if (!product.value) {
    return
  }

  const payload: Record<string, any> = {
    name: editionForm.name.trim(),
    reference: editionForm.reference.trim() || null,
  }

  const rawPrice = typeof editionForm.supplierPrice === 'string'
    ? editionForm.supplierPrice.trim()
    : editionForm.supplierPrice
  payload.supplierPrice = rawPrice !== '' && rawPrice !== null && rawPrice !== undefined
    ? Number.isNaN(Number(rawPrice))
      ? null
      : String(Number(rawPrice))
    : null

  saving.value = true
  try {
    const result = await updateProduct(product.value.id, payload)
    if (result.success && result.data?.id) {
      product.value = result.data
      const failedFields = await saveAllCustomFields()
      if (failedFields.length) {
        toast.showError(`Impossible d'enregistrer ${failedFields.length} champ(s): ${failedFields.join(', ')}`)
        return
      }
      await syncLinks('product', product.value.id, originalConstructeurLinks.value, constructeurLinks.value)
      originalConstructeurLinks.value = constructeurLinks.value.map(l => ({ ...l }))
      toast.showSuccess('Produit mis à jour avec succès')
      await loadProduct()
      isEditMode.value = false
      versionRefreshKey.value++
    }
  } catch (error: any) {
    toast.showError(humanizeError(error?.message) || 'Impossible de mettre à jour le produit')
  } finally {
    saving.value = false
  }
}

// Sync constructeurIds → constructeurLinks when IDs are added via ConstructeurSelect
watch(
  () => editionForm.constructeurIds,
  (ids) => {
    const currentIds = new Set(constructeurLinks.value.map(l => l.constructeurId))
    for (const id of ids) {
      if (!currentIds.has(id)) {
        const resolved = getConstructeurById(id)
        constructeurLinks.value.push({
          constructeurId: id,
          constructeur: resolved ? { id: resolved.id, name: resolved.name } : null,
          supplierReference: null,
        })
      }
    }
    constructeurLinks.value = constructeurLinks.value.filter(l => ids.includes(l.constructeurId))
  },
)

onMounted(async () => {
  await loadProduct()
  if (route.query.edit === 'true' && canEdit.value) {
    isEditMode.value = true
  }
})
</script>
