<template>
  <main class="container mx-auto px-6 py-10 space-y-8">
    <header class="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
      <div>
        <h1 class="text-3xl font-semibold text-base-content">Catalogue des composants</h1>
        <p class="text-sm text-gray-500">
          Consultez et gérez tous les composants existants.
        </p>
      </div>
      <div class="flex flex-wrap gap-2">
        <NuxtLink to="/component/create" class="btn btn-primary btn-sm md:btn-md">
          Ajouter un composant
        </NuxtLink>
        <NuxtLink to="/component-category" class="btn btn-outline btn-sm md:btn-md">
          Gérer les catégories
        </NuxtLink>
      </div>
    </header>

    <section class="card border border-base-200 bg-base-100 shadow-sm">
      <div class="card-body space-y-4">
        <header class="flex flex-col gap-2">
          <h2 class="text-xl font-semibold text-base-content">Composants créés</h2>
          <p class="text-sm text-base-content/70">
            Retrouvez ici tous les composants enregistrés, indépendamment de leur catégorie.
          </p>
        </header>

        <div class="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
          <div class="flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center">
            <label class="w-full sm:w-72">
              <span class="text-xs font-semibold uppercase tracking-wide text-base-content/70">Recherche</span>
              <input
                v-model="searchTerm"
                type="text"
                class="input input-bordered input-sm w-full mt-1"
                placeholder="Nom, référence ou catégorie…"
              />
            </label>
            <div class="flex items-center gap-2">
              <label
                class="text-xs font-semibold uppercase tracking-wide text-base-content/70"
                for="component-catalog-sort"
              >
                Trier par
              </label>
              <select
                id="component-catalog-sort"
                v-model="sortField"
                class="select select-bordered select-sm"
              >
                <option value="name">Nom</option>
                <option value="createdAt">Date de création</option>
              </select>
            </div>
            <div class="flex items-center gap-2">
              <label
                class="text-xs font-semibold uppercase tracking-wide text-base-content/70"
                for="component-catalog-dir"
              >
                Ordre
              </label>
              <select
                id="component-catalog-dir"
                v-model="sortDirection"
                class="select select-bordered select-sm"
              >
                <option value="asc">Ascendant</option>
                <option value="desc">Descendant</option>
              </select>
            </div>
          </div>
          <p class="text-xs text-base-content/50 lg:text-right">
            {{ visibleComposants.length }} / {{ composantsTotal }} résultat{{ visibleComposants.length > 1 ? 's' : '' }}
          </p>
        </div>

        <div v-if="loadingComposants" class="flex justify-center py-8">
          <span class="loading loading-spinner" aria-hidden="true" />
        </div>

        <p v-else-if="!composantsTotal" class="text-sm text-base-content/70">
          Aucun composant n'a encore été créé.
        </p>

        <p v-else-if="!visibleComposants.length" class="text-sm text-base-content/70">
          Aucun composant ne correspond à votre recherche.
        </p>

        <div v-else class="overflow-x-auto">
          <table class="table table-sm md:table-md">
            <thead>
              <tr>
                <th class="w-24">Aperçu</th>
                <th>Nom</th>
                <th>Catégorie</th>
                <th>Référence</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="component in visibleComposants" :key="component.id">
                <td class="align-middle">
                  <DocumentThumbnail
                    :document="resolvePrimaryDocument(component)"
                    :alt="resolvePreviewAlt(component)"
                  />
                </td>
                <td>{{ component.name || 'Composant sans nom' }}</td>
                <td>{{ component.typeComposant?.name || '—' }}</td>
                <td>{{ component.reference || '—' }}</td>
                <td>
                  <div class="flex items-center gap-2">
                    <NuxtLink
                      :to="`/component/${component.id}/edit`"
                      class="btn btn-ghost btn-xs"
                    >
                      Modifier
                    </NuxtLink>
                    <button
                      type="button"
                      class="btn btn-error btn-xs"
                      :disabled="loadingComposants"
                      @click="handleDeleteComponent(component)"
                    >
                      Supprimer
                    </button>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </section>
  </main>

</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useComposants } from '~/composables/useComposants'
import { useToast } from '~/composables/useToast'
import DocumentThumbnail from '~/components/DocumentThumbnail.vue'
import { isImageDocument, isPdfDocument } from '~/utils/documentPreview'

