<template>
  <main class="container">
    <h1>{{ t('pages.objetDetail') }}</h1>
    <p v-if="errorMessage">{{ errorMessage }}</p>
    <p v-else-if="pending">{{ t('states.loading') }}</p>
    <section v-else class="card">
      <h2>{{ item?.nom }}</h2>
      <p v-if="item?.description">{{ item?.description }}</p>
      <p>{{ t('form.quantite') }}: {{ item?.quantite ?? 0 }}</p>
      <p>{{ t('form.statut') }}: {{ item?.statut }}</p>
    </section>

    <section v-if="!pending" class="card" style="margin-top: 16px;">
      <h3>{{ t('sections.piecesJointes') }}</h3>
      <div style="margin: 8px 0 12px;">
        <FileUploader
          :disabled="isUploading"
          :label="t('fileUploader.label')"
          @upload="uploadFiles"
        />
      </div>
      <p v-if="uploadMessage">{{ uploadMessage }}</p>
      <p v-if="piecesPending">{{ t('states.loading') }}</p>
      <p v-else-if="piecesError">{{ piecesErrorMessage }}</p>
      <ul v-else>
        <li v-for="pj in piecesJointes" :key="pj.id">
          {{ pj.nom_fichier }} ({{ pj.categorie }})
          <span v-if="pj.est_principale" style="margin-left: 8px;">[Principale]</span>
          <button
            class="card"
            type="button"
            style="margin-left: 8px;"
            @click="setPrincipale(pj.id)"
          >
            {{ t('actions.setPrimary') }}
          </button>
          <button
            class="card"
            type="button"
            style="margin-left: 8px;"
            @click="confirmDeletePieceJointe(pj.id)"
          >
            {{ t('actions.delete') }}
          </button>
        </li>
      </ul>
    </section>

    <section v-if="!pending" class="card" style="margin-top: 16px;">
      <h3>{{ t('sections.champs') }}</h3>
      <p v-if="champMessage">{{ champMessage }}</p>
      <div style="margin: 8px 0 12px; display: grid; gap: 8px;">
        <input v-model="newChamp.nom_champ" :placeholder="t('placeholders.name')" />
        <input v-model="newChamp.valeur" :placeholder="t('placeholders.value')" />
        <input v-model="newChamp.unite" :placeholder="t('placeholders.unit')" />
        <select v-model="newChamp.type_champ">
          <option value="string">string</option>
          <option value="int">int</option>
          <option value="bool">bool</option>
          <option value="date">date</option>
        </select>
        <button class="card" type="button" @click="createChamp">{{ t('actions.add') }}</button>
      </div>
      <p v-if="champsPending">{{ t('states.loading') }}</p>
      <p v-else-if="champsError">{{ champsErrorMessage }}</p>
      <ul v-else>
        <li v-for="champ in champsEditable" :key="champ.id">
          <div style="display: grid; gap: 6px; margin-bottom: 10px;">
            <input v-model="champ.nom_champ" />
            <input v-model="champ.valeur" />
            <input v-model="champ.unite" />
            <select v-model="champ.type_champ">
              <option value="string">string</option>
              <option value="int">int</option>
              <option value="bool">bool</option>
              <option value="date">date</option>
            </select>
            <div style="display: flex; gap: 8px;">
              <button class="card" type="button" @click="updateChamp(champ)">{{ t('actions.save') }}</button>
              <button class="card" type="button" @click="confirmDeleteChamp(champ.id)">{{ t('actions.delete') }}</button>
            </div>
          </div>
        </li>
      </ul>
    </section>

    <section v-if="!pending" class="card" style="margin-top: 16px;">
      <h3>{{ t('sections.liensEmplacements') }}</h3>
      <p v-if="lienMessage">{{ lienMessage }}</p>
      <div style="margin: 8px 0 12px; display: grid; gap: 8px;">
        <EmplacementPicker v-model="newLien.emplacement_id" :items="emplacements" />
        <select v-model="newLien.type">
          <option value="stocke">stocke</option>
          <option value="utilise_dans">utilise_dans</option>
        </select>
        <button class="card" type="button" @click="createLien">{{ t('actions.add') }}</button>
      </div>
      <p v-if="liensPending">{{ t('states.loading') }}</p>
      <p v-else-if="liensError">{{ liensErrorMessage }}</p>
      <ul v-else>
        <li v-for="lien in liens" :key="lien.id">
          {{ emplacementLabel(lien.emplacement_id) }} ({{ lien.type }})
        </li>
      </ul>
    </section>

    <ConfirmDialog
      :open="confirmOpen"
      :title="confirmTitle"
      :message="confirmMessage"
      @confirm="runConfirm"
      @cancel="closeConfirm"
    />
  </main>
