import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useGraphQL } from '~/composables/useGraphQL'
import { GetNodesDocument } from '~/composables/graphql/public/geo-generated'

interface SelectedLocation {
  type: 'address' | 'hub'
  uuid: string
  name: string
  latitude: number
  longitude: number
}

export const useLocationStore = defineStore('location', () => {
  const { mutate } = useGraphQL()

  const selectedLocation = ref<SelectedLocation | null>(null)
  const isLoading = ref(false)

  const hasLocation = computed(() => !!selectedLocation.value)
  const locationName = computed(() => selectedLocation.value?.name || '')
  const locationType = computed(() => selectedLocation.value?.type || null)

  async function fetch() {
    isLoading.value = true
    try {
      const { GetTeamDocument } = await import('~/composables/graphql/team/teams-generated')
      const { data: teamData, error: teamError } = await useServerQuery('location-team', GetTeamDocument, {}, 'team', 'teams')
      if (teamError.value) throw teamError.value
      const team = teamData.value?.team

      if (team?.selectedLocation?.type && team?.selectedLocation?.uuid) {
        const { type, uuid } = team.selectedLocation

        if (type === 'hub') {
          const { data: nodesData, error: nodesError } = await useServerQuery('location-nodes', GetNodesDocument, {}, 'public', 'geo')
          if (nodesError.value) throw nodesError.value
          const hub = nodesData.value?.nodes?.find((n: { uuid: string }) => n.uuid === uuid)
          if (hub) {
            selectedLocation.value = {
              type: 'hub',
              uuid: hub.uuid,
              name: hub.name,
              latitude: hub.latitude,
              longitude: hub.longitude
            }
          }
        } else if (type === 'address') {
          const { GetTeamAddressesDocument } = await import('~/composables/graphql/team/teams-generated')
          const { data: addressesData, error: addressesError } = await useServerQuery('location-addresses', GetTeamAddressesDocument, {}, 'team', 'teams')
          if (addressesError.value) throw addressesError.value
          const address = addressesData.value?.teamAddresses?.find((a: { uuid: string }) => a.uuid === uuid)
          if (address) {
            selectedLocation.value = {
              type: 'address',
              uuid: address.uuid,
              name: address.name,
              latitude: address.latitude,
              longitude: address.longitude
            }
          }
        }
      }
    } finally {
      isLoading.value = false
    }
  }

  async function select(type: 'address' | 'hub', uuid: string, name: string, latitude: number, longitude: number) {
    isLoading.value = true
    try {
      const { SetSelectedLocationDocument } = await import('~/composables/graphql/team/teams-generated')
      const result = await mutate(SetSelectedLocationDocument, { input: { type, uuid, name, latitude, longitude } }, 'team', 'teams')

      if (result?.setSelectedLocation?.success) {
        selectedLocation.value = { type, uuid, name, latitude, longitude }
        return true
      }
      return false
    } finally {
      isLoading.value = false
    }
  }

  function setFromUserData(loc: { type: string; uuid: string; name: string; latitude: number; longitude: number } | null | undefined) {
    if (loc?.type && loc?.uuid && loc?.name) {
      selectedLocation.value = {
        type: loc.type as 'address' | 'hub',
        uuid: loc.uuid,
        name: loc.name,
        latitude: loc.latitude,
        longitude: loc.longitude
      }
    }
  }

  function clear() {
    selectedLocation.value = null
  }

  return {
    selectedLocation,
    isLoading,
    hasLocation,
    locationName,
    locationType,
    fetch,
    select,
    setFromUserData,
    clear
  }
})
