<template>
  <main class="container mx-auto px-6 py-8 space-y-8">
    <div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
      <div>
        <h1 class="text-3xl font-bold text-gray-800">Catalogue de modèles</h1>
        <p class="text-sm text-gray-500">
          Administrez les modèles de composants et de pièces disponibles lors de la création des machines.
        </p>
      </div>
      <div class="tabs tabs-boxed w-full md:w-auto">
        <button
          type="button"
          class="tab"
          :class="{ 'tab-active': activeTab === 'components' }"
          @click="activeTab = 'components'"
        >
          Modèles de composants
        </button>
        <button
          type="button"
          class="tab"
          :class="{ 'tab-active': activeTab === 'pieces' }"
          @click="activeTab = 'pieces'"
        >
          Modèles de pièces
        </button>
      </div>
    </div>

    <!-- Component Models -->
    <section v-if="activeTab === 'components'" class="space-y-4">
      <div 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="selectedComponentType" 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>
              <span class="text-xs text-gray-500">
                {{ componentModelsList.length }} modèle(s)
              </span>
            </div>
            <button type="button" class="btn btn-primary btn-sm w-full md:w-auto" @click="openComponentModal('create')">
              <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-12">
            <span class="loading loading-spinner loading-md"></span>
          </div>

          <div v-else-if="componentModelsList.length === 0" class="py-12 text-center text-sm text-gray-500">
            Aucun modèle trouvé pour 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 lg:table-cell">Structure</th>
                  <th class="hidden lg:table-cell">Dernière modification</th>
                  <th class="text-right">Actions</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="model in componentModelsList" :key="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 lg:table-cell">{{ formatStructurePreview(model.structure) }}</td>
                  <td class="hidden lg:table-cell">{{ formatDate(model.updatedAt || model.createdAt) }}</td>
                  <td class="text-right space-x-2">
                    <button type="button" class="btn btn-sm btn-outline" @click="openComponentModal('edit', model)">
                      Éditer
                    </button>
                    <button type="button" class="btn btn-sm btn-error" @click="confirmDeleteComponentModel(model)">
                      Supprimer
                    </button>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </section>

    <!-- Piece Models -->
    <section v-else class="space-y-4">
      <div 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 pièce</span>
                <select v-model="selectedPieceType" class="select select-bordered select-sm">
                  <option value="all">Tous les types</option>
                  <option
                    v-for="type in pieceTypes"
                    :key="type.id"
                    :value="type.id"
                  >
                    {{ type.name }}
                  </option>
                </select>
              </label>
              <span class="text-xs text-gray-500">
                {{ pieceModelsList.length }} modèle(s)
              </span>
            </div>
            <button type="button" class="btn btn-primary btn-sm w-full md:w-auto" @click="openPieceModal('create')">
              <IconLucidePlus class="w-4 h-4 mr-2" aria-hidden="true" />
              Nouveau modèle
            </button>
          </div>

          <div v-if="loadingPieceModels" class="flex justify-center py-12">
            <span class="loading loading-spinner loading-md"></span>
          </div>

          <div v-else-if="pieceModelsList.length === 0" class="py-12 text-center text-sm text-gray-500">
            Aucun modèle trouvé pour 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 lg:table-cell">Dernière modification</th>
                  <th class="text-right">Actions</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="model in pieceModelsList" :key="model.id">
                  <td>
                    <div class="flex items-center gap-2">
                      <IconLucidePackage class="w-4 h-4 text-secondary" aria-hidden="true" />
                      <span class="font-medium">{{ model.name }}</span>
                    </div>
                  </td>
                  <td class="hidden md:table-cell">{{ model.description || '—' }}</td>
                  <td>{{ model.typePiece?.name || 'Non défini' }}</td>
                  <td class="hidden lg:table-cell">{{ formatDate(model.updatedAt || model.createdAt) }}</td>
                  <td class="text-right space-x-2">
                    <button type="button" class="btn btn-sm btn-outline" @click="openPieceModal('edit', model)">
                      Éditer
                    </button>
                    <button type="button" class="btn btn-sm btn-error" @click="confirmDeletePieceModel(model)">
                      Supprimer
                    </button>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </section>

    <!-- Component Model Modal -->
    <div v-if="componentModal.open" class="modal modal-open">
      <div class="modal-box max-w-4xl">
        <h3 class="font-bold text-lg mb-1">
          {{ componentModal.mode === 'create' ? 'Nouveau modèle de composant' : 'Modifier le modèle de composant' }}
        </h3>
        <p class="text-xs text-gray-500 mb-4">
          Définissez le modèle de composant ainsi que sa structure par défaut (sous-composants, pièces et champs personnalisés).
        </p>
        <form class="space-y-5" @submit.prevent="submitComponentModal">
          <div class="form-control">
            <label class="label"><span class="label-text">Nom</span></label>
            <input v-model="componentModal.form.name" type="text" class="input input-bordered input-sm" required />
          </div>
          <div class="form-control">
            <label class="label"><span class="label-text">Description</span></label>
            <textarea
              v-model="componentModal.form.description"
              class="textarea textarea-bordered textarea-sm"
              rows="3"
              placeholder="Notes sur ce modèle"
            ></textarea>
          </div>
          <div class="form-control">
            <label class="label"><span class="label-text">Type de composant</span></label>
            <select v-model="componentModal.form.typeComposantId" class="select select-bordered select-sm" required>
              <option value="" disabled>Choisir 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="componentModal.form.structure" />
          <div class="rounded-lg border border-base-200 bg-base-200/60 p-3">
            <ModelStructureViewer :structure="componentModal.form.structure" />
          </div>
          <div class="modal-action">
            <button type="button" class="btn btn-outline" @click="closeComponentModal">Annuler</button>
            <button type="submit" class="btn btn-primary" :class="{ loading: componentModal.submitting }">
              {{ componentModal.mode === 'create' ? 'Créer' : 'Enregistrer' }}
            </button>
          </div>
        </form>
      </div>
    </div>

    <!-- Piece Model Modal -->
    <div v-if="pieceModal.open" class="modal modal-open">
      <div class="modal-box max-w-md">
        <h3 class="font-bold text-lg mb-1">
          {{ pieceModal.mode === 'create' ? 'Nouveau modèle de pièce' : 'Modifier le modèle de pièce' }}
        </h3>
        <form class="space-y-4" @submit.prevent="submitPieceModal">
          <div class="form-control">
            <label class="label"><span class="label-text">Nom</span></label>
            <input v-model="pieceModal.form.name" type="text" class="input input-bordered input-sm" required />
          </div>
          <div class="form-control">
            <label class="label"><span class="label-text">Description</span></label>
            <textarea
              v-model="pieceModal.form.description"
              class="textarea textarea-bordered textarea-sm"
              rows="3"
              placeholder="Notes sur ce modèle"
            ></textarea>
          </div>
          <div class="form-control">
            <label class="label"><span class="label-text">Type de pièce</span></label>
            <select v-model="pieceModal.form.typePieceId" class="select select-bordered select-sm" required>
              <option value="" disabled>Choisir un type</option>
              <option
                v-for="type in pieceTypes"
                :key="type.id"
                :value="type.id"
              >
                {{ type.name }}
              </option>
            </select>
          </div>
          <div class="modal-action">
            <button type="button" class="btn btn-outline" @click="closePieceModal">Annuler</button>
            <button type="submit" class="btn btn-primary" :class="{ loading: pieceModal.submitting }">
              {{ pieceModal.mode === 'create' ? 'Créer' : 'Enregistrer' }}
            </button>
          </div>
        </form>
      </div>
    </div>
  </main>
