<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="Nouveau produit"
          subtitle="Sélectionnez la catégorie cible puis renseignez toutes les informations de votre produit catalogue."
          :is-edit-mode="false"
          :can-edit="false"
          back-link="/catalogues/produits"
        />

        <EntityTabs v-model="activeTab" :tabs="entityTabs" aria-label="Sections du produit">
          <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 produit</span>
                  </label>
                  <SearchSelect
                    v-model="selectedTypeId"
                    :options="productTypeList"
                    :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-base-content/60 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 du produit</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>

              <!-- 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">Fournisseurs</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 fournisseur indicatif (€)</span>
                  </label>
                  <input
                    v-model="creationForm.supplierPrice"
                    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 -->
              <div v-if="selectedType" class="space-y-3 rounded-lg border border-base-200 bg-base-200/40 p-4">
                <div class="flex items-center justify-between gap-4">
                  <div>
                    <h2 class="font-semibold text-base-content">Squelette sélectionné</h2>
                    <p class="text-xs text-base-content/70">
                      {{ selectedType.description || 'Ce squelette définit les champs personnalisés applicables aux produits de cette catégorie.' }}
                    </p>
                  </div>
                  <span class="badge badge-outline">{{ formatProductStructurePreview(selectedType.structure) }}</span>
                </div>

                <p v-if="!customFieldInputs.length" class="text-xs text-base-content/70">
                  Cette catégorie ne définit pas encore de champs personnalisés.
                </p>
              </div>
            </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 pour ce produit (fiches techniques, notices, etc.).
                  </p>
                </div>
                <span v-if="selectedDocuments.length" class="badge badge-outline">
                  {{ selectedDocuments.length }} document{{ selectedDocuments.length > 1 ? 's' : '' }} sélectionné{{ selectedDocuments.length > 1 ? 's' : '' }}
                </span>
              </header>
              <div :class="{ 'pointer-events-none opacity-60': !canEdit || submitting || uploadingDocuments }">
                <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 à ce produit catalogue.
                </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/produits" 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 le produit
          </button>
        </div>
        <p v-if="selectedType && hasRequiredCustomFields && !requiredCustomFieldsFilled" class="text-xs text-error text-right">
          Merci de renseigner tous les champs personnalisés obligatoires.
        </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 SearchSelect from '~/components/common/SearchSelect.vue'
import DocumentUpload from '~/components/DocumentUpload.vue'
import { useProductTypes } from '~/composables/useProductTypes'
import { useProducts } from '~/composables/useProducts'
import { useToast } from '~/composables/useToast'
import { useDocuments } from '~/composables/useDocuments'
import { formatProductStructurePreview, normalizeProductStructureForSave } from '~/shared/modelUtils'
import { constructeurIdsFromLinks } from '~/shared/constructeurUtils'
import type { ConstructeurLinkEntry } from '~/shared/constructeurUtils'
import { useConstructeurLinks } from '~/composables/useConstructeurLinks'
import { useConstructeurs } from '~/composables/useConstructeurs'
import type { ProductModelStructure } from '~/shared/types/inventory'
import type { ModelType } from '~/services/modelTypes'
import { useCustomFieldInputs, type CustomFieldEntityType } from '~/composables/useCustomFieldInputs'

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

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

const { productTypes, loadProductTypes, loadingProductTypes: loadingTypes } = useProductTypes()
const { createProduct } = useProducts()
const toast = useToast()
const { uploadDocuments } = useDocuments()
const { canEdit } = usePermissions()
const { syncLinks } = useConstructeurLinks()
const { getConstructeurById } = useConstructeurs()

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,
  reference: '' as string,
  constructeurIds: [] as string[],
  supplierPrice: '' as string,
})
const constructeurLinks = ref<ConstructeurLinkEntry[]>([])
const selectedDocuments = ref<File[]>([])
const uploadingDocuments = ref(false)

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

const productTypeList = computed<ProductCatalogType[]>(() =>
  (productTypes.value || []) as ProductCatalogType[],
)

const typeOptionLabel = (type?: ProductCatalogType) => type?.name || 'Catégorie'
const typeOptionDescription = (type?: ProductCatalogType) =>
  type?.description ? String(type.description) : ''

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

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

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(() => {})
})

watch(selectedType, (type) => {
  if (!type) {
    clearForm()
    cfDefinitions.value = []
    return
  }
  if (!creationForm.name) {
    creationForm.name = type.name
  }
  const normalized = normalizeProductStructureForSave(type.structure)
  cfDefinitions.value = normalized?.customFields ?? []
})

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

const clearForm = () => {
  creationForm.name = ''
  creationForm.reference = ''
  creationForm.constructeurIds = []
  creationForm.supplierPrice = ''
}

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

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

  const rawPrice = typeof creationForm.supplierPrice === 'string'
    ? creationForm.supplierPrice.trim()
    : creationForm.supplierPrice
  if (rawPrice !== '' && rawPrice !== null && rawPrice !== undefined) {
    const parsed = Number(rawPrice)
    if (!Number.isNaN(parsed)) {
      payload.supplierPrice = String(parsed)
    }
  }

  return payload
}

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

  submitting.value = true
  try {
    const payload = buildPayload()
    const result = await createProduct(payload)
    if (result.success && result.data?.id) {
      const productId = result.data.id
      createdEntityId.value = productId
      const failedFields = await saveAllCustomFields()
      if (failedFields.length) {
        toast.showError(`Produit créé, mais impossible d'enregistrer ${failedFields.length} champ(s): ${failedFields.join(', ')}`)
        await router.replace(`/product/${result.data.id}?edit=true`)
        return
      }
      // Sync constructeur links after creation
      if (constructeurLinks.value.length) {
        await syncLinks('product', productId, [], constructeurLinks.value)
      }
      if (selectedDocuments.value.length) {
        uploadingDocuments.value = true
        const uploadResult = await uploadDocuments(
          {
            files: selectedDocuments.value,
            context: { productId },
          },
          { 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)
        } else {
          selectedDocuments.value = []
        }
      }
      toast.showSuccess('Produit créé avec succès')
      await router.replace(`/product/${productId}?edit=true`)
    }
  } catch (error: any) {
    toast.showError(error?.message || 'Erreur lors de la création du produit')
  } 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))
  },
)

onMounted(async () => {
  await loadProductTypes()
  if (selectedTypeId.value && !selectedType.value) {
    await router.replace({
      path: route.path,
      query: { ...route.query, typeId: undefined },
    }).catch(() => {})
  }
})
</script>
