<template>
  <main class="container mx-auto px-6 py-10">
    <section class="card border border-base-200 bg-base-100 shadow-sm max-w-5xl mx-auto">
      <div class="card-body space-y-6">
        <DetailHeader
          title="Nouvelle pièce"
          subtitle="Choisissez la catégorie adaptée puis renseignez toutes les informations de votre pièce."
          :is-edit-mode="false"
          :can-edit="false"
          back-link="/catalogues/pieces"
        />

        <EntityTabs v-model="activeTab" :tabs="entityTabs" aria-label="Sections de la pièce">
          <template #tab-general>
            <div class="space-y-6">
              <!-- Catégorie -->
              <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
                <div class="form-control">
                  <label class="label">
                    <span class="label-text">Catégorie de pièce</span>
                  </label>
                  <SearchSelect
                    v-model="selectedTypeId"
                    :options="pieceTypeList"
                    :loading="loadingTypes"
                    size="sm"
                    placeholder="Rechercher une catégorie..."
                    empty-text="Aucune catégorie disponible"
                    :option-label="typeOptionLabel"
                    :option-description="typeOptionDescription"
                    :disabled="!canEdit || loadingTypes || submitting"
                  />
                  <p v-if="loadingTypes" class="text-xs text-gray-500 mt-1">
                    Chargement des catégories…
                  </p>
                </div>
              </div>

              <!-- Nom -->
              <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
                <div class="form-control">
                  <label class="label">
                    <span class="label-text">Nom de la pièce</span>
                  </label>
                  <input
                    v-model="creationForm.name"
                    type="text"
                    class="input input-bordered input-sm md:input-md"
                    :disabled="!canEdit || submitting || !selectedType"
                    placeholder="Nom affiché dans le catalogue"
                    required
                  >
                </div>
              </div>

              <!-- Description -->
              <div class="form-control">
                <label class="label">
                  <span class="label-text">Description</span>
                </label>
                <textarea
                  v-model="creationForm.description"
                  class="textarea textarea-bordered textarea-sm md:textarea-md"
                  :disabled="!canEdit || submitting || !selectedType"
                  placeholder="Description de la pièce (optionnel)"
                  rows="3"
                />
              </div>

              <!-- Référence + Fournisseurs -->
              <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
                <div class="form-control">
                  <label class="label">
                    <span class="label-text">Référence</span>
                  </label>
                  <input
                    v-model="creationForm.reference"
                    type="text"
                    class="input input-bordered input-sm md:input-md"
                    :disabled="!canEdit || submitting || !selectedType"
                    placeholder="Référence interne ou fournisseur"
                  >
                </div>

                <div class="form-control">
                  <label class="label">
                    <span class="label-text">Fournisseur</span>
                  </label>
                  <ConstructeurSelect
                    v-model="creationForm.constructeurIds"
                    class="w-full"
                    :disabled="!canEdit || submitting || !selectedType"
                    placeholder="Rechercher un ou plusieurs fournisseurs..."
                  />
                </div>
              </div>

              <ConstructeurLinksTable
                v-if="constructeurLinks.length"
                v-model="constructeurLinks"
              />

              <!-- Prix -->
              <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
                <div class="form-control">
                  <label class="label">
                    <span class="label-text">Prix indicatif (€)</span>
                  </label>
                  <input
                    v-model="creationForm.prix"
                    type="number"
                    step="0.01"
                    min="0"
                    class="input input-bordered input-sm md:input-md"
                    :disabled="!canEdit || submitting || !selectedType"
                    placeholder="Valeur indicatrice"
                  >
                </div>
              </div>

              <!-- Skeleton preview -->
              <StructureSkeletonPreview
                v-if="selectedType"
                :structure="selectedType.structure"
                :description="selectedType.description || 'Ce squelette définit la structure et les champs personnalisés de la pièce.'"
                :preview-badge="formatPieceStructurePreview(selectedType.structure)"
                variant="piece"
              />
            </div>
          </template>

          <template #tab-products>
            <div class="space-y-6">
              <div
                v-if="structureProducts.length"
                class="space-y-3 rounded-lg border border-base-200 bg-base-200/40 p-4"
              >
                <header class="space-y-1">
                  <h2 class="font-semibold text-base-content">
                    Produit requis par le squelette
                  </h2>
                  <p class="text-xs text-base-content/70">
                    Sélectionnez un produit catalogue compatible avec les exigences ci-dessous.
                  </p>
                </header>
                <ul class="space-y-2 text-sm text-base-content/80">
                  <li
                    v-for="(description, index) in productRequirementDescriptions"
                    :key="`requirement-${index}`"
                    class="flex items-start gap-2"
                  >
                    <span class="mt-0.5 inline-flex h-2 w-2 flex-shrink-0 rounded-full bg-primary"></span>
                    <span>{{ description }}</span>
                  </li>
                </ul>
                <div class="grid grid-cols-1 gap-3 md:grid-cols-2">
                  <div
                    v-for="entry in productRequirementEntries"
                    :key="entry.key"
                    class="form-control"
                  >
                    <label class="label">
                      <span class="label-text text-xs font-medium">
                        {{ entry.label }}
                      </span>
                    </label>
                    <ProductSelect
                      :model-value="productSelections[entry.index] || null"
                      :disabled="!canEdit || submitting || !selectedType"
                      :type-product-id="entry.typeProductId"
                      helper-text="Sélectionnez un produit (optionnel)."
                      @update:model-value="(value) => setProductSelection(entry.index, value)"
                    />
                  </div>
                </div>
              </div>

              <EmptyState
                v-if="!structureProducts.length"
                title="Aucun produit requis"
                :description="selectedType ? 'Cette catégorie ne requiert pas de produit lié.' : 'Sélectionnez une catégorie pour voir les produits requis.'"
              />
            </div>
          </template>

          <template #tab-documents>
            <div class="space-y-4 rounded-lg border border-base-200 bg-base-200/40 p-4">
              <header class="flex flex-col gap-1 md:flex-row md:items-center md:justify-between">
                <div>
                  <h2 class="font-semibold text-base-content">Documents</h2>
                  <p class="text-xs text-base-content/70">
                    Ajoutez des documents (PDF, images, textes…) liés à cette pièce.
                  </p>
                </div>
                <span v-if="selectedDocuments.length" class="badge badge-outline">
                  {{ selectedDocuments.length }} document{{ selectedDocuments.length > 1 ? 's' : '' }} prêt{{ selectedDocuments.length > 1 ? 's' : '' }}
                </span>
              </header>
              <div :class="{ 'pointer-events-none opacity-60': !canEdit || submitting }">
                <DocumentUpload
                  v-model="selectedDocuments"
                  title="Déposer vos fichiers"
                  subtitle="Formats acceptés : PDF, images, documents…"
                />
              </div>
              <p v-if="uploadingDocuments" class="text-xs text-base-content/70">
                Téléversement des documents en cours…
              </p>
            </div>
          </template>

          <template #tab-custom-fields>
            <div v-if="customFieldInputs.length" class="space-y-4 rounded-lg border border-base-200 bg-base-200/40 p-4">
              <header class="space-y-1">
                <h2 class="font-semibold text-base-content">Champs personnalisés</h2>
                <p class="text-xs text-base-content/70">
                  Renseignez les valeurs propres à cette pièce. Ces champs complètent le squelette sélectionné.
                </p>
              </header>
              <CustomFieldInputGrid :fields="customFieldInputs" :disabled="!canEdit || submitting" />
              <p v-if="hasRequiredCustomFields && !requiredCustomFieldsFilled" class="text-xs text-warning">
                Certains champs personnalisés sont obligatoires. Veuillez les renseigner avant de valider.
              </p>
            </div>
            <EmptyState
              v-else
              title="Aucun champ personnalisé"
              :description="selectedType ? 'Cette catégorie ne définit pas de champs personnalisés.' : 'Sélectionnez une catégorie pour voir les champs personnalisés.'"
            />
          </template>
        </EntityTabs>

        <!-- Save/Cancel buttons -->
        <div class="flex flex-col gap-3 md:flex-row md:justify-end">
          <NuxtLink to="/catalogues/pieces" class="btn btn-ghost" :class="{ 'btn-disabled': submitting }">
            Annuler
          </NuxtLink>
          <button type="button" class="btn btn-primary" :disabled="!canSubmit" @click="submitCreation">
            <span v-if="submitting" class="loading loading-spinner loading-sm mr-2"></span>
            Créer la pièce
          </button>
        </div>
        <p v-if="selectedType && hasRequiredCustomFields && !requiredCustomFieldsFilled" class="text-xs text-error text-right">
          Merci de renseigner tous les champs personnalisés obligatoires avant de créer la pièce.
        </p>
      </div>
    </section>
  </main>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute, useRouter } from '#imports'