</template>

<script setup>
import { ref, computed, reactive, watch, onMounted } from 'vue'
import { useComponentModels } from '~/composables/useComponentModels'
import { usePieceModels } from '~/composables/usePieceModels'
import { useComponentTypes } from '~/composables/useComponentTypes'
import { usePieceTypes } from '~/composables/usePieceTypes'
import { useToast } from '~/composables/useToast'
import IconLucidePlus from '~icons/lucide/plus'
import IconLucideLayers from '~icons/lucide/layers'
import IconLucidePackage from '~icons/lucide/package'
import ComponentModelStructureEditor from '~/components/ComponentModelStructureEditor.vue'
import ModelStructureViewer from '~/components/ModelStructureViewer.vue'
import {
  defaultStructure,
  cloneStructure,
  formatStructurePreview,
  normalizeStructureForSave,
} from '~/shared/modelUtils'

const activeTab = ref('components')
const selectedComponentType = ref('all')
const selectedPieceType = ref('all')

const { componentTypes, loadComponentTypes } = useComponentTypes()
const { pieceTypes, loadPieceTypes } = usePieceTypes()

const {
  componentModels,
  loadComponentModels,
  createComponentModel,
  updateComponentModel,
  deleteComponentModel,
  loadingComponentModels,
  getComponentModelsForType,
} = useComponentModels()

