-- | Discord Interactions
module Calamity.Types.Model.Interaction (
  Interaction (..),
  InteractionToken (..),
  InteractionData (..),
  ResolvedInteractionData (..),
  InteractionType (..),
  Application,
  ApplicationCommand,
) where

import Calamity.Internal.AesonThings
import Calamity.Internal.OverriddenVia
import Calamity.Internal.Utils
import Calamity.Types.Model.Channel (Attachment, Channel, Partial)
import Calamity.Types.Model.Channel.Component
import Calamity.Types.Model.Channel.Message (Message)
import Calamity.Types.Model.Guild (Guild, Role)
import Calamity.Types.Model.Guild.Member (Member)
import Calamity.Types.Model.User (User)
import Calamity.Types.Snowflake
import Data.Aeson
import qualified Data.HashMap.Strict as H
import Data.Scientific (toBoundedInteger)
import qualified Data.Text as T
import GHC.Generics

-- | Empty type to flag application IDs
data Application

-- | Empty type to flag application command IDs
data ApplicationCommand

newtype InteractionToken = InteractionToken
  { InteractionToken -> Text
fromInteractionToken :: T.Text
  }
  deriving stock (Int -> InteractionToken -> ShowS
[InteractionToken] -> ShowS
InteractionToken -> String
(Int -> InteractionToken -> ShowS)
-> (InteractionToken -> String)
-> ([InteractionToken] -> ShowS)
-> Show InteractionToken
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InteractionToken] -> ShowS
$cshowList :: [InteractionToken] -> ShowS
show :: InteractionToken -> String
$cshow :: InteractionToken -> String
showsPrec :: Int -> InteractionToken -> ShowS
$cshowsPrec :: Int -> InteractionToken -> ShowS
Show, (forall x. InteractionToken -> Rep InteractionToken x)
-> (forall x. Rep InteractionToken x -> InteractionToken)
-> Generic InteractionToken
forall x. Rep InteractionToken x -> InteractionToken
forall x. InteractionToken -> Rep InteractionToken x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep InteractionToken x -> InteractionToken
$cfrom :: forall x. InteractionToken -> Rep InteractionToken x
Generic)
  deriving (Value -> Parser [InteractionToken]
Value -> Parser InteractionToken
(Value -> Parser InteractionToken)
-> (Value -> Parser [InteractionToken])
-> FromJSON InteractionToken
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [InteractionToken]
$cparseJSONList :: Value -> Parser [InteractionToken]
parseJSON :: Value -> Parser InteractionToken
$cparseJSON :: Value -> Parser InteractionToken
FromJSON, [InteractionToken] -> Encoding
[InteractionToken] -> Value
InteractionToken -> Encoding
InteractionToken -> Value
(InteractionToken -> Value)
-> (InteractionToken -> Encoding)
-> ([InteractionToken] -> Value)
-> ([InteractionToken] -> Encoding)
-> ToJSON InteractionToken
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [InteractionToken] -> Encoding
$ctoEncodingList :: [InteractionToken] -> Encoding
toJSONList :: [InteractionToken] -> Value
$ctoJSONList :: [InteractionToken] -> Value
toEncoding :: InteractionToken -> Encoding
$ctoEncoding :: InteractionToken -> Encoding
toJSON :: InteractionToken -> Value
$ctoJSON :: InteractionToken -> Value
ToJSON) via T.Text