import ConstructeurSelect from '~/components/ConstructeurSelect.vue'
import ConstructeurLinksTable from '~/components/ConstructeurLinksTable.vue'
import DocumentUpload from '~/components/DocumentUpload.vue'
import ProductSelect from '~/components/ProductSelect.vue'
import SearchSelect from '~/components/common/SearchSelect.vue'
import { usePieceTypes } from '~/composables/usePieceTypes'
import { usePieces } from '~/composables/usePieces'
import { useToast } from '~/composables/useToast'
import { humanizeError } from '~/shared/utils/errorMessages'
import { useDocuments } from '~/composables/useDocuments'
import { useConstructeurLinks } from '~/composables/useConstructeurLinks'
import { useConstructeurs } from '~/composables/useConstructeurs'
import { formatPieceStructurePreview } from '~/shared/modelUtils'
import { constructeurIdsFromLinks } from '~/shared/constructeurUtils'
import type { ConstructeurLinkEntry } from '~/shared/constructeurUtils'
import type { PieceModelStructure } from '~/shared/types/inventory'
import type { ModelType } from '~/services/modelTypes'
import {
  getStructureProducts,
  buildProductRequirementDescriptions,
  buildProductRequirementEntries,
  resizeProductSelections,
  applyProductSelection,
  collectNormalizedProductIds,
} from '~/shared/utils/pieceProductSelectionUtils'
import { useCustomFieldInputs, type CustomFieldEntityType } from '~/composables/useCustomFieldInputs'

