{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell   #-}

module CoinbasePro.Authenticated.Withdrawal
    ( WithdrawalDetails (..)
    , WithdrawalRequest (..)
    , WithdrawalResponse (..)
    , CoinbaseWithdrawalRequest (..)
    , CryptoWithdrawalRequest (..)
    , CryptoWithdrawalResponse (..)
    , WithdrawalFeeEstimateResponse (..)
    ) where

import           Data.Aeson                         (FromJSON, parseJSON,
                                                     withObject, (.:), (.:?))
import           Data.Aeson.Casing                  (snakeCase)
import           Data.Aeson.TH                      (defaultOptions, deriveJSON,
                                                     fieldLabelModifier)
import           Data.Text                          (Text)
import           Data.Time.Clock                    (UTCTime)
import           Data.UUID                          (UUID)

import           CoinbasePro.Authenticated.Accounts (AccountId)
import           CoinbasePro.Authenticated.Payment  (PaymentMethodId)
import           Control.Applicative
import           Text.Read                          (readMaybe)


data WithdrawalDetails = WithdrawalDetails
    { WithdrawalDetails -> Maybe Text
destinationTag          :: Maybe Text
    , WithdrawalDetails -> Maybe Text
sentToAddress           :: Maybe Text
    , WithdrawalDetails -> Text
coinbaseAccountId       :: Text
    , WithdrawalDetails -> Maybe Text
destinationTagName      :: Maybe Text
    , WithdrawalDetails -> Maybe Text
coinbaseWithdrawalId    :: Maybe Text
    , WithdrawalDetails -> Maybe Text
coinbaseTransactionId   :: Maybe Text
    , WithdrawalDetails -> Text
coinbasePaymentMethodId :: Text
    , WithdrawalDetails -> Maybe Double
fee                     :: Maybe Double
    , WithdrawalDetails -> Maybe Double
subtotal                :: Maybe Double
    } deriving (WithdrawalDetails -> WithdrawalDetails -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WithdrawalDetails -> WithdrawalDetails -> Bool
$c/= :: WithdrawalDetails -> WithdrawalDetails -> Bool
== :: WithdrawalDetails -> WithdrawalDetails -> Bool
$c== :: WithdrawalDetails -> WithdrawalDetails -> Bool
Eq, Int -> WithdrawalDetails -> ShowS
[WithdrawalDetails] -> ShowS
WithdrawalDetails -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WithdrawalDetails] -> ShowS
$cshowList :: [WithdrawalDetails] -> ShowS
show :: WithdrawalDetails -> String
$cshow :: WithdrawalDetails -> String
showsPrec :: Int -> WithdrawalDetails -> ShowS
$cshowsPrec :: Int -> WithdrawalDetails -> ShowS
Show)


instance FromJSON WithdrawalDetails where
  parseJSON :: Value -> Parser WithdrawalDetails
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"withdrawal details" forall a b. (a -> b) -> a -> b
$ \Object
o -> Maybe Text
-> Maybe Text
-> Text
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Text
-> Maybe Double
-> Maybe Double
-> WithdrawalDetails
WithdrawalDetails
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"destination_tag"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"sent_to_address"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"coinbase_account_id"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"destination_tag_name"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"coinbase_withdrawal_id"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"coinbase_transaction_id"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"coinbase_payment_method_id"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Maybe a
Nothing forall a. Read a => String -> Maybe a
readMaybe forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"fee")
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Maybe a
Nothing forall a. Read a => String -> Maybe a
readMaybe forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"subtotal")


data WithdrawalRequest = WithdrawalRequest
    { WithdrawalRequest -> Double
amount          :: Double
    , WithdrawalRequest -> Text
currency        :: Text
    , WithdrawalRequest -> PaymentMethodId
paymentMethodId :: PaymentMethodId
    } deriving (WithdrawalRequest -> WithdrawalRequest -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WithdrawalRequest -> WithdrawalRequest -> Bool
$c/= :: WithdrawalRequest -> WithdrawalRequest -> Bool
== :: WithdrawalRequest -> WithdrawalRequest -> Bool
$c== :: WithdrawalRequest -> WithdrawalRequest -> Bool
Eq, Int -> WithdrawalRequest -> ShowS
[WithdrawalRequest] -> ShowS
WithdrawalRequest -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WithdrawalRequest] -> ShowS
$cshowList :: [WithdrawalRequest] -> ShowS
show :: WithdrawalRequest -> String
$cshow :: WithdrawalRequest -> String
showsPrec :: Int -> WithdrawalRequest -> ShowS
$cshowsPrec :: Int -> WithdrawalRequest -> ShowS
Show)


