<template>
  <main class="container mx-auto px-6 py-8 space-y-6">
    <div class="flex items-center justify-between">
      <div>
        <h1 class="text-3xl font-bold">
          Fournisseurs
        </h1>
        <p class="text-sm text-gray-500">
          Gérez les fournisseurs, leurs coordonnées et leurs catégories.
        </p>
      </div>
      <button v-if="canEdit" class="btn btn-primary" @click="openCreateModal">
        <IconLucidePlus class="w-4 h-4 mr-2" aria-hidden="true" />
        Nouveau fournisseur
      </button>
    </div>

    <div class="card bg-base-100 shadow-sm">
      <div class="card-body space-y-4">
        <DataTable
          :columns="columns"
          :rows="pageItems"
          :loading="loading"
          :sort="currentSort"
          :pagination="paginationState"
          :show-counter="true"
          :show-per-page="true"
          empty-message="Aucun fournisseur trouvé."
          no-results-message="Aucun fournisseur trouvé."
          @sort="handleSort"
          @update:current-page="onPageChange"
          @update:per-page="onPerPageChange"
        >
          <template #toolbar>
            <div class="flex flex-col sm:flex-row gap-3 w-full">
              <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="search"
                  class="input input-bordered input-sm w-full mt-1"
                  placeholder="Nom, email ou téléphone"
                  @input="debouncedSearch"
                >
              </label>
              <label class="w-full sm:w-64">
                <span class="text-xs font-semibold uppercase tracking-wide text-base-content/70">Catégorie</span>
                <select
                  v-model="selectedCategoryId"
                  class="select select-bordered select-sm w-full mt-1"
                >
                  <option value="">
                    Toutes les catégories
                  </option>
                  <option v-for="cat in allCategories" :key="cat.id" :value="cat.id">
                    {{ cat.name }}
                  </option>
                </select>
              </label>
            </div>
          </template>

          <template #cell-telephones="{ row }">
            <div v-if="rowPhones(row).length" class="flex flex-col gap-0.5">
              <span v-for="(tel, idx) in rowPhones(row)" :key="idx" class="whitespace-nowrap text-sm">
                {{ formatPhoneDisplay(tel.numero) }}
                <span v-if="tel.label" class="text-xs text-base-content/50">({{ tel.label }})</span>
              </span>
            </div>
            <span v-else class="text-base-content/30">—</span>
          </template>

          <template #cell-categories="{ row }">
            <div v-if="row.categories && row.categories.length" class="flex flex-wrap gap-1">
              <span
                v-for="cat in row.categories"
                :key="cat.id"
                class="badge badge-ghost badge-sm cursor-pointer hover:badge-primary transition-colors"
                @click="selectedCategoryId = cat.id"
              >
                {{ cat.name }}
              </span>
            </div>
            <span v-else class="text-base-content/30">—</span>
          </template>

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

          <template #cell-composantCount="{ row }">
            <NuxtLink
              v-if="stats[row.id]?.composantCount"
              :to="`/catalogues/composants?constructeur=${row.id}`"
              class="badge badge-ghost badge-sm hover:badge-primary transition-colors"
            >
              {{ stats[row.id].composantCount }}
            </NuxtLink>
            <span v-else class="text-base-content/30">—</span>
          </template>

          <template #cell-pieceCount="{ row }">
            <NuxtLink
              v-if="stats[row.id]?.pieceCount"
              :to="`/catalogues/pieces?constructeur=${row.id}`"
              class="badge badge-ghost badge-sm hover:badge-primary transition-colors"
            >
              {{ stats[row.id].pieceCount }}
            </NuxtLink>
            <span v-else class="text-base-content/30">—</span>
          </template>

          <template #cell-machineCount="{ row }">
            <NuxtLink
              v-if="stats[row.id]?.machineCount"
              :to="`/machines?constructeur=${row.id}`"
              class="badge badge-ghost badge-sm hover:badge-primary transition-colors"
            >
              {{ stats[row.id].machineCount }}
            </NuxtLink>
            <span v-else class="text-base-content/30">—</span>
          </template>

          <template #cell-actions="{ row }">
            <div class="flex items-center justify-end gap-2">
              <button class="btn btn-ghost btn-xs" @click="openEditModal(row)">
                {{ canEdit ? 'Modifier' : 'Consulter' }}
              </button>
              <button v-if="canEdit" class="btn btn-ghost btn-xs text-error" @click="confirmDelete(row)">
                Supprimer
              </button>
            </div>
          </template>
        </DataTable>
      </div>
    </div>

    <dialog class="modal" :class="{ 'modal-open': modalOpen }">
      <div class="modal-box max-w-2xl">
        <h3 class="font-bold text-lg mb-4">
          {{ editingConstructeur ? (canEdit ? 'Modifier' : 'Détails du') : 'Nouveau' }} fournisseur
        </h3>
        <form class="space-y-4" @submit.prevent="saveConstructeur">
          <div class="form-control">
            <label class="label"><span class="label-text">Nom</span></label>
            <input v-model="form.name" type="text" class="input input-bordered" :disabled="!canEdit" required>
          </div>

          <FieldEmail v-model="form.email" label="Email" :disabled="!canEdit" />

          <div class="form-control">
            <div class="flex items-center justify-between mb-1">
              <span class="label-text">Téléphones</span>
              <button
                v-if="canEdit"
                type="button"
                class="btn btn-ghost btn-xs"
                @click="addTelephoneRow"
              >
                <IconLucidePlus class="w-3 h-3 mr-1" aria-hidden="true" />
                Ajouter
              </button>
            </div>
            <p v-if="!form.telephones.length" class="text-sm text-base-content/50">
              Aucun téléphone.
            </p>
            <div v-for="(tel, idx) in form.telephones" :key="idx" class="flex items-end gap-2 mb-2">
              <div class="flex-1">
                <FieldPhone v-model="tel.numero" label="" :disabled="!canEdit" placeholder="Ex: 05 49 00 00 00" />
              </div>
              <input
                v-model="tel.label"
                type="text"
                class="input input-bordered input-sm md:input-md w-40"
                placeholder="Libellé (optionnel)"
                :disabled="!canEdit"
              >
              <button
                v-if="canEdit"
                type="button"
                class="btn btn-ghost btn-sm text-error"
                aria-label="Supprimer ce téléphone"
                @click="removeTelephoneRow(idx)"
              >
                <IconLucideX class="w-4 h-4" aria-hidden="true" />
              </button>
            </div>
          </div>

          <div class="form-control">
            <label class="label"><span class="label-text">Catégories</span></label>
            <ConstructeurCategorieSelect v-model="form.categories" :disabled="!canEdit" />
          </div>

          <div class="modal-action">
            <button type="button" class="btn" @click="closeModal">
              Annuler
            </button>
            <button type="submit" class="btn btn-primary" :disabled="!canEdit || saving">
              <span v-if="saving" class="loading loading-spinner loading-xs mr-2" />
              {{ editingConstructeur ? 'Enregistrer' : 'Créer' }}
            </button>
          </div>
        </form>
      </div>
    </dialog>
  </main>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import DataTable from '~/components/common/DataTable.vue'
