module Bank.TrueLayer.DataAPI.Accounts
  ( accounts
  , account
  , accountBalance
  , transactions
  , pendingTransactions
  , standingOrders
  , directDebits
  ) where

import           Bank.TrueLayer.DataAPI.Schema
    ( AccountBalances
    , AccountId (..)
    , Accounts
    , DirectDebits
    , Ip (..)
    , StandingOrders
    , TransactionParams
    , Transactions
    , addTransactionParams
    )
import           Bank.TrueLayer.Internal
    (AccessToken, Endpoint, defaults, fromString, getWithAuthAndOptions, header, (&), (.~), (</>))


accounts :: Ip -> Endpoint -> AccessToken -> IO (Maybe Accounts)
accounts :: Ip -> Endpoint -> AccessToken -> IO (Maybe Accounts)
accounts (Ip String
ip) = do
  let opts :: Options
opts = Options
defaults Options -> (Options -> Options) -> Options
forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"X-PSU-IP" (([ByteString] -> Identity [ByteString])
 -> Options -> Identity Options)
-> [ByteString] -> Options -> Options
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [String -> ByteString
forall a. IsString a => String -> a
fromString String
ip]
  Options -> String -> Endpoint -> AccessToken -> IO (Maybe Accounts)
forall a.
FromJSON a =>
Options -> String -> Endpoint -> AccessToken -> IO (Maybe a)
getWithAuthAndOptions Options
opts String
"/data/v1/accounts"

account :: Ip -> AccountId -> Endpoint -> AccessToken -> IO (Maybe Accounts)
account :: Ip -> AccountId -> Endpoint -> AccessToken -> IO (Maybe Accounts)
account (Ip String
ip) (AccountId String
accountId) = do
  let opts :: Options
opts = Options
defaults Options -> (Options -> Options) -> Options
forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"X-PSU-IP" (([ByteString] -> Identity [ByteString])
 -> Options -> Identity Options)
-> [ByteString] -> Options -> Options
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [String -> ByteString
forall a. IsString a => String -> a
fromString String
ip]
  Options -> String -> Endpoint -> AccessToken -> IO (Maybe Accounts)
forall a.
FromJSON a =>
Options -> String -> Endpoint -> AccessToken -> IO (Maybe a)
getWithAuthAndOptions Options
opts (String
"/data/v1/accounts" String -> String -> String
</> String
accountId)

accountBalance :: Ip -> AccountId -> Endpoint -> AccessToken -> IO (Maybe AccountBalances)
accountBalance :: Ip
-> AccountId
-> Endpoint
-> AccessToken
-> IO (Maybe AccountBalances)
accountBalance (Ip String
ip) (AccountId String
accountId) = do
  let opts :: Options
opts = Options
defaults Options -> (Options -> Options) -> Options
forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"X-PSU-IP" (([ByteString] -> Identity [ByteString])
 -> Options -> Identity Options)
-> [ByteString] -> Options -> Options
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [String -> ByteString
forall a. IsString a => String -> a
fromString String
ip]
  Options
-> String -> Endpoint -> AccessToken -> IO (Maybe AccountBalances)
forall a.
FromJSON a =>
Options -> String -> Endpoint -> AccessToken -> IO (Maybe a)
getWithAuthAndOptions Options
opts (String
"/data/v1/accounts" String -> String -> String
</> String
accountId String -> String -> String
</> String
"balance")

transactions :: Ip -> AccountId -> Maybe TransactionParams -> Endpoint -> AccessToken -> IO (Maybe Transactions)
transactions :: Ip
-> AccountId
-> Maybe TransactionParams
-> Endpoint
-> AccessToken
-> IO (Maybe Transactions)
transactions (Ip String
ip) (AccountId String
accountId) Maybe TransactionParams
params Endpoint
endpoint AccessToken
accessToken = do
  Options
