<template>
  <main class="mx-auto flex w-full max-w-4xl flex-col gap-8 px-4 py-8 sm:px-6 lg:px-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-semibold text-base-content">Nouveau produit</h1>
        <p class="text-sm text-base-content/70">
          Sélectionnez la catégorie cible puis renseignez toutes les informations de votre produit catalogue.
        </p>
      </div>
      <button type="button" class="btn btn-ghost btn-sm md:btn-md self-start" @click="$router.back()">
        Retour au catalogue
      </button>
    </header>

    <section class="card border border-base-200 bg-base-100 shadow-sm">
      <div class="card-body space-y-6">
        <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>

        <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>

        <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>

        <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>

        <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 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" />
        </div>

        <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>

        <div class="flex flex-col gap-3 md:flex-row md:justify-end">
          <NuxtLink to="/product-catalog" 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 && !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 { useCustomFields } from '~/composables/useCustomFields'
import { useDocuments } from '~/composables/useDocuments'
import { formatProductStructurePreview, normalizeProductStructureForSave } from '~/shared/modelUtils'
import { uniqueConstructeurIds } from '~/shared/constructeurUtils'
import type { ProductModelStructure } from '~/shared/types/inventory'
import type { ModelType } from '~/services/modelTypes'
import {
  type CustomFieldInput,
  normalizeCustomFieldInputs as normalizeCustomFieldInputsFromUtils,
} from '~/shared/utils/customFieldFormUtils'

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 { upsertCustomFieldValue } = useCustomFields()
const { uploadDocuments } = useDocuments()
const { canEdit } = usePermissions()

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 selectedDocuments = ref<File[]>([])
const uploadingDocuments = ref(false)

const customFieldInputs = ref<CustomFieldInput[]>([])

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
})

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()
    customFieldInputs.value = []
    return
  }
  if (!creationForm.name) {
    creationForm.name = type.name
  }
  customFieldInputs.value = normalizeCustomFieldInputsFromUtils(normalizeProductStructureForSave(type.structure))
})

const requiredCustomFieldsFilled = computed(() =>
  customFieldInputs.value.every((field) => {
    if (!field.required) {
      return true
    }
    if (field.type === 'boolean') {
      return field.value === 'true' || field.value === 'false'
    }
    return field.value.trim().length > 0
  }),
)

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
  }

  payload.constructeurIds = uniqueConstructeurIds(creationForm.constructeurIds)

  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
      const failedFields = await saveCustomFieldValues(result.data.id)
      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
      }
      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
  }
}

const saveCustomFieldValues = async (productId: string) => {
  const failed: string[] = []
  for (const field of customFieldInputs.value) {
    if (!field.name) {
      continue
    }
    const value = field.value ?? ''
    const metadata = field.customFieldId
      ? undefined
      : { customFieldName: field.name, customFieldType: field.type, customFieldRequired: field.required }
    const result = await upsertCustomFieldValue(
      field.customFieldId,
      'product',
      productId,
      String(value ?? ''),
      metadata,
    )
    if (!result.success) {
      failed.push(field.name)
    } else {
      const createdValue = result.data
      if (createdValue?.id) {
        field.customFieldValueId = createdValue.id
      }
      const resolvedId = createdValue?.customField?.id || field.customFieldId
      if (resolvedId) {
        field.customFieldId = resolvedId
      }
    }
  }
  return failed
}

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