</template>

<script setup lang="ts">
type Objet = {
  id: string
  nom: string
  description?: string | null
  quantite: number
  statut: string
}

type PieceJointe = {
  id: string
  nom_fichier: string
  categorie: string
  est_principale?: boolean
}

type ChampPersonnalise = {
  id: string
  nom_champ: string
  valeur?: string | null
  unite?: string | null
  type_champ: string
}

type LienEmplacement = {
  id: string
  emplacement_id: string
  type: string
}

type Emplacement = {
  id: string
  nom: string
  parent_id?: string | null
}

const { apiBase, getErrorMessage } = useApi()
const { t } = useI18n()
const route = useRoute()
const objetId = route.params.id

const { data, pending, error } = await useFetch<Objet>(
  `${apiBase}/objets/${objetId}`
)

const { data: piecesData, pending: piecesPending, error: piecesError, refresh: refreshPieces } =
  await useFetch<{ items: PieceJointe[] }>(
    `${apiBase}/objets/${objetId}/pieces_jointes?limit=50`
  )

const { data: champsData, pending: champsPending, error: champsError, refresh: refreshChamps } =
  await useFetch<{ items: ChampPersonnalise[] }>(
    `${apiBase}/objets/${objetId}/champs_personnalises?limit=50`
  )

const { data: liensData, pending: liensPending, error: liensError, refresh: refreshLiens } =
  await useFetch<{ items: LienEmplacement[] }>(
    `${apiBase}/objets/${objetId}/liens_emplacements?limit=50`
  )

const { data: emplacementsData } = await useFetch<{ items: Emplacement[] }>(
  `${apiBase}/emplacements?limit=200`
)

const item = computed(() => data.value ?? null)
const errorMessage = computed(() =>
  error.value ? getErrorMessage(error.value, t('messages.loadError')) : ""
)
const piecesErrorMessage = computed(() =>
  piecesError.value ? getErrorMessage(piecesError.value, t('messages.loadError')) : ""
)
const champsErrorMessage = computed(() =>
  champsError.value ? getErrorMessage(champsError.value, t('messages.loadError')) : ""
)
const liensErrorMessage = computed(() =>
  liensError.value ? getErrorMessage(liensError.value, t('messages.loadError')) : ""
)
const piecesJointes = computed(() => piecesData.value?.items ?? [])
const champsPersonnalises = computed(() => champsData.value?.items ?? [])
const liens = computed(() => liensData.value?.items ?? [])
const emplacements = computed(() => emplacementsData.value?.items ?? [])

const isUploading = ref(false)
const uploadMessage = ref('')
const champMessage = ref('')
const lienMessage = ref('')
const newChamp = ref({
  nom_champ: "",
  valeur: "",
  unite: "",
  type_champ: "string"
})
const champsEditable = ref<ChampPersonnalise[]>([])
const newLien = ref({
  emplacement_id: "",
  type: "stocke"
})

watch(champsPersonnalises, (items) => {
  champsEditable.value = items.map((champ) => ({ ...champ }))
})

const uploadFiles = async (files: FileList) => {
  uploadMessage.value = ''
  if (!files || files.length === 0) {
    uploadMessage.value = t('messages.noFiles')
    return
  }
  isUploading.value = true
  const formData = new FormData()
  Array.from(files).forEach((file) => {
    formData.append("fichiers", file)
  })
  try {
    await $fetch(`${apiBase}/objets/${objetId}/pieces_jointes`, {
      method: "POST",
      body: formData
    })
    uploadMessage.value = t('messages.uploadDone')
    await refreshPieces()
  } catch (err) {
    uploadMessage.value = getErrorMessage(err, t('messages.uploadError'))
  } finally {
    isUploading.value = false
  }
}