interface PieceCatalogType extends ModelType {
  structure: PieceModelStructure | null
  customFields?: Array<Record<string, any>>
}

const route = useRoute()
const router = useRouter()

const { pieceTypes, loadPieceTypes, loadingPieceTypes: loadingTypes } = usePieceTypes()
const { createPiece } = usePieces()
const toast = useToast()
const { uploadDocuments } = useDocuments()
const { syncLinks } = useConstructeurLinks()
const { getConstructeurById } = useConstructeurs()
const { canEdit } = usePermissions()

const activeTab = ref('general')
const initialTypeId = ref<string>(typeof route.query.typeId === 'string' ? route.query.typeId : '')
const selectedTypeId = ref<string>(initialTypeId.value)
const submitting = ref(false)
const creationForm = reactive({
  name: '' as string,
  description: '' as string,
  reference: '' as string,
  constructeurIds: [] as string[],
  prix: '' as string,
})
const constructeurLinks = ref<ConstructeurLinkEntry[]>([])
const productSelections = ref<(string | null)[]>([])

const lastSuggestedName = ref('')
const cfDefinitions = ref<any[]>([])
const createdEntityId = ref<string | null>(null)
const { fields: customFieldInputs, requiredFilled: requiredCustomFieldsFilled, saveAll: saveAllCustomFields } = useCustomFieldInputs({
  definitions: cfDefinitions,
  values: [] as any[],
  entityType: 'piece' as CustomFieldEntityType,
  entityId: createdEntityId,
  context: 'standalone',
})
const hasRequiredCustomFields = computed(() => customFieldInputs.value.some(f => f.required))
const selectedDocuments = ref<File[]>([])
const uploadingDocuments = ref(false)

watch(
  () => route.query.typeId,
  (value) => {
    if (typeof value === 'string') {
      selectedTypeId.value = value
    }
  },
)

watch(selectedTypeId, (id) => {
  const current = typeof route.query.typeId === 'string' ? route.query.typeId : ''
  if ((id || '') === current) {
    return
  }
  const nextQuery = { ...route.query }
  if (id) {
    nextQuery.typeId = id
  } else {
    delete nextQuery.typeId
  }
  router.replace({ path: route.path, query: nextQuery }).catch(() => {})
})

const pieceTypeList = computed<PieceCatalogType[]>(() => (pieceTypes.value || []) as PieceCatalogType[])

const typeOptionLabel = (type?: PieceCatalogType) =>
  type?.name || 'Catégorie'

const typeOptionDescription = (type?: PieceCatalogType) =>
  type?.description ? String(type.description) : ''

const selectedType = computed(() => {
  if (!selectedTypeId.value) {
    return null
  }
  return pieceTypeList.value.find((type) => type.id === selectedTypeId.value) ?? null
})

const structureProducts = computed(() =>
  getStructureProducts(selectedType.value?.structure ?? null),
)

const requiresProductSelection = computed(() => structureProducts.value.length > 0)

const productRequirementDescriptions = computed(() =>
  buildProductRequirementDescriptions(structureProducts.value),
)

const ensureProductSelections = (count: number) => {
  productSelections.value = resizeProductSelections(productSelections.value, count)
}

const productRequirementEntries = computed(() =>
  buildProductRequirementEntries(structureProducts.value, 'piece-create-product-requirement'),
)

const productSelectionsFilled = computed(() => true)

const setProductSelection = (index: number, value: string | null) => {
  productSelections.value = applyProductSelection(productSelections.value, index, value)
}

watch(structureProducts, (products) => {
  ensureProductSelections(products.length)
})