const {
  pieceModels,
  loadPieceModels,
  createPieceModel,
  updatePieceModel,
  deletePieceModel,
  loadingPieceModels,
  getPieceModelsForType,
} = usePieceModels()

const toast = useToast()

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

const pieceModal = reactive({
  open: false,
  mode: 'create',
  submitting: false,
  previousTypeId: null,
  form: {
    id: null,
    name: '',
    description: '',
    typePieceId: '',
  },
})

const componentModelsList = computed(() => {
  if (selectedComponentType.value === 'all') {
    return componentModels.value
  }
  return getComponentModelsForType(selectedComponentType.value) || []
})

const pieceModelsList = computed(() => {
  if (selectedPieceType.value === 'all') {
    return pieceModels.value
  }
  return getPieceModelsForType(selectedPieceType.value) || []
})

const formatDate = (value) => {
  if (!value) return '—'
  const date = new Date(value)
  return date.toLocaleDateString('fr-FR', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
  })
}

const ensureTypeSelected = (typeId, list) => {
  if (typeId && list.some((type) => type.id === typeId)) {
    return typeId
  }
  return list[0]?.id || ''
}

const openComponentModal = (mode, model) => {
  componentModal.mode = mode
  componentModal.open = true
  componentModal.submitting = false
  componentModal.previousTypeId = model?.typeComposantId || null
  if (mode === 'edit' && model) {
    componentModal.form = {
      id: model.id,
      name: model.name,
      description: model.description || '',
      typeComposantId: model.typeComposantId || model.typeComposant?.id || '',
      structure: cloneStructure(model.structure || defaultStructure()),
    }
  } else {
    componentModal.form = {
      id: null,
      name: '',
      description: '',
      typeComposantId: ensureTypeSelected(selectedComponentType.value !== 'all' ? selectedComponentType.value : '', componentTypes.value),
      structure: defaultStructure(),
    }
  }
}

const closeComponentModal = () => {
  componentModal.open = false
}

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

  componentModal.submitting = true
  try {
    if (componentModal.mode === 'create') {
      await createComponentModel({
        name: componentModal.form.name.trim(),
        description: componentModal.form.description.trim() || undefined,
        typeComposantId: componentModal.form.typeComposantId,
        structure: normalizeStructureForSave(componentModal.form.structure),
      })
    } else {
      await updateComponentModel(componentModal.form.id, {
        name: componentModal.form.name.trim(),
        description: componentModal.form.description.trim() || undefined,
        typeComposantId: componentModal.form.typeComposantId,
        structure: normalizeStructureForSave(componentModal.form.structure),
      })
    }

    await refreshComponentModels(componentModal.form.typeComposantId)
    if (selectedComponentType.value === 'all') {
      await refreshComponentModels()
    }
    if (
      componentModal.mode === 'edit' &&
      componentModal.previousTypeId &&
      componentModal.previousTypeId !== componentModal.form.typeComposantId
    ) {
      await refreshComponentModels(componentModal.previousTypeId)
    }

    closeComponentModal()
  } catch (error) {
    toast.showError('Impossible d\'enregistrer le modèle de composant')
  } finally {
    componentModal.submitting = false
  }
}

