<template>
  <main class="container mx-auto px-6 py-8 space-y-8">
    <header class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
      <div class="space-y-1">
        <h1 class="text-3xl font-bold text-gray-800">
          Catalogue de composant
        </h1>
        <p class="text-sm text-gray-500">
          Gérez les modèles disponibles pour chaque famille de composant.
        </p>
      </div>
      <div class="tabs tabs-boxed">
        <NuxtLink to="/component-catalog" class="tab tab-active">
          Composants
        </NuxtLink>
        <NuxtLink to="/pieces-catalog" class="tab">
          Pièces
        </NuxtLink>
      </div>
    </header>

    <div class="grid grid-cols-1 gap-8 xl:grid-cols-[2fr,1fr]">
      <section class="card bg-base-100 shadow-lg">
        <div class="card-body space-y-4">
          <div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
            <div class="flex flex-col gap-2 md:flex-row md:items-center md:gap-4">
              <label class="form-control w-full md:w-64">
                <span class="label-text text-sm">Type de composant</span>
                <select v-model="selectedType" class="select select-bordered select-sm">
                  <option value="all">Tous les types</option>
                  <option
                    v-for="type in componentTypes"
                    :key="type.id"
                    :value="type.id"
                  >
                    {{ type.name }}
                  </option>
                </select>
              </label>
              <label class="form-control">
                <span class="label-text text-sm">Filtrer</span>
                <input
                  v-model="searchQuery"
                  type="search"
                  placeholder="Rechercher un modèle..."
                  class="input input-bordered input-sm"
                >
              </label>
              <span class="text-xs text-gray-500">{{ filteredModels.length }} modèle(s)</span>
            </div>
            <button type="button" class="btn btn-primary btn-sm w-full md:w-auto" @click="startCreate">
              <IconLucidePlus class="w-4 h-4 mr-2" aria-hidden="true" />
              Nouveau modèle
            </button>
          </div>

          <div v-if="loadingComponentModels" class="flex justify-center py-16">
            <span class="loading loading-spinner loading-lg" />
          </div>

          <div v-else-if="filteredModels.length === 0" class="py-16 text-center text-sm text-gray-500">
            Aucun modèle ne correspond à ce filtre.
          </div>

          <div v-else class="overflow-x-auto">
            <table class="table">
              <thead>
                <tr class="text-sm text-gray-500">
                  <th>Nom</th>
                  <th class="hidden md:table-cell">
                    Description
                  </th>
                  <th>Type</th>
                  <th class="hidden xl:table-cell">
                    Structure
                  </th>
                  <th class="hidden lg:table-cell">
                    Modifié
                  </th>
                  <th class="text-right">
                    Actions
                  </th>
                </tr>
              </thead>
              <tbody>
                <tr
                  v-for="model in filteredModels"
                  :key="model.id"
                  :class="{
                    'bg-base-200/60': form.mode === 'edit' && form.data.id === model.id
                  }"
                >
                  <td>
                    <div class="flex items-center gap-2">
                      <IconLucideLayers class="w-4 h-4 text-primary" aria-hidden="true" />
                      <span class="font-medium">{{ model.name }}</span>
                    </div>
                  </td>
                  <td class="hidden md:table-cell">
                    {{ model.description || '—' }}
                  </td>
                  <td>{{ model.typeComposant?.name || 'Non défini' }}</td>
                  <td class="hidden xl:table-cell text-xs text-gray-500">
                    {{ formatStructurePreview(model.structure) }}
                  </td>
                  <td class="hidden lg:table-cell text-xs text-gray-500">
                    {{ formatFrenchDate(model.updatedAt || model.createdAt) }}
                  </td>
                  <td class="text-right space-x-2">
                    <button type="button" class="btn btn-sm btn-outline" @click="startEdit(model)">
                      Éditer
                    </button>
                    <button type="button" class="btn btn-sm btn-error" @click="confirmDelete(model)">
                      Supprimer
                    </button>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </section>

      <aside class="card bg-base-100 shadow-lg">
        <div class="card-body space-y-4">
          <div class="flex items-center justify-between">
            <h2 class="card-title text-lg">
              {{ form.mode === 'edit' ? 'Modifier le modèle' : 'Nouveau modèle' }}
            </h2>
            <button
              v-if="form.mode === 'edit'"
              type="button"
              class="btn btn-ghost btn-xs"
              @click="startCreate"
            >
              Réinitialiser
            </button>
          </div>

          <form class="space-y-4" @submit.prevent="handleSubmit">
            <div class="form-control">
              <label class="label"><span class="label-text">Nom</span></label>
              <input
                v-model="form.data.name"
                type="text"
                class="input input-bordered input-sm"
                placeholder="Nom du modèle"
                required
              >
            </div>
            <div class="form-control">
              <label class="label"><span class="label-text">Description</span></label>
              <textarea
                v-model="form.data.description"
                class="textarea textarea-bordered textarea-sm"
                rows="3"
                placeholder="Notes optionnelles"
              />
            </div>
            <div class="form-control">
              <label class="label"><span class="label-text">Type de composant</span></label>
              <select
                v-model="form.data.typeComposantId"
                class="select select-bordered select-sm"
                required
              >
                <option value="" disabled>
                  Sélectionner un type
                </option>
                <option
                  v-for="type in componentTypes"
                  :key="type.id"
                  :value="type.id"
                >
                  {{ type.name }}
                </option>
              </select>
            </div>

            <div class="divider my-0">
              Structure
            </div>
            <ComponentModelStructureEditor
              v-model="form.data.structure"
              :root-type-id="form.data.typeComposantId"
              :root-type-label="selectedComponentTypeLabel"
              :lock-root-type="!!form.data.typeComposantId"
            />
            <div class="rounded-lg border border-base-200 bg-base-200/60 p-3 text-xs text-gray-500">
              Aperçu : {{ formatStructurePreview(form.data.structure) }}
            </div>

            <div class="card-actions justify-end">
              <button type="submit" class="btn btn-primary" :class="{ loading: form.submitting }">
                {{ form.mode === 'edit' ? 'Enregistrer' : 'Créer' }}
              </button>
            </div>
          </form>
        </div>
      </aside>
    </div>
  </main>
