<template>
  <main class="container mx-auto px-6 py-10">
    <div class="flex flex-col gap-2 mb-6 md:flex-row md:items-end md:justify-between">
      <div>
        <h1 class="text-3xl font-bold tracking-tight">Pièces</h1>
        <p class="text-sm text-base-content/70">Catalogue et catégories de pièces.</p>
      </div>
      <NuxtLink v-if="canEdit" :to="activeTab === 'categories' ? '/piece-category/new' : '/pieces/create'" class="btn btn-primary btn-sm md:btn-md">
        {{ activeTab === 'categories' ? 'Ajouter une catégorie' : 'Ajouter une pièce' }}
      </NuxtLink>
    </div>

    <EntityTabs v-model="activeTab" :tabs="pageTabs" aria-label="Pièces">
      <template #tab-catalogue>
        <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">Pièces créées</h2>
              <p class="text-sm text-base-content/70">
                Liste globale des pièces enregistrées, quel que soit leur squelette d'origine.
              </p>
            </header>

            <DataTable
              :columns="columns"
              :rows="pieceRows"
              :loading="loadingPieces"
              :sort="table.sort.value"
              :pagination="paginationState"
              :column-filters="table.columnFilters.value"
              :show-per-page="true"
              empty-message="Aucune pièce n'a encore été créée."
              no-results-message="Aucune pièce ne correspond à votre recherche."
              @sort="table.handleSort"
              @update:current-page="table.handlePageChange"
              @update:per-page="table.handlePerPageChange"
              @update:column-filters="table.handleColumnFiltersChange"
            >
              <template #toolbar>
                <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="table.searchTerm.value"
                    type="text"
                    class="input input-bordered input-sm w-full mt-1"
                    placeholder="Nom ou référence…"
                    @input="table.debouncedSearch"
                  />
                </label>
              </template>

              <template #cell-preview="{ row }">
                <DocumentThumbnail
                  :document="resolvePrimaryDocument(row.piece)"
                  :alt="resolvePreviewAlt(row.piece)"
                />
              </template>

              <template #cell-name="{ row }">
                {{ row.piece.name || 'Pièce sans nom' }}
              </template>

              <template #cell-reference="{ row }">
                {{ row.piece.reference || '—' }}
              </template>

              <template #cell-referenceAuto="{ row }">
                {{ row.piece.referenceAuto || '—' }}
              </template>

              <template #cell-description="{ row }">
                <div v-if="row.piece.description" class="group relative">
                  <span class="block cursor-help truncate">{{ row.piece.description }}</span>
                  <div class="pointer-events-none invisible absolute left-0 top-full z-50 mt-1 max-w-sm overflow-hidden rounded-lg border border-base-300 bg-base-100 p-3 text-sm shadow-sm group-hover:pointer-events-auto group-hover:visible">
                    <p class="break-words whitespace-pre-wrap">{{ row.piece.description }}</p>
                  </div>
                </div>
                <span v-else>—</span>
              </template>

              <template #cell-suppliers="{ row }">
                <div
                  v-if="row.suppliers.visible.length"
                  class="flex max-w-[14rem] flex-wrap items-center gap-1"
                  :title="row.suppliers.tooltip"
                >
                  <span
                    v-for="supplier in row.suppliers.visible"
                    :key="supplier"
                    class="badge badge-ghost badge-sm whitespace-nowrap"
                  >
                    {{ supplier }}
                  </span>
                  <span
                    v-if="row.suppliers.overflow"
                    class="badge badge-outline badge-sm"
                  >
                    +{{ row.suppliers.overflow }}
                  </span>
                </div>
                <span v-else>—</span>
              </template>

              <template #cell-typePiece="{ row }">
                <NuxtLink
                  v-if="row.piece.typePiece?.id"
                  :to="`/piece-category/${row.piece.typePiece.id}/edit`"
                  class="link link-hover link-primary"
                >
                  {{ resolvePieceType(row.piece) }}
                </NuxtLink>
                <span v-else>{{ resolvePieceType(row.piece) }}</span>
              </template>

              <template #cell-createdAt="{ row }">
                <span class="whitespace-nowrap">{{ formatDate(row.piece.createdAt) }}</span>
              </template>

              <template #cell-actions="{ row }">
                <div class="flex items-center justify-end gap-2">
                  <button
                    v-if="canEdit"
                    type="button"
                    class="btn btn-ghost btn-xs"
                    @click="navigateTo(`/piece/${row.piece.id}?edit=true`)"
                  >
                    Modifier
                  </button>
                  <button
                    v-if="canEdit"
                    type="button"
                    class="btn btn-ghost btn-xs text-error"
                    :disabled="loadingPieces"
                    @click="handleDeletePiece(row.piece)"
                  >
                    Supprimer
                  </button>
                  <NuxtLink
                    :to="`/piece/${row.piece.id}`"
                    class="btn btn-primary btn-xs"
                  >
                    Détails
                  </NuxtLink>
                </div>
              </template>
            </DataTable>
          </div>
        </section>
      </template>

      <template #tab-categories>
        <ManagementView
          category="PIECE"
          heading="Catégories de pièce"
          :hide-heading="true"
        />
      </template>
    </EntityTabs>
  </main>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import DataTable from '~/components/common/DataTable.vue'
