{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}

module GigSpider.Places where

import GigSpider.URL
import qualified GigSpider.Search as S
import qualified GigSpider.Geocoding as G

import Control.Applicative
import Control.Monad.Trans.Either

import Data.Aeson
import GHC.Generics
import Network.HTTP.Conduit (simpleHttp)

data Point = Point  { lat :: Float
                    , long :: Float }
                    deriving (Generic)
instance FromJSON Point

instance Show Point where
  show point = show (lat point) ++ "," ++ show (long point)

convert :: G.Point -> Point
convert gp = Point (G.lat gp) (G.lng gp)


data Geometry = Geometry  { location :: Point }
                          deriving (Show, Generic)
instance FromJSON Geometry

data Place = Place { name         :: String
                   , reference    :: String }
                   deriving (Show, Generic)
instance FromJSON Place

data PlacesResponse = PlacesResponse { results :: [Place] }
                                     deriving (Show, Generic)
instance FromJSON PlacesResponse

placesApiBase :: String
placesApiBase = "https://maps.googleapis.com/maps/api/place/nearbysearch/json"

defaultRadius :: Int
defaultRadius = 10000

defaultTypes :: String
defaultTypes = "bar|cafe|night_club|restaurant"

placesApiUrl :: Point -> String -> String
placesApiUrl point key =
  urlWithParams placesApiBase [loc, radius, types, k]
  where loc = ("location", show point)
        radius = ("radius", show defaultRadius)
        types = ("types", defaultTypes)
        k = ("key", key)

toVenue :: Place -> S.Venue
toVenue place = S.Venue (name place) [] Nothing

toVenues :: PlacesResponse -> [S.Venue]
toVenues = map toVenue . results

findVenuesNearArea :: S.Area -> String -> EitherT String IO [S.Venue]
findVenuesNearArea area key = do
  point <- G.find area key
  let url = placesApiUrl (convert point) key
  found <- eitherDecode <$> simpleHttp url
  hoistEither $ toVenues <$> found

data GoogleBackend = GoogleBackend { apiKey :: String }

instance S.Backend GoogleBackend where
  search (GoogleBackend key) area = runEitherT $ findVenuesNearArea area key
