<!-- Component d'un formulaire d'une adresse postale d'organization -->
<template>
  <main>
    <LayoutContainer>
      <v-card class="mb-5">
        <FormToolbar title="address_postal" icon="fa-globe-europe"/>

        <UiForm
          :id="id"
          :model="model"
          :query="query()"
          :submitActions="submitActions">
          <template #form.input="{entry, updateRepository}">
            <v-container fluid class="container">
              <v-row>
                <v-col cols="12" sm="12">
                  <UiInputAutocompleteWithAPI
                    field="owner"
                    label="importAddress"
                    :item-text="['person.givenName', 'person.name']"
                    :searchFunction="accessSearch"
                    @update="updateAccessAddress"
                  />
                </v-col>

                <v-col cols="12" sm="6">
                  <UiInputEnum field="type" label="addresstype" :data="entry['type']" enum-type="address_postal_organization" @update="updateRepository" />
                </v-col>

                <v-col cols="12" sm="6">
                  <UiInputText field="addressPostal.addressOwner" label="addressOwner" :data="entry['addressPostal.addressOwner']" @update="updateRepository" />
                </v-col>

                <v-col cols="12" sm="6">
                  <UiInputText field="addressPostal.streetAddress" label="streetAddress" :data="entry['addressPostal.streetAddress']" @update="updateRepository" />
                </v-col>

                <v-col cols="12" sm="6">
                  <UiInputText field="addressPostal.streetAddressSecond" label="streetAddressSecond" :data="entry['addressPostal.streetAddressSecond']" @update="updateRepository" />
                </v-col>

                <v-col cols="12" sm="6">
                  <UiInputText field="addressPostal.streetAddressThird" label="streetAddressThird" :data="entry['addressPostal.streetAddressThird']" @update="updateRepository" />
                </v-col>

                <v-col cols="12" sm="6">
                  <UiInputAutocompleteWithAPI
                    field="addressPostal.postalCode"
                    label="postalCode"
                    :data="getAutoCompleteAddressItem"
                    :item-text="['postcode']"
                    :slotText="['postcode', 'city']"
                    :searchFunction="addressSearch"
                    :returnObject="true"
                    @update="updateCpAddress($event, updateRepository)"
                  />
                </v-col>

                <v-col cols="12" sm="6">
                  <UiInputAutocompleteWithAPI
                    field="addressPostal.addressCity"
                    label="addressCity"
                    :data="getAutoCompleteAddressItem"
                    :item-text="['city']"
                    :slotText="['postcode', 'city']"
                    :searchFunction="addressSearch"
                    :returnObject="true"
                    @update="updateCpAddress($event, updateRepository)"
                  />
                </v-col>

                <v-col cols="12" sm="6">
                  <UiInputAutocomplete
                    field="addressPostal.addressCountry"
                    label="addressCountry"
                    :data="getIdFromUri(entry['addressPostal.addressCountry'])"
                    :items="countries"
                    :isLoading="countriesFetchingState.pending"
                    :item-text="['name']"
                    @update="updateRepository(`/api/countries/${$event}`, 'addressPostal.addressCountry')"
                  />
                </v-col>

              </v-row>
            </v-container>

            <UiMap :zoom="12" :address="addressPostalItem()" @updateAddress="updateAddressFromMap" />

          </template>

          <template #form.button>
            <NuxtLink :to="{ path: '/organization', query: { accordion: 'address_postal' }}" class="no-decoration">
              <v-btn class="mr-4 ot_light_grey ot_grey--text">
                {{ $t('back') }}
              </v-btn>
            </NuxtLink>
          </template>

        </UiForm>
      </v-card>
    </LayoutContainer>
  </main>
</template>

<script lang="ts">
import { defineComponent, useContext, computed, ComputedRef} from '@nuxtjs/composition-api'
import { Repository as VuexRepository } from '@vuex-orm/core/dist/src/repository/Repository'
import { Query, Model } from '@vuex-orm/core'
import { OrganizationAddressPostal } from '~/models/Organization/OrganizationAddressPostal'
import {Country} from "~/models/Core/Country";
import {QUERY_TYPE, SUBMIT_TYPE} from '~/types/enums'
import { repositoryHelper } from '~/services/store/repository'
import { queryHelper } from '~/services/store/query'
import { AddressPostal } from '~/models/Core/AddressPostal'
import ModelsUtils from "~/services/utils/modelsUtils";
import {AnyJson} from "~/types/interfaces";
import DataProvider from "~/services/data/dataProvider";
import {useAccessesProvider} from "~/composables/data/useAccessesProvider";
import {useAddressPostalUtils} from "~/composables/data/useAddressPostalUtils";
import {useCountryProvider} from "~/composables/data/useCountryProvider";