const { showError } = useToast()
const { composants, loadComposants, loading: loadingComposantsRef, deleteComposant } = useComposants()
const loadingComposants = computed(() => loadingComposantsRef.value)
const composantsList = computed(() => composants.value || [])
const composantsTotal = computed(() => composantsList.value.length)

const searchTerm = ref('')
const sortField = ref<'name' | 'createdAt'>('name')
const sortDirection = ref<'asc' | 'desc'>('asc')

const resolvePrimaryDocument = (component: Record<string, any>) => {
  const documents = Array.isArray(component?.documents) ? component.documents : []
  if (!documents.length) {
    return null
  }
  const normalized = documents.filter((doc) => doc && typeof doc === 'object')
  const withPath = normalized.filter((doc) => doc?.path)
  const pdf = withPath.find((doc) => isPdfDocument(doc))
  if (pdf) {
    return pdf
  }
  const image = withPath.find((doc) => isImageDocument(doc))
  if (image) {
    return image
  }
  return withPath[0] ?? normalized[0] ?? null
}

const resolvePreviewAlt = (component: Record<string, any>) => {
  const parts = [component?.name, component?.reference].filter(Boolean)
  if (parts.length) {
    return `Aperçu du document de ${parts.join(' – ')}`
  }
  return 'Aperçu du document'
}

const resolveDeleteGuard = (component: Record<string, any>) => {
  const blockingReasons: string[] = []
  const machineLinks = Array.isArray(component?.machineLinks)
    ? component.machineLinks.length
    : component?.machineLinksCount ?? 0
  const documents = Array.isArray(component?.documents)
    ? component.documents.length
    : component?.documentsCount ?? 0
  const customFields = Array.isArray(component?.customFieldValues)
    ? component.customFieldValues.length
    : component?.customFieldValuesCount ?? 0

  if (machineLinks > 0) {
    blockingReasons.push(`${machineLinks} liaison${machineLinks > 1 ? 's' : ''} machine`)
  }
  if (documents > 0) {
    blockingReasons.push(`${documents} document${documents > 1 ? 's' : ''}`)
  }
  return {
    blockingReasons,
    hasCustomFields: customFields > 0,
  }
}

const resolveComparableName = (component: Record<string, any>) => {
  const toComparable = (value?: string | null) =>
    (value ?? '').toString().trim().toLowerCase()

  return (
    toComparable(component?.name) ||
    toComparable(component?.reference) ||
    toComparable(component?.id)
  )
}

const resolveComparableDate = (component: Record<string, any>) => {
  const raw = component?.createdAt ?? component?.created_at ?? null
  if (!raw) {
    return 0
  }
  const parsed = new Date(raw).getTime()
  return Number.isNaN(parsed) ? 0 : parsed
}

const visibleComposants = computed(() => {
  const term = searchTerm.value.trim().toLowerCase()
  const source = composantsList.value || []

  const filtered = term
    ? source.filter((component) => {
        const name = (component?.name || '').toLowerCase()
        const reference = (component?.reference || '').toLowerCase()
        const category = (component?.typeComposant?.name || '').toLowerCase()
        return (
          name.includes(term) ||
          reference.includes(term) ||
          category.includes(term)
        )
      })
    : [...source]

  const direction = sortDirection.value === 'asc' ? 1 : -1

  return filtered.sort((a, b) => {
    if (sortField.value === 'name') {
      return (
        resolveComparableName(a).localeCompare(
          resolveComparableName(b),
          'fr',
          { sensitivity: 'base' }
        ) * direction
      )
    }

    return (resolveComparableDate(a) - resolveComparableDate(b)) * direction
  })
})

const handleDeleteComponent = async (component: Record<string, any>) => {
  const { blockingReasons, hasCustomFields } = resolveDeleteGuard(component)

  if (blockingReasons.length) {
    showError(
      `Impossible de supprimer ce composant car il possède encore: ${blockingReasons.join(
        ', ',
      )}. Supprimez ou détachez ces éléments avant de réessayer.`
    )
    return
  }

  const componentName = component?.name || 'ce composant'
  const confirmLines = [
    `Voulez-vous vraiment supprimer ${componentName} ?`,
  ]
  if (hasCustomFields) {
    confirmLines.push(
      'Les valeurs de champs personnalisés associées seront également supprimées.'
    )
  }

  const confirmed = window.confirm(confirmLines.join('\n\n'))
  if (!confirmed) {
    return
  }

  await deleteComposant(component.id)
}

onMounted(async () => {
  await loadComposants()
})
</script>