const confirmDeleteComponentModel = async (model) => {
  if (!confirm(`Supprimer le modèle "${model.name}" ?`)) return
  try {
    const result = await deleteComponentModel(model.id)
    if (result.success) {
      await refreshComponentModels(model.typeComposantId)
      if (selectedComponentType.value === 'all') {
        await refreshComponentModels()
      }
    }
  } catch (error) {
    toast.showError('Impossible de supprimer ce modèle')
  }
}

const openPieceModal = (mode, model) => {
  pieceModal.mode = mode
  pieceModal.open = true
  pieceModal.submitting = false
  pieceModal.previousTypeId = model?.typePieceId || null
  if (mode === 'edit' && model) {
    pieceModal.form = {
      id: model.id,
      name: model.name,
      description: model.description || '',
      typePieceId: model.typePieceId || model.typePiece?.id || '',
    }
  } else {
    pieceModal.form = {
      id: null,
      name: '',
      description: '',
      typePieceId: ensureTypeSelected(selectedPieceType.value !== 'all' ? selectedPieceType.value : '', pieceTypes.value),
    }
  }
}

const closePieceModal = () => {
  pieceModal.open = false
}

const submitPieceModal = async () => {
  if (!pieceModal.form.typePieceId) {
    toast.showError('Veuillez sélectionner un type de pièce')
    return
  }

  pieceModal.submitting = true
  try {
    if (pieceModal.mode === 'create') {
      await createPieceModel({
        name: pieceModal.form.name.trim(),
        description: pieceModal.form.description.trim() || undefined,
        typePieceId: pieceModal.form.typePieceId,
        structure: {},
      })
    } else {
      await updatePieceModel(pieceModal.form.id, {
        name: pieceModal.form.name.trim(),
        description: pieceModal.form.description.trim() || undefined,
        typePieceId: pieceModal.form.typePieceId,
      })
    }

    await refreshPieceModels(pieceModal.form.typePieceId)
    if (selectedPieceType.value === 'all') {
      await refreshPieceModels()
    }
    if (
      pieceModal.mode === 'edit' &&
      pieceModal.previousTypeId &&
      pieceModal.previousTypeId !== pieceModal.form.typePieceId
    ) {
      await refreshPieceModels(pieceModal.previousTypeId)
    }

    closePieceModal()
  } catch (error) {
    toast.showError('Impossible d\'enregistrer le modèle de pièce')
  } finally {
    pieceModal.submitting = false
  }
}

const confirmDeletePieceModel = async (model) => {
  if (!confirm(`Supprimer le modèle "${model.name}" ?`)) return
  try {
    const result = await deletePieceModel(model.id)
    if (result.success) {
      await refreshPieceModels(model.typePieceId)
      if (selectedPieceType.value === 'all') {
        await refreshPieceModels()
      }
    }
  } catch (error) {
    toast.showError('Impossible de supprimer ce modèle')
  }
}

const refreshComponentModels = async (typeId) => {
  if (typeId) {
    await loadComponentModels(typeId)
  } else {
    await loadComponentModels()
  }
}

const refreshPieceModels = async (typeId) => {
  if (typeId) {
    await loadPieceModels(typeId)
  } else {
    await loadPieceModels()
  }
}

watch(selectedComponentType, async (value) => {
  await refreshComponentModels(value === 'all' ? undefined : value)
}, { immediate: true })

watch(selectedPieceType, async (value) => {
  await refreshPieceModels(value === 'all' ? undefined : value)
}, { immediate: true })

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