deriveJSON defaultOptions { fieldLabelModifier = snakeCase } ''WithdrawalRequest


data WithdrawalResponse = WithdrawalResponse
    { WithdrawalResponse -> UUID
wId       :: UUID
    , WithdrawalResponse -> Double
wAmount   :: Double
    , WithdrawalResponse -> Text
wCurrency :: Text
    , WithdrawalResponse -> UTCTime
wPayoutAt :: UTCTime
    } deriving (WithdrawalResponse -> WithdrawalResponse -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WithdrawalResponse -> WithdrawalResponse -> Bool
$c/= :: WithdrawalResponse -> WithdrawalResponse -> Bool
== :: WithdrawalResponse -> WithdrawalResponse -> Bool
$c== :: WithdrawalResponse -> WithdrawalResponse -> Bool
Eq, Int -> WithdrawalResponse -> ShowS
[WithdrawalResponse] -> ShowS
WithdrawalResponse -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WithdrawalResponse] -> ShowS
$cshowList :: [WithdrawalResponse] -> ShowS
show :: WithdrawalResponse -> String
$cshow :: WithdrawalResponse -> String
showsPrec :: Int -> WithdrawalResponse -> ShowS
$cshowsPrec :: Int -> WithdrawalResponse -> ShowS
Show)


instance FromJSON WithdrawalResponse where
  parseJSON :: Value -> Parser WithdrawalResponse
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"withdrawal response" forall a b. (a -> b) -> a -> b
$ \Object
o -> UUID -> Double -> Text -> UTCTime -> WithdrawalResponse
WithdrawalResponse
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"id"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall a. Read a => String -> a
read forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"amount")
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"currency"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"payout_at"


data CoinbaseWithdrawalRequest = CoinbaseWithdrawalRequest
    { CoinbaseWithdrawalRequest -> Double
cAmount            :: Double
    , CoinbaseWithdrawalRequest -> Text
cCurrency          :: Text
    , CoinbaseWithdrawalRequest -> AccountId
cCoinbaseAccountId :: AccountId
    } deriving (CoinbaseWithdrawalRequest -> CoinbaseWithdrawalRequest -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CoinbaseWithdrawalRequest -> CoinbaseWithdrawalRequest -> Bool
$c/= :: CoinbaseWithdrawalRequest -> CoinbaseWithdrawalRequest -> Bool
== :: CoinbaseWithdrawalRequest -> CoinbaseWithdrawalRequest -> Bool
$c== :: CoinbaseWithdrawalRequest -> CoinbaseWithdrawalRequest -> Bool
Eq, Int -> CoinbaseWithdrawalRequest -> ShowS
[CoinbaseWithdrawalRequest] -> ShowS
CoinbaseWithdrawalRequest -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CoinbaseWithdrawalRequest] -> ShowS
$cshowList :: [CoinbaseWithdrawalRequest] -> ShowS
show :: CoinbaseWithdrawalRequest -> String
$cshow :: CoinbaseWithdrawalRequest -> String
showsPrec :: Int -> CoinbaseWithdrawalRequest -> ShowS
$cshowsPrec :: Int -> CoinbaseWithdrawalRequest -> ShowS
Show)


deriveJSON defaultOptions { fieldLabelModifier = snakeCase . drop 1 } ''CoinbaseWithdrawalRequest


data CryptoWithdrawalRequest = CryptoWithdrawalRequest
    { CryptoWithdrawalRequest -> Double
crAmount        :: Double
    , CryptoWithdrawalRequest -> Text
crCurrency      :: Text
    , CryptoWithdrawalRequest -> Text
crCryptoAddress :: Text
    } deriving (CryptoWithdrawalRequest -> CryptoWithdrawalRequest -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CryptoWithdrawalRequest -> CryptoWithdrawalRequest -> Bool
$c/= :: CryptoWithdrawalRequest -> CryptoWithdrawalRequest -> Bool
== :: CryptoWithdrawalRequest -> CryptoWithdrawalRequest -> Bool
$c== :: CryptoWithdrawalRequest -> CryptoWithdrawalRequest -> Bool
Eq, Int -> CryptoWithdrawalRequest -> ShowS
[CryptoWithdrawalRequest] -> ShowS
CryptoWithdrawalRequest -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CryptoWithdrawalRequest] -> ShowS
$cshowList :: [CryptoWithdrawalRequest] -> ShowS
show :: CryptoWithdrawalRequest -> String
$cshow :: CryptoWithdrawalRequest -> String
showsPrec :: Int -> CryptoWithdrawalRequest -> ShowS
$cshowsPrec :: Int -> CryptoWithdrawalRequest -> ShowS
Show)


