import clsx from 'clsx'
import {OriginLocation} from 'common/filters'
import {ProfileRow} from 'common/profiles/profile'
import {useEffect, useRef, useState} from 'react'
import {api} from 'web/lib/api'
import {countryCodeToFlag} from 'web/lib/util/location'

function isDigitString(value: string): boolean {
  return /^\d+$/.test(value)
}

export type City = {
  geodb_city_id: string
  city: string | null
  region_code: string
  country: string
  country_code: string
  latitude: number
  longitude: number
}

export function profileToCity(profile: ProfileRow): City {
  return {
    geodb_city_id: profile.geodb_city_id!,
    city: profile.city,
    region_code: profile.region_code!,
    country: profile.country!,
    country_code: '',
    latitude: profile.city_latitude!,
    longitude: profile.city_longitude!,
  }
}

export function originToCity(origin: OriginLocation): City {
  return {
    geodb_city_id: origin.id,
    city: origin.name,
    region_code: '',
    country: '',
    country_code: '',
    latitude: 0,
    longitude: 0,
  }
}

export function CityRow(props: {city: City; onSelect: (city: City) => void; className?: string}) {
  const {city, onSelect, className} = props
  return (
    <button
      key={city.geodb_city_id}
      onClick={() => onSelect(city)}
      className={clsx(
        'group flex cursor-pointer flex-row flex-wrap justify-between gap-x-4',
        className,
      )}
    >
      <div className="group-hover:text-ink-950 font-semibold transition-colors">
        {city.city}
        {city.region_code && !isDigitString(city.region_code) ? `, ${city.region_code}` : ''}
      </div>
      <div className="text-ink-400 group-hover:text-ink-700 transition-colors">
        {countryCodeToFlag(city.country_code) || city.country}
      </div>
    </button>
  )
}

export const useCitySearch = () => {
  const [query, setQuery] = useState('')
  const [loading, setLoading] = useState(false)
  const [cities, setCities] = useState<City[]>([])

  const searchCountRef = useRef(0)

  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true)
        searchCountRef.current++
        const thisSearchCount = searchCountRef.current
        const response = await api('search-location', {term: query, limit: 8})
        if (response.status !== 'success') {
          throw new Error(response.data)
        }
        if (thisSearchCount == searchCountRef.current) {
          setCities(
            response.data.data.map((city: any) => ({
              geodb_city_id: city.id.toString(),
              city: city.name,
              region_code: city.regionCode,
              country: city.country,
              country_code: city.countryCode,
              latitude: city.latitude,
              longitude: city.longitude,
            })),
          )
        }
      } catch (error) {
        console.error('Error fetching cities', error)
      } finally {
        setLoading(false)
      }
    }

    const debounce = setTimeout(() => {
      if (query.length < 2) {
        setCities([])
        return
      } else {
        fetchData()
      }
    }, 1000)

    return () => {
      clearTimeout(debounce)
    }
  }, [query])

  return {query, setQuery, loading, cities}
}
