import { useFuse } from '@vueuse/integrations/useFuse'
import { useToString } from '@vueuse/core'

export default defineEventHandler(async (event) => {
  const query = getQuery(event)

  const keywords = useToString(query.search).value.split(' ')
  const nameSearch = keywords.map((word) => {
    return { Name: { startsWith: word, mode: 'insensitive' } }
  })

  try {
    const villages = await prisma.addressVillages.findMany({
      where: {
        OR: nameSearch,
      },
      select: {
        Name: true,
        Postal: true,
        District: {
          select: {
            Name: true,
            City: {
              select: {
                Name: true,
                State: {
                  select: {
                    Name: true,
                    Country: {
                      select: {
                        Name: true,
                      },
                    },
                  },
                },
              },
            },
          },
        },
      },
      take: 100,
    })
    const districts = await prisma.addressDistricts.findMany({
      where: {
        OR: nameSearch,
      },
      select: {
        Name: true,
        Postal: true,
        City: {
          select: {
            Name: true,
            State: {
              select: {
                Name: true,
                Country: {
                  select: {
                    Name: true,
                  },
                },
              },
            },
          },
        },
      },
      take: 50,
    })
    const cities = await prisma.addressCities.findMany({
      where: {
        OR: nameSearch,
      },
      select: {
        Name: true,
        Postal: true,
        State: {
          select: {
            Name: true,
            Country: {
              select: {
                Name: true,
              },
            },
          },
        },
      },
      take: 30,
    })
    const states = await prisma.addressStates.findMany({
      where: {
        OR: nameSearch,
      },
      select: {
        Name: true,
        Postal: true,
        Country: {
          select: {
            Name: true,
          },
        },
      },
      take: 20,
    })
    const countries = await prisma.addressCountries.findMany({
      where: {
        OR: nameSearch,
      },
      select: {
        Name: true,
        Postal: true,
      },
      take: 10,
    })

    const addresses = [
      ...villages.map((item) => {
        return {
          villages: item.Name,
          districts: item.District?.Name,
          cities: item.District?.City?.Name,
          states: item.District?.City?.State?.Name,
          countries: item.District?.City?.State?.Country?.Name,
          postal: item.Postal,
        }
      }),
      ...districts.map((item) => {
        return {
          districts: item.Name,
          cities: item.City?.Name,
          states: item.City?.State?.Name,
          countries: item.City?.State?.Country?.Name,
          postal: item.Postal,
        }
      }),
      ...cities.map((item) => {
        return {
          cities: item.Name,
          states: item.State?.Name,
          countries: item.State?.Country?.Name,
          postal: item.Postal,
        }
      }),
      ...states.map((item) => {
        return {
          states: item.Name,
          countries: item.Country?.Name,
          postal: item.Postal,
        }
      }),
      ...countries.map((item) => {
        return {
          countries: item.Name,
          postal: item.Postal,
        }
      }),
    ]

    const options = {
      fuseOptions: {
        keys: ['villages', 'districts', 'cities', 'states', 'countries'],
        shouldSort: true,
        // includeScore: true,
        minMatchCharLength: 3,
        threshold: 0.8,
      },
    }

    const { results } = useFuse(useToString(query.search), addresses, options)

    return results.value
      .map((value) => {
        return value.item
      })
      .slice(0, 9)
  } catch (error) {
    // Return error if fetching users fails
    return {
      status: 500,
      body: { message: 'Failed to fetch addresses' },
    }
  }
})
