{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE TypeApplications           #-}
{-# LANGUAGE TypeOperators              #-}
module Telegram.Bot.API.InlineMode where

import           Data.Aeson                      (FromJSON (..), ToJSON (..))
import           Data.Hashable                   (Hashable)
import           Data.Proxy
import           Data.Text                       (Text)
import           GHC.Generics                    (Generic)

import           Servant.API
import           Servant.Client                  hiding (Response)

import           Telegram.Bot.API.Internal.Utils
import           Telegram.Bot.API.MakingRequests
import           Telegram.Bot.API.Types
import           Telegram.Bot.API.InlineMode.InlineQueryResult
import Telegram.Bot.API.Internal.TH (makeDefault)

-- * Available types
-- ** User
--
-- | This object represents an incoming inline query. When the user sends an empty query, your bot could return some default or trending results.
--
-- <https://core.telegram.org/bots/api#inline-mode>
data InlineQuery = InlineQuery
  { InlineQuery -> InlineQueryId
inlineQueryId       :: InlineQueryId -- ^ Unique query identifier
  , InlineQuery -> User
inlineQueryFrom     :: User -- ^ Sender
  , InlineQuery -> Maybe Location
inlineQueryLocation :: Maybe Location -- ^ For bots that require user location, sender location
  , InlineQuery -> Text
inlineQueryQuery    :: Text -- ^ Text of the query, up to 256 characters
  , InlineQuery -> Text
inlineQueryOffset   :: Text -- ^ Offset of the results to be returned, can be controlled by bot
  , InlineQuery -> Maybe ChatType
inlineQueryChatType :: Maybe ChatType -- ^ Type of the chat, from which the inline query was sent. Can be either “sender” for a private chat with the inline query sender, “private”, “group”, “supergroup”, or “channel”. The chat type should be always known for requests sent from official clients and most third-party clients, unless the request was sent from a secret chat.
  } deriving ((forall x. InlineQuery -> Rep InlineQuery x)
-> (forall x. Rep InlineQuery x -> InlineQuery)
-> Generic InlineQuery
forall x. Rep InlineQuery x -> InlineQuery
forall x. InlineQuery -> Rep InlineQuery x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. InlineQuery -> Rep InlineQuery x
from :: forall x. InlineQuery -> Rep InlineQuery x
$cto :: forall x. Rep InlineQuery x -> InlineQuery
to :: forall x. Rep InlineQuery x -> InlineQuery
Generic, Int -> InlineQuery -> ShowS
[InlineQuery] -> ShowS
InlineQuery -> String
(Int -> InlineQuery -> ShowS)
-> (InlineQuery -> String)
-> ([InlineQuery] -> ShowS)
-> Show InlineQuery
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InlineQuery -> ShowS
showsPrec :: Int -> InlineQuery -> ShowS
$cshow :: InlineQuery -> String
show :: InlineQuery -> String
$cshowList :: [InlineQuery] -> ShowS
showList :: [InlineQuery] -> ShowS
Show)

-- | Unique identifier for this query
newtype InlineQueryId = InlineQueryId Text
  deriving (InlineQueryId -> InlineQueryId -> Bool
(InlineQueryId -> InlineQueryId -> Bool)
-> (InlineQueryId -> InlineQueryId -> Bool) -> Eq InlineQueryId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InlineQueryId -> InlineQueryId -> Bool
== :: InlineQueryId -> InlineQueryId -> Bool
$c/= :: InlineQueryId -> InlineQueryId -> Bool
/= :: InlineQueryId -> InlineQueryId -> Bool
Eq, Int -> InlineQueryId -> ShowS
[InlineQueryId] -> ShowS
InlineQueryId -> String
(Int -> InlineQueryId -> ShowS)
-> (InlineQueryId -> String)
-> ([InlineQueryId] -> ShowS)
-> Show InlineQueryId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InlineQueryId -> ShowS
showsPrec :: Int -> InlineQueryId -> ShowS
$cshow :: InlineQueryId -> String
show :: InlineQueryId -> String
$cshowList :: [InlineQueryId] -> ShowS
showList :: [InlineQueryId] -> ShowS
Show, [InlineQueryId] -> Value
[InlineQueryId] -> Encoding
InlineQueryId -> Bool
InlineQueryId -> Value
InlineQueryId -> Encoding
(InlineQueryId -> Value)
-> (InlineQueryId -> Encoding)
-> ([InlineQueryId] -> Value)
-> ([InlineQueryId] -> Encoding)
-> (InlineQueryId -> Bool)
-> ToJSON InlineQueryId
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: InlineQueryId -> Value
toJSON :: InlineQueryId -> Value
$ctoEncoding :: InlineQueryId -> Encoding
toEncoding :: InlineQueryId -> Encoding
$ctoJSONList :: [InlineQueryId] -> Value
toJSONList :: [InlineQueryId] -> Value
$ctoEncodingList :: [InlineQueryId] -> Encoding
toEncodingList :: [InlineQueryId] -> Encoding
$comitField :: InlineQueryId -> Bool
omitField :: InlineQueryId -> Bool
ToJSON, Maybe InlineQueryId
Value -> Parser [InlineQueryId]
Value -> Parser InlineQueryId
(Value -> Parser InlineQueryId)
-> (Value -> Parser [InlineQueryId])
-> Maybe InlineQueryId
-> FromJSON InlineQueryId
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser InlineQueryId
parseJSON :: Value -> Parser InlineQueryId
$cparseJSONList :: Value -> Parser [InlineQueryId]
parseJSONList :: Value -> Parser [InlineQueryId]
$comittedField :: Maybe InlineQueryId
omittedField :: Maybe InlineQueryId
FromJSON, Eq InlineQueryId
Eq InlineQueryId =>
(Int -> InlineQueryId -> Int)
-> (InlineQueryId -> Int) -> Hashable InlineQueryId
Int -> InlineQueryId -> Int
InlineQueryId -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> InlineQueryId -> Int
hashWithSalt :: Int -> InlineQueryId -> Int
$chash :: InlineQueryId -> Int
hash :: InlineQueryId -> Int
Hashable, (forall x. InlineQueryId -> Rep InlineQueryId x)
-> (forall x. Rep InlineQueryId x -> InlineQueryId)
-> Generic InlineQueryId
forall x. Rep InlineQueryId x -> InlineQueryId
forall x. InlineQueryId -> Rep InlineQueryId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. InlineQueryId -> Rep InlineQueryId x
from :: forall x. InlineQueryId -> Rep InlineQueryId x
$cto :: forall x. Rep InlineQueryId x -> InlineQueryId
to :: forall x. Rep InlineQueryId x -> InlineQueryId
Generic)

-- * Available methods

-- ** answerInlineQuery

type AnswerInlineQuery
  = "answerInlineQuery" :> ReqBody '[JSON] AnswerInlineQueryRequest :> Post '[JSON] (Response Bool)

answerInlineQuery :: AnswerInlineQueryRequest -> ClientM (Response Bool)
answerInlineQuery :: AnswerInlineQueryRequest -> ClientM (Response Bool)
answerInlineQuery = Proxy AnswerInlineQuery -> Client ClientM AnswerInlineQuery
forall api.
HasClient ClientM api =>
Proxy api -> Client ClientM api
client (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @AnswerInlineQuery)

data AnswerInlineQueryRequest = AnswerInlineQueryRequest
  { AnswerInlineQueryRequest -> InlineQueryId
answerInlineQueryRequestInlineQueryId :: InlineQueryId       -- ^ Unique identifier for the answered query.
  , AnswerInlineQueryRequest -> [InlineQueryResult]
answerInlineQueryRequestResults       :: [InlineQueryResult] -- ^ A JSON-serialized array of results for the inline query.
  , AnswerInlineQueryRequest -> Maybe Seconds
answerInlineQueryCacheTime            :: Maybe Seconds       -- ^ The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300.
  , AnswerInlineQueryRequest -> Maybe Bool
answerInlineQueryIsPersonal           :: Maybe Bool          -- ^ Pass 'True', if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query.
  , AnswerInlineQueryRequest -> Maybe Text
answerInlineQueryNextOffset           :: Maybe Text          -- ^ Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don't support pagination. Offset length can't exceed 64 bytes.
  , AnswerInlineQueryRequest -> Maybe InlineQueryResultsButton
answerInlineQueryButton               :: Maybe InlineQueryResultsButton -- ^ A JSON-serialized object describing a button to be shown above inline query results.
  } deriving ((forall x.
 AnswerInlineQueryRequest -> Rep AnswerInlineQueryRequest x)
-> (forall x.
    Rep AnswerInlineQueryRequest x -> AnswerInlineQueryRequest)
-> Generic AnswerInlineQueryRequest
forall x.
Rep AnswerInlineQueryRequest x -> AnswerInlineQueryRequest
forall x.
AnswerInlineQueryRequest -> Rep AnswerInlineQueryRequest x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x.
AnswerInlineQueryRequest -> Rep AnswerInlineQueryRequest x
from :: forall x.
AnswerInlineQueryRequest -> Rep AnswerInlineQueryRequest x
$cto :: forall x.
Rep AnswerInlineQueryRequest x -> AnswerInlineQueryRequest
to :: forall x.
Rep AnswerInlineQueryRequest x -> AnswerInlineQueryRequest
Generic)

instance ToJSON AnswerInlineQueryRequest where toJSON :: AnswerInlineQueryRequest -> Value
toJSON = AnswerInlineQueryRequest -> Value
forall a (d :: Meta) (f :: * -> *).
(Generic a, GToJSON Zero (Rep a), Rep a ~ D1 d f, Datatype d) =>
a -> Value
gtoJSON
instance FromJSON AnswerInlineQueryRequest where parseJSON :: Value -> Parser AnswerInlineQueryRequest
parseJSON = Value -> Parser AnswerInlineQueryRequest
forall a (d :: Meta) (f :: * -> *).
(Generic a, GFromJSON Zero (Rep a), Rep a ~ D1 d f, Datatype d) =>
Value -> Parser a
gparseJSON

data ChosenInlineResult = ChosenInlineResult
  { ChosenInlineResult -> InlineQueryResultId
chosenInlineResultResultId        :: InlineQueryResultId -- ^ The unique identifier for the result that was chosen.
  , ChosenInlineResult -> User
chosenInlineResultFrom            :: User            -- ^ The user that chose the result.
  , ChosenInlineResult -> Maybe Location
chosenInlineResultLocation        :: Maybe Location  -- ^ Sender location, only for bots that require user location.
  , ChosenInlineResult -> Maybe InlineMessageId
chosenInlineResultInlineMessageId :: Maybe InlineMessageId -- ^ Identifier of the sent inline message. Available only if there is an inline keyboard attached to the message. Will be also received in callback queries and can be used to edit the message.
  , ChosenInlineResult -> InlineQueryId
chosenInlineResultQuery           :: InlineQueryId   -- ^ The query that was used to obtain the result.
  } deriving ((forall x. ChosenInlineResult -> Rep ChosenInlineResult x)
-> (forall x. Rep ChosenInlineResult x -> ChosenInlineResult)
-> Generic ChosenInlineResult
forall x. Rep ChosenInlineResult x -> ChosenInlineResult
forall x. ChosenInlineResult -> Rep ChosenInlineResult x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ChosenInlineResult -> Rep ChosenInlineResult x
from :: forall x. ChosenInlineResult -> Rep ChosenInlineResult x
$cto :: forall x. Rep ChosenInlineResult x -> ChosenInlineResult
to :: forall x. Rep ChosenInlineResult x -> ChosenInlineResult
Generic, Int -> ChosenInlineResult -> ShowS
[ChosenInlineResult] -> ShowS
ChosenInlineResult -> String
(Int -> ChosenInlineResult -> ShowS)
-> (ChosenInlineResult -> String)
-> ([ChosenInlineResult] -> ShowS)
-> Show ChosenInlineResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChosenInlineResult -> ShowS
showsPrec :: Int -> ChosenInlineResult -> ShowS
$cshow :: ChosenInlineResult -> String
show :: ChosenInlineResult -> String
$cshowList :: [ChosenInlineResult] -> ShowS
showList :: [ChosenInlineResult] -> ShowS
Show)

instance ToJSON ChosenInlineResult where toJSON :: ChosenInlineResult -> Value
toJSON = ChosenInlineResult -> Value
forall a (d :: Meta) (f :: * -> *).
(Generic a, GToJSON Zero (Rep a), Rep a ~ D1 d f, Datatype d) =>
a -> Value
gtoJSON
instance FromJSON ChosenInlineResult where parseJSON :: Value -> Parser ChosenInlineResult
parseJSON = Value -> Parser ChosenInlineResult
forall a (d :: Meta) (f :: * -> *).
(Generic a, GFromJSON Zero (Rep a), Rep a ~ D1 d f, Datatype d) =>
Value -> Parser a
gparseJSON

deriveJSON' ''InlineQuery

makeDefault ''AnswerInlineQueryRequest