deriveJSON defaultOptions { fieldLabelModifier = snakeCase . drop 2 } ''CryptoWithdrawalRequest


data CryptoWithdrawalResponse = CryptoWithdrawalResponse
    { CryptoWithdrawalResponse -> UUID
cwId       :: UUID
    , CryptoWithdrawalResponse -> Double
cwAmount   :: Double
    , CryptoWithdrawalResponse -> Text
cwCurrency :: Text
    , CryptoWithdrawalResponse -> Double
cwFee      :: Double
    , CryptoWithdrawalResponse -> Double
cwSubtotal :: Double
    } deriving (CryptoWithdrawalResponse -> CryptoWithdrawalResponse -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CryptoWithdrawalResponse -> CryptoWithdrawalResponse -> Bool
$c/= :: CryptoWithdrawalResponse -> CryptoWithdrawalResponse -> Bool
== :: CryptoWithdrawalResponse -> CryptoWithdrawalResponse -> Bool
$c== :: CryptoWithdrawalResponse -> CryptoWithdrawalResponse -> Bool
Eq, Int -> CryptoWithdrawalResponse -> ShowS
[CryptoWithdrawalResponse] -> ShowS
CryptoWithdrawalResponse -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CryptoWithdrawalResponse] -> ShowS
$cshowList :: [CryptoWithdrawalResponse] -> ShowS
show :: CryptoWithdrawalResponse -> String
$cshow :: CryptoWithdrawalResponse -> String
showsPrec :: Int -> CryptoWithdrawalResponse -> ShowS
$cshowsPrec :: Int -> CryptoWithdrawalResponse -> ShowS
Show)


instance FromJSON CryptoWithdrawalResponse where
  parseJSON :: Value -> Parser CryptoWithdrawalResponse
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"crypto withdrawal response" forall a b. (a -> b) -> a -> b
$ \Object
o -> UUID
-> Double -> Text -> Double -> Double -> CryptoWithdrawalResponse
CryptoWithdrawalResponse
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"id"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall a. Read a => String -> a
read forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"amount")
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"currency"
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((forall a. Read a => String -> a
read forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"fee") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"fee"))
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((forall a. Read a => String -> a
read forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"subtotal") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"subtotal"))



newtype WithdrawalFeeEstimateResponse = WithdrawalFeeEstimateResponse
    { WithdrawalFeeEstimateResponse -> Double
wfFee :: Double} deriving (WithdrawalFeeEstimateResponse
-> WithdrawalFeeEstimateResponse -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WithdrawalFeeEstimateResponse
-> WithdrawalFeeEstimateResponse -> Bool
$c/= :: WithdrawalFeeEstimateResponse
-> WithdrawalFeeEstimateResponse -> Bool
== :: WithdrawalFeeEstimateResponse
-> WithdrawalFeeEstimateResponse -> Bool
$c== :: WithdrawalFeeEstimateResponse
-> WithdrawalFeeEstimateResponse -> Bool
Eq, Int -> WithdrawalFeeEstimateResponse -> ShowS
[WithdrawalFeeEstimateResponse] -> ShowS
WithdrawalFeeEstimateResponse -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WithdrawalFeeEstimateResponse] -> ShowS
$cshowList :: [WithdrawalFeeEstimateResponse] -> ShowS
show :: WithdrawalFeeEstimateResponse -> String
$cshow :: WithdrawalFeeEstimateResponse -> String
showsPrec :: Int -> WithdrawalFeeEstimateResponse -> ShowS
$cshowsPrec :: Int -> WithdrawalFeeEstimateResponse -> ShowS
Show)


deriveJSON defaultOptions { fieldLabelModifier = snakeCase . drop 2 } ''WithdrawalFeeEstimateResponse