import ManagementView from '~/components/model-types/ManagementView.vue'
import { usePieces } from '~/composables/usePieces'
import { usePieceTypes } from '~/composables/usePieceTypes'
import { useDataTable } from '~/composables/useDataTable'
import DocumentThumbnail from '~/components/DocumentThumbnail.vue'
import { buildDeleteMessageWithUsage, type UsageInfo } from '~/shared/utils/deleteImpactUtils'
import { resolvePrimaryDocument, resolvePreviewAlt, resolveSupplierNames, buildSuppliersDisplay } from '~/shared/utils/catalogDisplayUtils'
import { formatFrenchDate } from '~/utils/date'

const route = useRoute()
const { canEdit } = usePermissions()

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

const pageTabs = computed(() => {
  const t: Array<{ key: string; label: string }> = [
    { key: 'catalogue', label: 'Catalogue' },
  ]
  if (canEdit.value) {
    t.push({ key: 'categories', label: 'Catégories' })
  }
  return t
})

const { pieces, total, loadPieces, loading: loadingPieces, deletePiece } = usePieces()
const { pieceTypes, loadPieceTypes } = usePieceTypes()

const table = useDataTable(
  { fetchData: fetchPieces },
  { defaultSort: 'name', defaultDirection: 'asc', defaultPerPage: 20, persistToUrl: true, columnFilterKeys: ['typePiece'] },
)

const columns = [
  { key: 'preview', label: 'Aperçu', width: 'w-24' },
  { key: 'name', label: 'Nom', sortable: true },
  { key: 'reference', label: 'Référence' },
  { key: 'referenceAuto', label: 'Réf. auto' },
  { key: 'description', label: 'Description' },
  { key: 'suppliers', label: 'Fournisseurs' },
  { key: 'typePiece', label: 'Type de pièce', filterable: true, filterPlaceholder: 'Filtrer…' },
  { key: 'createdAt', label: 'Date', sortable: true },
  { key: 'actions', label: 'Actions' },
]

const piecesOnPage = computed(() => pieceRows.value.length)
const paginationState = table.pagination(total, piecesOnPage)

const piecesList = computed(() => {
  return (pieces.value || []).map((piece) => {
    const typePiece = pieceTypes.value.find(t => t.id === piece.typePieceId)
    return { ...piece, typePiece: typePiece || piece.typePiece || null }
  })
})

const pieceRows = computed(() =>
  piecesList.value.map(piece => ({
    id: piece.id,
    piece,
    suppliers: buildPieceSuppliersDisplay(piece),
  })),
)

async function fetchPieces() {
  await loadPieces({
    search: table.searchTerm.value,
    page: table.currentPage.value,
    itemsPerPage: table.itemsPerPage.value,
    orderBy: table.sortField.value,
    orderDir: table.sortDirection.value as 'asc' | 'desc',
    typeName: table.columnFilters.value.typePiece || undefined,
    force: true,
  })
}

const resolvePieceType = (piece: Record<string, any>) => {
  if (piece?.typePiece?.name) return piece.typePiece.name
  if (piece?.typePieceLabel) return piece.typePieceLabel
  return '—'
}

const buildPieceSuppliersDisplay = (piece: Record<string, any>) =>
  buildSuppliersDisplay(resolveSupplierNames(piece, 'product'))

const { confirm } = useConfirm()
const api = useApi()

const handleDeletePiece = async (piece: Record<string, any>) => {
  const pieceName = piece?.name || 'cette pièce'

  let usage: UsageInfo = {}
  try {
    const result = await api.get(`/pieces/${piece.id}/used-in`)
    if (result.success && result.data) {
      usage = {
        machines: result.data.machines ?? [],
        composants: result.data.composants ?? [],
      }
    }
  } catch (error) {
    console.warn('Impossible de récupérer les usages de la pièce avant suppression :', error)
  }

  const message = buildDeleteMessageWithUsage(pieceName, 'Cette pièce', usage)
  const confirmed = await confirm({ title: 'Supprimer la pièce', message, dangerous: true })
  if (!confirmed) return
  await deletePiece(piece.id)
  fetchPieces()
}

const formatDate = formatFrenchDate

onMounted(async () => {
  await Promise.all([fetchPieces(), loadPieceTypes()])
})
</script>