import FieldEmail from '~/components/form/FieldEmail.vue'
import FieldPhone from '~/components/form/FieldPhone.vue'
import ConstructeurCategorieSelect from '~/components/form/ConstructeurCategorieSelect.vue'
import { useConstructeurs } from '~/composables/useConstructeurs'
import { useConstructeurCategories, type ConstructeurCategorie } from '~/composables/useConstructeurCategories'
import { useToast } from '~/composables/useToast'
import { usePersistedValue } from '~/composables/usePersistedValue'
import { constructeurPhones } from '~/shared/constructeurUtils'
import { formatPhone } from '~/utils/formatters/phone'
import { formatFrenchDate } from '~/utils/date'
import IconLucidePlus from '~icons/lucide/plus'
import IconLucideX from '~icons/lucide/x'

interface TelephoneFormRow { '@id'?: string, numero: string, label: string }
interface ConstructeurFormState {
  name: string
  email: string
  telephones: TelephoneFormRow[]
  categories: ConstructeurCategorie[]
}

const api = useApi()
const { canEdit } = usePermissions()
const { constructeurs, loading, createConstructeur, updateConstructeur, deleteConstructeur, fetchConstructeursPage } = useConstructeurs()
const { categories: allCategories, loadCategories } = useConstructeurCategories()
const { showError } = useToast()

const pageItems = ref<typeof constructeurs.value>([])
const totalItems = ref(0)
const totalPages = ref(0)
const currentPage = ref(1)
const perPage = ref(30)
const perPageOptions = [15, 30, 50, 100]

const columns = [
  { key: 'name', label: 'Nom', sortable: true },
  { key: 'email', label: 'Email', sortable: true },
  { key: 'telephones', label: 'Téléphones' },
  { key: 'categories', label: 'Catégories' },
  { key: 'createdAt', label: 'Date de création', sortable: true },
  { key: 'composantCount', label: 'Composants', align: 'center' },
  { key: 'pieceCount', label: 'Pièces', align: 'center' },
  { key: 'machineCount', label: 'Machines', align: 'center' },
  { key: 'actions', label: 'Actions', align: 'right' },
]

const searchTerm = ref('')
const selectedCategoryId = ref('')
const sortKey = usePersistedValue('constructeurs-sort', 'name')
const sortDir = ref('asc')
const stats = ref<Record<string, { composantCount?: number, pieceCount?: number, machineCount?: number }>>({})

const currentSort = computed(() => ({
  field: sortKey.value,
  direction: sortDir.value,
}))

const handleSort = (sort) => {
  sortKey.value = sort.field
  sortDir.value = sort.direction
}

const paginationState = computed(() => ({
  currentPage: currentPage.value,
  totalPages: totalPages.value,
  totalItems: totalItems.value,
  pageItems: pageItems.value.length,
  perPage: perPage.value,
  perPageOptions,
}))