data Interaction = Interaction
  { Interaction -> Snowflake Interaction
id :: Snowflake Interaction
  , Interaction -> Snowflake Application
applicationID :: Snowflake Application
  , Interaction -> InteractionType
type_ :: InteractionType
  , Interaction -> Maybe InteractionData
data_ :: Maybe InteractionData
  , Interaction -> Maybe (Snowflake Guild)
guildID :: Maybe (Snowflake Guild)
  , Interaction -> Maybe (Snowflake Channel)
channelID :: Maybe (Snowflake Channel)
  , Interaction -> Maybe Member
member :: Maybe Member
  , Interaction -> Maybe User
user :: Maybe User
  , Interaction -> InteractionToken
token :: InteractionToken
  , Interaction -> Int
version :: Int
  , Interaction -> Maybe Message
message :: Maybe Message
  , Interaction -> Maybe Text
locale :: Maybe T.Text
  , Interaction -> Maybe Text
guildLocale :: Maybe T.Text
  }
  deriving (Int -> Interaction -> ShowS
[Interaction] -> ShowS
Interaction -> String
(Int -> Interaction -> ShowS)
-> (Interaction -> String)
-> ([Interaction] -> ShowS)
-> Show Interaction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Interaction] -> ShowS
$cshowList :: [Interaction] -> ShowS
show :: Interaction -> String
$cshow :: Interaction -> String
showsPrec :: Int -> Interaction -> ShowS
$cshowsPrec :: Int -> Interaction -> ShowS
Show, (forall x. Interaction -> Rep Interaction x)
-> (forall x. Rep Interaction x -> Interaction)
-> Generic Interaction
forall x. Rep Interaction x -> Interaction
forall x. Interaction -> Rep Interaction x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Interaction x -> Interaction
$cfrom :: forall x. Interaction -> Rep Interaction x
Generic)
  deriving (Value -> Parser [Interaction]
Value -> Parser Interaction
(Value -> Parser Interaction)
-> (Value -> Parser [Interaction]) -> FromJSON Interaction
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Interaction]
$cparseJSONList :: Value -> Parser [Interaction]
parseJSON :: Value -> Parser Interaction
$cparseJSON :: Value -> Parser Interaction
FromJSON) via CalamityJSON Interaction
  deriving (HasID Interaction) via HasIDField "id" Interaction
  deriving (HasID Application) via HasIDField "applicationID" Interaction

data InteractionData = InteractionData
  { InteractionData -> Maybe (Snowflake ApplicationCommand)
id :: Maybe (Snowflake ApplicationCommand)
  , InteractionData -> Maybe Text
name :: Maybe T.Text
  , InteractionData -> Maybe ResolvedInteractionData
resolved :: Maybe ResolvedInteractionData
  , -- , options :: [ApplicationCommandInteractionDataOptions]
    -- No commands yet
    InteractionData -> Maybe CustomID
customID :: Maybe CustomID
  , InteractionData -> Maybe ComponentType
componentType :: Maybe ComponentType
  , InteractionData -> Maybe [Text]
values :: Maybe [T.Text]
  , InteractionData -> Maybe (Snowflake ())
targetID :: Maybe (Snowflake ())
  , InteractionData -> Maybe [Value]
components :: Maybe [Value]
  }
  deriving (Int -> InteractionData -> ShowS
[InteractionData] -> ShowS
InteractionData -> String
(Int -> InteractionData -> ShowS)
-> (InteractionData -> String)
-> ([InteractionData] -> ShowS)
-> Show InteractionData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InteractionData] -> ShowS
$cshowList :: [InteractionData] -> ShowS
show :: InteractionData -> String
$cshow :: InteractionData -> String
showsPrec :: Int -> InteractionData -> ShowS
$cshowsPrec :: Int -> InteractionData -> ShowS
Show, (forall x. InteractionData -> Rep InteractionData x)
-> (forall x. Rep InteractionData x -> InteractionData)
-> Generic InteractionData
forall x. Rep InteractionData x -> InteractionData
forall x. InteractionData -> Rep InteractionData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep InteractionData x -> InteractionData
$cfrom :: forall x. InteractionData -> Rep InteractionData x
Generic)
  deriving (Value -> Parser [InteractionData]
Value -> Parser InteractionData
(Value -> Parser InteractionData)
-> (Value -> Parser [InteractionData]) -> FromJSON InteractionData
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [InteractionData]
$cparseJSONList :: Value -> Parser [InteractionData]
parseJSON :: Value -> Parser InteractionData
$cparseJSON :: Value -> Parser InteractionData
FromJSON) via CalamityJSON InteractionData