</template>

<script setup>
import { ref, computed, reactive, onMounted, watch } from 'vue'
import { useComponentModels } from '~/composables/useComponentModels'
import { useComponentTypes } from '~/composables/useComponentTypes'
import { useToast } from '~/composables/useToast'
import ComponentModelStructureEditor from '~/components/ComponentModelStructureEditor.vue'
import {
  formatStructurePreview,
  defaultStructure,
  cloneStructure,
  normalizeStructureForSave,
} from '~/shared/modelUtils'
import { componentModelStructureValidator } from '~/shared/types/inventory'
import { formatFrenchDate } from '~/utils/date'
import IconLucidePlus from '~icons/lucide/plus'
import IconLucideLayers from '~icons/lucide/layers'

const { componentTypes, loadComponentTypes } = useComponentTypes()
const {
  componentModels,
  loadComponentModels,
  createComponentModel,
  updateComponentModel,
  deleteComponentModel,
  loadingComponentModels,
  getComponentModelsForType
} = useComponentModels()
const { showError, showSuccess } = useToast()

const selectedType = ref('all')
const searchQuery = ref('')

const form = reactive({
  mode: 'create',
  submitting: false,
  data: {
    id: null,
    name: '',
    description: '',
    typeComposantId: '',
    structure: defaultStructure(),
  }
})

const ensureTypeSelected = () => {
  if (form.data.typeComposantId && componentTypes.value.some(type => type.id === form.data.typeComposantId)) {
    return
  }
  if (selectedType.value !== 'all' && componentTypes.value.some(type => type.id === selectedType.value)) {
    form.data.typeComposantId = selectedType.value
    return
  }
  form.data.typeComposantId = componentTypes.value[0]?.id || ''
}