const SORTABLE_FIELDS = new Set(['name', 'email', 'createdAt'])

const loadPage = async () => {
  const orderField = SORTABLE_FIELDS.has(sortKey.value)
    ? (sortKey.value as 'name' | 'email' | 'createdAt')
    : 'name'
  const result = await fetchConstructeursPage({
    page: currentPage.value,
    itemsPerPage: perPage.value,
    search: searchTerm.value,
    categoryId: selectedCategoryId.value || undefined,
    orderField,
    orderDirection: sortDir.value === 'desc' ? 'desc' : 'asc',
  })
  if (!result.success) {
    if (result.error) showError(result.error)
    pageItems.value = []
    totalItems.value = 0
    totalPages.value = 0
    return
  }
  pageItems.value = result.items
  totalItems.value = result.totalItems
  totalPages.value = result.totalPages
  if (currentPage.value > result.totalPages && result.totalPages > 0) {
    currentPage.value = result.totalPages
  }
}

const modalOpen = ref(false)
const saving = ref(false)
const editingConstructeur = ref<Record<string, any> | null>(null)
const form = ref<ConstructeurFormState>({ name: '', email: '', telephones: [], categories: [] })

const rowPhones = constructeurPhones

const debouncedSearch = debounce(() => {
  currentPage.value = 1
  loadPage()
}, 300)

watch(selectedCategoryId, () => {
  currentPage.value = 1
  loadPage()
})

watch([sortKey, sortDir], () => {
  currentPage.value = 1
  loadPage()
})

const onPageChange = (page: number) => {
  currentPage.value = page
  loadPage()
}

const onPerPageChange = (value: number) => {
  perPage.value = value
  currentPage.value = 1
  loadPage()
}

const formatDate = formatFrenchDate

const formatPhoneDisplay = value => formatPhone(value) || value || '—'

function debounce(fn, delay) {
  let timeout
  return (...args) => {
    clearTimeout(timeout)
    timeout = setTimeout(() => fn(...args), delay)
  }
}

const resetForm = () => {
  form.value = { name: '', email: '', telephones: [], categories: [] }
  editingConstructeur.value = null
}

const openCreateModal = () => {
  resetForm()
  modalOpen.value = true
}

const openEditModal = (constructeur) => {
  editingConstructeur.value = constructeur
  form.value = {
    name: constructeur.name,
    email: constructeur.email || '',
    telephones: (constructeur.telephones || []).map(t => ({
      '@id': t['@id'],
      numero: t.numero || '',
      label: t.label || '',
    })),
    categories: (constructeur.categories || []).map(c => ({ ...c })),
  }
  modalOpen.value = true
}

const closeModal = () => {
  modalOpen.value = false
  resetForm()
}

const addTelephoneRow = () => {
  form.value.telephones.push({ numero: '', label: '' })
}

const removeTelephoneRow = (idx) => {
  form.value.telephones.splice(idx, 1)
}

const saveConstructeur = async () => {
  const trimmedName = form.value.name.trim()
  if (!trimmedName) {
    showError('Le nom est obligatoire.')
    return
  }
  const duplicate = constructeurs.value.find(
    c => c.name.toLowerCase() === trimmedName.toLowerCase()
      && c.id !== editingConstructeur.value?.id,
  )
  if (duplicate) {
    showError(`Un fournisseur "${duplicate.name}" existe déjà.`)
    return
  }

  saving.value = true
  const payload = {
    name: trimmedName,
    email: form.value.email?.trim() || null,
    telephones: form.value.telephones
      .filter(t => t.numero && t.numero.trim())
      .map((t) => {
        const entry: { numero: string, label: string | null, '@id'?: string } = {
          numero: t.numero.trim(),
          label: t.label?.trim() || null,
        }
        if (t['@id']) { entry['@id'] = t['@id'] }
        return entry
      }),
    categories: form.value.categories
      .map(c => c['@id'] || (c.id ? `/api/constructeur_categories/${c.id}` : null))
      .filter((iri): iri is string => Boolean(iri)),
  }

  let result
  if (editingConstructeur.value) {
    result = await updateConstructeur(editingConstructeur.value.id, payload)
  }
  else {
    result = await createConstructeur(payload)
  }
  saving.value = false
  if (result.success) {
    closeModal()
    await loadPage()
  }
}

const { confirm } = useConfirm()

const confirmDelete = async (constructeur) => {
  if (!await confirm({ message: `Supprimer le fournisseur "${constructeur.name}" ?` })) { return }
  const result = await deleteConstructeur(constructeur.id)
  if (!result.success && result.error) {
    showError(result.error)
    return
  }
  if (result.success) {
    await loadPage()
  }
}

const loadStats = async () => {
  const result = await api.get('/constructeurs/stats')
  if (result.success && result.data) {
    stats.value = result.data
  }
}

onMounted(() => {
  loadPage()
  loadCategories()
  loadStats()
})
</script>