opts <- Maybe TransactionParams -> Options -> IO Options
addTransactionParams Maybe TransactionParams
params (Options
defaults Options -> (Options -> Options) -> Options
forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"X-PSU-IP" (([ByteString] -> Identity [ByteString])
 -> Options -> Identity Options)
-> [ByteString] -> Options -> Options
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [String -> ByteString
forall a. IsString a => String -> a
fromString String
ip])
  Options
-> String -> Endpoint -> AccessToken -> IO (Maybe Transactions)
forall a.
FromJSON a =>
Options -> String -> Endpoint -> AccessToken -> IO (Maybe a)
getWithAuthAndOptions Options
opts (String
"/data/v1/accounts" String -> String -> String
</> String
accountId String -> String -> String
</> String
"transactions")Endpoint
endpoint AccessToken
accessToken

pendingTransactions :: Ip -> AccountId -> Maybe TransactionParams -> Endpoint -> AccessToken -> IO (Maybe Transactions)
pendingTransactions :: Ip
-> AccountId
-> Maybe TransactionParams
-> Endpoint
-> AccessToken
-> IO (Maybe Transactions)
pendingTransactions (Ip String
ip) (AccountId String
accountId) Maybe TransactionParams
params Endpoint
endpoint AccessToken
accessToken = do
  Options
opts <- Maybe TransactionParams -> Options -> IO Options
addTransactionParams Maybe TransactionParams
params (Options
defaults Options -> (Options -> Options) -> Options
forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"X-PSU-IP" (([ByteString] -> Identity [ByteString])
 -> Options -> Identity Options)
-> [ByteString] -> Options -> Options
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [String -> ByteString
forall a. IsString a => String -> a
fromString String
ip])
  Options
-> String -> Endpoint -> AccessToken -> IO (Maybe Transactions)
forall a.
FromJSON a =>
Options -> String -> Endpoint -> AccessToken -> IO (Maybe a)
getWithAuthAndOptions Options
opts (String
"/data/v1/accounts" String -> String -> String
</> String
accountId String -> String -> String
</> String
"transactions/pending") Endpoint
endpoint AccessToken
accessToken

standingOrders :: Ip -> AccountId -> Endpoint -> AccessToken -> IO (Maybe StandingOrders)
standingOrders :: Ip
-> AccountId
-> Endpoint
-> AccessToken
-> IO (Maybe StandingOrders)
standingOrders (Ip String
ip) (AccountId String
accountId) = do
  let opts :: Options
opts = Options
defaults Options -> (Options -> Options) -> Options
forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"X-PSU-IP" (([ByteString] -> Identity [ByteString])
 -> Options -> Identity Options)
-> [ByteString] -> Options -> Options
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [String -> ByteString
forall a. IsString a => String -> a
fromString String
ip]
  Options
-> String -> Endpoint -> AccessToken -> IO (Maybe StandingOrders)
forall a.
FromJSON a =>
Options -> String -> Endpoint -> AccessToken -> IO (Maybe a)
getWithAuthAndOptions Options
opts (String
"/data/v1/accounts" String -> String -> String
</> String
accountId String -> String -> String
</> String
"standing-orders")

directDebits :: Ip -> AccountId -> Endpoint -> AccessToken -> IO (Maybe DirectDebits)
directDebits :: Ip
-> AccountId -> Endpoint -> AccessToken -> IO (Maybe DirectDebits)
directDebits (Ip String
ip) (AccountId String
accountId) = do
  let opts :: Options
opts = Options
defaults Options -> (Options -> Options) -> Options
forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"X-PSU-IP" (([ByteString] -> Identity [ByteString])
 -> Options -> Identity Options)
-> [ByteString] -> Options -> Options
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [String -> ByteString
forall a. IsString a => String -> a
fromString String
ip]
  Options
-> String -> Endpoint -> AccessToken -> IO (Maybe DirectDebits)
forall a.
FromJSON a =>
Options -> String -> Endpoint -> AccessToken -> IO (Maybe a)
getWithAuthAndOptions Options
opts (String
"/data/v1/accounts" String -> String -> String
</> String
accountId String -> String -> String
</> String
"direct-debits")