export default defineComponent({
  props: {
    id:{
      type: [Number, String],
      required: true
    }
  },
  setup (props) {
    const { $dataProvider } = useContext()
    const {getPhysicalByFullName: accessSearch} = useAccessesProvider($dataProvider)
    const {searchFunction: addressSearch, updateCpAddress} = useAddressPostalUtils($dataProvider)
    const {countries, fetchState: countriesFetchingState} = useCountryProvider($dataProvider)

    const repository: VuexRepository<Model> = repositoryHelper.getRepository(OrganizationAddressPostal)
    const query: Query = repository.with('addressPostal')

    const organizationAddressPostalItem: ComputedRef<OrganizationAddressPostal> = computed(() => {
      return queryHelper.getItem(query, props.id) as OrganizationAddressPostal
    })

    const addressPostalItem: ComputedRef<AddressPostal|null> = computed(() => {
      return organizationAddressPostalItem.value?.addressPostal || null
    })

    const updateAddressFromMap = (addressPostal: AddressPostal) => {
      repositoryHelper.persist(AddressPostal, addressPostal)
    }

    const getAutoCompleteAddressItem = computed(() => {
      if(addressPostalItem.value?.addressCity || addressPostalItem.value?.postalCode)
        return {id:0, city: addressPostalItem.value?.addressCity, postcode: addressPostalItem.value?.postalCode}
      return {}
    })
    const {updateAccessAddress} = accessOwnerResearch($dataProvider, organizationAddressPostalItem, addressPostalItem)

    const getIdFromUri = (uri: string) => {
      return ModelsUtils.extractIdFromUri(uri)
    }

    const submitActions = computed(() => {
      let actions:AnyJson = {}
      actions[SUBMIT_TYPE.SAVE_AND_BACK] = { path: `/organization`, query: { accordion: 'address_postal' } }
      actions[SUBMIT_TYPE.SAVE] = { path: `/organization/address/` }
      return actions
    })

    /** todo Computed properties needs to be returned as functions until nuxt3 : https://github.com/nuxt-community/composition-api/issues/207 **/
    return {
      model: OrganizationAddressPostal,
      query: () => query,
      panel: 0,
      addressPostalItem: () => addressPostalItem,
      countries,
      countriesFetchingState,
      addressSearch,
      getIdFromUri,
      getAutoCompleteAddressItem,
      accessSearch,
      updateAccessAddress,
      updateAddressFromMap,
      updateCpAddress,
      submitActions
    }
  },
  beforeDestroy() {
    repositoryHelper.cleanRepository(OrganizationAddressPostal)
    repositoryHelper.cleanRepository(Country)
    repositoryHelper.cleanRepository(AddressPostal)
  }
})

/**
 * Fonction permettant la mise à jour des champs de l'adresse suivant une adresse d'un Access
 * @param $dataProvider
 * @param organizationAddressPostalItem
 * @param addressItem
 */
function accessOwnerResearch($dataProvider:DataProvider, organizationAddressPostalItem:ComputedRef<OrganizationAddressPostal>, addressItem:ComputedRef<AddressPostal|null>){
  const updateAccessAddress = async (accessId: number) =>{
    const response = await $dataProvider.invoke({
      type: QUERY_TYPE.DEFAULT,
      url: `api/access_addresses`,
      id:accessId
    })

    //On ne conserve que l'adresse principale
    const principalPersonalAddress = response.data.person.personAddressPostal.filter((personAddress: AnyJson) => {
      return personAddress.type === 'ADDRESS_PRINCIPAL'
    })

    if(principalPersonalAddress.length > 0){
      const personalAddress = principalPersonalAddress.pop()

      //On créer la nouvelle adresse et on initialise les champs restants...
      const addressPostal:AddressPostal = new AddressPostal(personalAddress.addressPostal)
      addressPostal.addressOwner = `${response.data.person.name} ${response.data.person.givenName}`
      addressPostal['@id'] = ''

      if(addressItem.value)
        addressPostal.id = addressItem.value.id

      //On l'associe à l'OrganizationAddressPostal qui est éditée, et on persist
      organizationAddressPostalItem.value.addressPostal = addressPostal
      repositoryHelper.persist(OrganizationAddressPostal, organizationAddressPostalItem.value)
    }
  }

  return {
    updateAccessAddress
  }
}

</script>