const startCreate = () => {
  form.mode = 'create'
  form.data = {
    id: null,
    name: '',
    description: '',
    typeComposantId: selectedType.value !== 'all' ? selectedType.value : '',
    structure: defaultStructure(),
  }
  ensureTypeSelected()
}

const startEdit = (model) => {
  form.mode = 'edit'
  form.data = {
    id: model.id,
    name: model.name,
    description: model.description || '',
    typeComposantId: model.typeComposantId || model.typeComposant?.id || '',
    structure: cloneStructure(model.structure || defaultStructure()),
  }
}

const filteredModels = computed(() => {
  const list = selectedType.value === 'all'
    ? componentModels.value
    : getComponentModelsForType(selectedType.value) || []

  if (!searchQuery.value.trim()) {
    return list
  }
  const term = searchQuery.value.toLowerCase()
  return list.filter((model) => {
    return (
      model.name?.toLowerCase().includes(term) ||
      model.description?.toLowerCase().includes(term) ||
      model.typeComposant?.name?.toLowerCase().includes(term)
    )
  })
})

const selectedComponentType = computed(() => {
  if (!form.data.typeComposantId) {
    return null
  }
  return componentTypes.value.find((type) => type.id === form.data.typeComposantId) || null
})

const selectedComponentTypeLabel = computed(() => {
  const type = selectedComponentType.value
  if (!type) {
    return ''
  }
  return type.code ? `${type.name} (${type.code})` : type.name
})

const refreshModels = async () => {
  if (selectedType.value === 'all') {
    await loadComponentModels()
  } else {
    await loadComponentModels(selectedType.value)
  }
}

const handleSubmit = async () => {
  if (!form.data.typeComposantId) {
    showError('Veuillez sélectionner un type de composant')
    return
  }

  form.submitting = true
  try {
    const normalizedStructure = normalizeStructureForSave(form.data.structure)
    const validationResult = componentModelStructureValidator.safeParse(normalizedStructure)
    if (!validationResult.success) {
      showError(`Structure invalide: ${validationResult.issues.join(', ')}`)
      return
    }

    if (form.mode === 'create') {
      const result = await createComponentModel({
        name: form.data.name.trim(),
        description: form.data.description.trim() || undefined,
        typeComposantId: form.data.typeComposantId,
        structure: normalizedStructure,
      })
      if (!result.success) {
        showError(result.error || 'Impossible de créer le modèle')
        return
      }
      showSuccess(`Modèle "${result.data.name}" créé`)
    } else if (form.data.id) {
      const result = await updateComponentModel(form.data.id, {
        name: form.data.name.trim(),
        description: form.data.description.trim() || undefined,
        typeComposantId: form.data.typeComposantId,
        structure: normalizedStructure,
      })
      if (!result.success) {
        showError(result.error || 'Impossible de mettre à jour le modèle')
        return
      }
      showSuccess(`Modèle "${result.data.name}" mis à jour`)
    }

    await refreshModels()
    startCreate()
  } finally {
    form.submitting = false
  }
}

const confirmDelete = async (model) => {
  const ok = confirm(`Supprimer le modèle "${model.name}" ?`)
  if (!ok) { return }
  const result = await deleteComponentModel(model.id)
  if (!result.success) {
    showError(result.error || 'Impossible de supprimer ce modèle')
    return
  }
  if (form.mode === 'edit' && form.data.id === model.id) {
    startCreate()
  }
  showSuccess('Modèle supprimé')
  await refreshModels()
}

onMounted(async () => {
  await Promise.all([loadComponentTypes(), loadComponentModels()])
  ensureTypeSelected()
})

watch(selectedType, async () => {
  await refreshModels()
  if (form.mode === 'create') {
    ensureTypeSelected()
  }
})
</script>