watch(selectedType, (type) => {
  if (!type) {
    clearCreationForm()
    cfDefinitions.value = []
    return
  }
  if (!creationForm.name || creationForm.name === lastSuggestedName.value) {
    creationForm.name = type.name
  }
  lastSuggestedName.value = creationForm.name
  cfDefinitions.value = type.structure?.customFields ?? []
  productSelections.value = Array.from({ length: structureProducts.value.length }, () => null)
})

const canSubmit = computed(() =>
  Boolean(
    canEdit.value &&
    selectedType.value &&
    creationForm.name &&
    requiredCustomFieldsFilled.value &&
    productSelectionsFilled.value &&
    !submitting.value,
  ),
)

const entityTabs = computed(() => [
  { key: 'general', label: 'Général' },
  { key: 'products', label: 'Produits liés', count: structureProducts.value.length },
  { key: 'documents', label: 'Documents', count: selectedDocuments.value.length },
  { key: 'custom-fields', label: 'Champs perso', count: customFieldInputs.value.length },
])

const clearCreationForm = () => {
  creationForm.name = ''
  creationForm.description = ''
  creationForm.reference = ''
  creationForm.constructeurIds = []
  constructeurLinks.value = []
  creationForm.prix = ''
  productSelections.value = []
  lastSuggestedName.value = ''
}

const submitCreation = async () => {
  if (!selectedType.value) {
    toast.showError('Sélectionnez une catégorie de pièce.')
    return
  }

  const payload: Record<string, any> = {
    name: creationForm.name.trim(),
    typePieceId: selectedType.value.id,
  }

  const description = creationForm.description.trim()
  if (description) {
    payload.description = description
  }

  const reference = creationForm.reference.trim()
  if (reference) {
    payload.reference = reference
  }

  const normalizedProductIds = collectNormalizedProductIds(
    productRequirementEntries.value,
    productSelections.value,
  )
  if (normalizedProductIds.length) {
    payload.productIds = normalizedProductIds
    payload.productId = normalizedProductIds[0]
  }

  const rawPrice = typeof creationForm.prix === 'string'
    ? creationForm.prix.trim()
    : creationForm.prix === null || creationForm.prix === undefined
      ? ''
      : String(creationForm.prix).trim()

  if (rawPrice) {
    const parsed = Number(rawPrice)
    if (!Number.isNaN(parsed)) {
      payload.prix = String(parsed)
    }
  }

  submitting.value = true
  try {
    const result = await createPiece(payload)
    if (result.success && result.data) {
      const createdPiece = result.data as Record<string, any>
      createdEntityId.value = createdPiece.id
      const failedFields = await saveAllCustomFields()
      if (failedFields.length) {
        toast.showError(`Pièce créée, mais impossible d'enregistrer ${failedFields.length} champ(s): ${failedFields.join(', ')}`)
      }
      // Sync constructeur links after creation
      if (constructeurLinks.value.length) {
        await syncLinks('piece', createdPiece.id, [], constructeurLinks.value)
      }
      if (selectedDocuments.value.length && createdPiece.id) {
        uploadingDocuments.value = true
        const uploadResult = await uploadDocuments(
          {
            files: selectedDocuments.value,
            context: { pieceId: createdPiece.id },
          },
          { updateStore: false },
        )
        if (!uploadResult.success) {
          const message = uploadResult.error
            ? `Documents non ajoutés : ${uploadResult.error}`
            : 'Documents non ajoutés : une erreur est survenue.'
          toast.showError(message)
        }
        selectedDocuments.value = []
      }
      toast.showSuccess('Pièce créée avec succès')
      await router.replace(`/piece/${createdPiece.id}?edit=true`)
    } else if (result.error) {
      toast.showError(result.error)
    }
  } catch (error: any) {
    toast.showError(humanizeError(error?.message) || 'Impossible de créer la pièce')
  } finally {
    submitting.value = false
    uploadingDocuments.value = false
  }
}

// Sync constructeurIds → constructeurLinks when IDs are added via ConstructeurSelect
watch(
  () => creationForm.constructeurIds,
  (ids) => {
    const currentIds = new Set(constructeurLinks.value.map(l => l.constructeurId))
    for (const id of ids) {
      if (!currentIds.has(id)) {
        const resolved = getConstructeurById(id)
        constructeurLinks.value.push({
          constructeurId: id,
          constructeur: resolved ? { id: resolved.id, name: resolved.name } : null,
          supplierReference: null,
        })
      }
    }
    constructeurLinks.value = constructeurLinks.value.filter(l => ids.includes(l.constructeurId))
  },
  { deep: true },
)

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