const createChamp = async () => {
  champMessage.value = ''
  if (!newChamp.value.nom_champ) {
    champMessage.value = t('messages.requiredName')
    return
  }
  try {
    await $fetch(`${apiBase}/objets/${objetId}/champs_personnalises`, {
      method: "POST",
      body: newChamp.value
    })
    newChamp.value = { nom_champ: "", valeur: "", unite: "", type_champ: "string" }
    champMessage.value = t('messages.created')
    await refreshChamps()
  } catch (err) {
    champMessage.value = getErrorMessage(err, t('messages.saveError'))
  }
}

const updateChamp = async (champ: ChampPersonnalise) => {
  champMessage.value = ''
  try {
    await $fetch(`${apiBase}/champs_personnalises/${champ.id}`, {
      method: "PUT",
      body: champ
    })
    champMessage.value = t('messages.updated')
    await refreshChamps()
  } catch (err) {
    champMessage.value = getErrorMessage(err, t('messages.saveError'))
  }
}

const deleteChamp = async (id: string) => {
  champMessage.value = ''
  try {
    await $fetch(`${apiBase}/champs_personnalises/${id}`, {
      method: "DELETE"
    })
    champMessage.value = t('messages.deleted')
    await refreshChamps()
  } catch (err) {
    champMessage.value = getErrorMessage(err, t('messages.deleteError'))
  }
}

const createLien = async () => {
  lienMessage.value = ''
  if (!newLien.value.emplacement_id) {
    lienMessage.value = t('messages.requiredName')
    return
  }
  try {
    await $fetch(`${apiBase}/objets/${objetId}/liens_emplacements`, {
      method: "POST",
      body: newLien.value
    })
    newLien.value = { emplacement_id: "", type: "stocke" }
    lienMessage.value = t('messages.created')
    await refreshLiens()
  } catch (err) {
    lienMessage.value = getErrorMessage(err, t('messages.saveError'))
  }
}

const deletePieceJointe = async (id: string) => {
  uploadMessage.value = ''
  try {
    await $fetch(`${apiBase}/pieces_jointes/${id}`, {
      method: 'DELETE'
    })
    uploadMessage.value = t('messages.deleted')
    await refreshPieces()
  } catch (err) {
    uploadMessage.value = getErrorMessage(err, t('messages.deleteError'))
  }
}

const setPrincipale = async (id: string) => {
  uploadMessage.value = ''
  try {
    await $fetch(`${apiBase}/pieces_jointes/${id}/principale`, {
      method: 'PUT'
    })
    uploadMessage.value = t('messages.updated')
    await refreshPieces()
  } catch (err) {
    uploadMessage.value = getErrorMessage(err, t('messages.saveError'))
  }
}

const confirmOpen = ref(false)
const confirmTitle = ref('Confirmation')
const confirmMessage = ref('Confirmer la suppression ?')
const confirmAction = ref<null | (() => Promise<void>)>(null)

const confirmDeletePieceJointe = (id: string) => {
  confirmTitle.value = t('confirm.deletePieceTitle')
  confirmMessage.value = t('confirm.deletePieceMessage')
  confirmAction.value = () => deletePieceJointe(id)
  confirmOpen.value = true
}

const confirmDeleteChamp = (id: string) => {
  confirmTitle.value = t('confirm.deleteChampTitle')
  confirmMessage.value = t('confirm.deleteChampMessage')
  confirmAction.value = () => deleteChamp(id)
  confirmOpen.value = true
}

const closeConfirm = () => {
  confirmOpen.value = false
  confirmAction.value = null
}

const runConfirm = async () => {
  if (confirmAction.value) {
    await confirmAction.value()
  }
  closeConfirm()
}

const emplacementLabel = (id: string) => {
  const item = emplacements.value.find((e) => e.id === id)
  if (!item) return id
  return item.nom
}
</script>