data ResolvedInteractionData' = ResolvedInteractionData'
  { ResolvedInteractionData'
-> CalamityFromStringShow (HashMap (Snowflake User) User)
users :: CalamityFromStringShow (H.HashMap (Snowflake User) User)
  , ResolvedInteractionData'
-> CalamityFromStringShow (HashMap (Snowflake Member) Member)
members :: CalamityFromStringShow (H.HashMap (Snowflake Member) Member)
  , ResolvedInteractionData'
-> CalamityFromStringShow (HashMap (Snowflake Role) Role)
roles :: CalamityFromStringShow (H.HashMap (Snowflake Role) Role)
  , ResolvedInteractionData'
-> CalamityFromStringShow
     (HashMap (Snowflake Channel) (Partial Channel))
channels :: CalamityFromStringShow (H.HashMap (Snowflake Channel) (Partial Channel))
  , ResolvedInteractionData'
-> CalamityFromStringShow
     (HashMap (Snowflake Message) (Partial Message))
messages :: CalamityFromStringShow (H.HashMap (Snowflake Message) (Partial Message))
  , ResolvedInteractionData'
-> CalamityFromStringShow
     (HashMap (Snowflake Attachment) Attachment)
attachments :: CalamityFromStringShow (H.HashMap (Snowflake Attachment) Attachment)
  }
  deriving ((forall x.
 ResolvedInteractionData' -> Rep ResolvedInteractionData' x)
-> (forall x.
    Rep ResolvedInteractionData' x -> ResolvedInteractionData')
-> Generic ResolvedInteractionData'
forall x.
Rep ResolvedInteractionData' x -> ResolvedInteractionData'
forall x.
ResolvedInteractionData' -> Rep ResolvedInteractionData' x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x.
Rep ResolvedInteractionData' x -> ResolvedInteractionData'
$cfrom :: forall x.
ResolvedInteractionData' -> Rep ResolvedInteractionData' x
Generic)
  deriving (Value -> Parser [ResolvedInteractionData']
Value -> Parser ResolvedInteractionData'
(Value -> Parser ResolvedInteractionData')
-> (Value -> Parser [ResolvedInteractionData'])
-> FromJSON ResolvedInteractionData'
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [ResolvedInteractionData']
$cparseJSONList :: Value -> Parser [ResolvedInteractionData']
parseJSON :: Value -> Parser ResolvedInteractionData'
$cparseJSON :: Value -> Parser ResolvedInteractionData'
FromJSON) via CalamityJSON ResolvedInteractionData'

data ResolvedInteractionData = ResolvedInteractionData
  { ResolvedInteractionData -> HashMap (Snowflake User) User
users :: H.HashMap (Snowflake User) User
  , ResolvedInteractionData -> HashMap (Snowflake Member) Member
members :: H.HashMap (Snowflake Member) Member
  , ResolvedInteractionData -> HashMap (Snowflake Role) Role
roles :: H.HashMap (Snowflake Role) Role
  , ResolvedInteractionData
-> HashMap (Snowflake Channel) (Partial Channel)
channels :: H.HashMap (Snowflake Channel) (Partial Channel)
  , ResolvedInteractionData
-> HashMap (Snowflake Message) (Partial Message)
messages :: H.HashMap (Snowflake Message) (Partial Message)
  , ResolvedInteractionData
-> HashMap (Snowflake Attachment) Attachment
attachments :: H.HashMap (Snowflake Attachment) Attachment
  }
  deriving (Int -> ResolvedInteractionData -> ShowS
[ResolvedInteractionData] -> ShowS
ResolvedInteractionData -> String
(Int -> ResolvedInteractionData -> ShowS)
-> (ResolvedInteractionData -> String)
-> ([ResolvedInteractionData] -> ShowS)
-> Show ResolvedInteractionData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResolvedInteractionData] -> ShowS
$cshowList :: [ResolvedInteractionData] -> ShowS
show :: ResolvedInteractionData -> String
$cshow :: ResolvedInteractionData -> String
showsPrec :: Int -> ResolvedInteractionData -> ShowS
$cshowsPrec :: Int -> ResolvedInteractionData -> ShowS
Show, (forall x.
 ResolvedInteractionData -> Rep ResolvedInteractionData x)
-> (forall x.
    Rep ResolvedInteractionData x -> ResolvedInteractionData)
-> Generic ResolvedInteractionData
forall x. Rep ResolvedInteractionData x -> ResolvedInteractionData
forall x. ResolvedInteractionData -> Rep ResolvedInteractionData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ResolvedInteractionData x -> ResolvedInteractionData
$cfrom :: forall x. ResolvedInteractionData -> Rep ResolvedInteractionData x
Generic)
  deriving
    (Value -> Parser [ResolvedInteractionData]
Value -> Parser ResolvedInteractionData
(Value -> Parser ResolvedInteractionData)
-> (Value -> Parser [ResolvedInteractionData])
-> FromJSON ResolvedInteractionData
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [ResolvedInteractionData]
$cparseJSONList :: Value -> Parser [ResolvedInteractionData]
parseJSON :: Value -> Parser ResolvedInteractionData
$cparseJSON :: Value -> Parser ResolvedInteractionData
FromJSON)
    via OverriddenVia ResolvedInteractionData ResolvedInteractionData'

data InteractionType
  = PingType
  | ApplicationCommandType
  | MessageComponentType
  | ApplicationCommandAutoCompleteType
  | ModalSubmitType
  deriving (InteractionType -> InteractionType -> Bool
(InteractionType -> InteractionType -> Bool)
-> (InteractionType -> InteractionType -> Bool)
-> Eq InteractionType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: InteractionType -> InteractionType -> Bool
$c/= :: InteractionType -> InteractionType -> Bool
== :: InteractionType -> InteractionType -> Bool
$c== :: InteractionType -> InteractionType -> Bool
Eq, Int -> InteractionType -> ShowS
[InteractionType] -> ShowS
InteractionType -> String
(Int -> InteractionType -> ShowS)
-> (InteractionType -> String)
-> ([InteractionType] -> ShowS)
-> Show InteractionType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InteractionType] -> ShowS
$cshowList :: [InteractionType] -> ShowS
show :: InteractionType -> String
$cshow :: InteractionType -> String
showsPrec :: Int -> InteractionType -> ShowS
$cshowsPrec :: Int -> InteractionType -> ShowS
Show, (forall x. InteractionType -> Rep InteractionType x)
-> (forall x. Rep InteractionType x -> InteractionType)
-> Generic InteractionType
forall x. Rep InteractionType x -> InteractionType
forall x. InteractionType -> Rep InteractionType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep InteractionType x -> InteractionType
$cfrom :: forall x. InteractionType -> Rep InteractionType x
Generic)

instance FromJSON InteractionType where
  parseJSON :: Value -> Parser InteractionType
parseJSON = String
-> (Scientific -> Parser InteractionType)
-> Value
-> Parser InteractionType
forall a. String -> (Scientific -> Parser a) -> Value -> Parser a
withScientific String
"InteractionType" ((Scientific -> Parser InteractionType)
 -> Value -> Parser InteractionType)
-> (Scientific -> Parser InteractionType)
-> Value
-> Parser InteractionType
forall a b. (a -> b) -> a -> b
$ \Scientific
n -> case Scientific -> Maybe Int
forall i. (Integral i, Bounded i) => Scientific -> Maybe i
toBoundedInteger @Int Scientific
n of
    Just Int
1 -> InteractionType -> Parser InteractionType
forall (f :: * -> *) a. Applicative f => a -> f a
pure InteractionType
PingType
    Just Int
2 -> InteractionType -> Parser InteractionType
forall (f :: * -> *) a. Applicative f => a -> f a
pure InteractionType
ApplicationCommandType
    Just Int
3 -> InteractionType -> Parser InteractionType
forall (f :: * -> *) a. Applicative f => a -> f a
pure InteractionType
MessageComponentType
    Just Int
4 -> InteractionType -> Parser InteractionType
forall (f :: * -> *) a. Applicative f => a -> f a
pure InteractionType
ApplicationCommandAutoCompleteType
    Just Int
5 -> InteractionType -> Parser InteractionType
forall (f :: * -> *) a. Applicative f => a -> f a
pure InteractionType
ModalSubmitType
    Maybe Int
_ -> String -> Parser InteractionType
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser InteractionType)
-> String -> Parser InteractionType
forall a b. (a -> b) -> a -> b
$ String
"Invalid InteractionType: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Scientific -> String
forall a. Show a => a -> String
show Scientific
n