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

module PayPal.Types where

import           Control.Monad.Error   (Error, noMsg, strMsg)
import           Data.Aeson.TH
import           Data.ByteString.Char8 as CBS
import           Data.IORef
import           Data.Text             as T
import           Network.HTTP.Conduit  (Manager)

import           PayPal.Types.Util     (Language (..))
import           PayPal.Util           (jsonUnderscore)

data PayPalConf = PayPalConf
            { paypalEndpoint :: String
            , paypalLanguage :: Language
            , paypalManager  :: Manager
            , paypalClientId :: CBS.ByteString
            , paypalSecret   :: CBS.ByteString
            , paypalToken    :: IORef Token
            }

data Token = Token
            { tokenScope       :: Text
            , tokenAccessToken :: Text
            , tokenTokenType   :: Text
            , tokenAppId       :: Text
            , tokenExpiresIn   :: Int
            } deriving (Show)

data PayPalFailure = BadRequest     (Maybe PayPalError)
                   | Unauthorized   (Maybe PayPalError)
                   | NotFound       (Maybe PayPalError)
                   | HttpFailure    (Maybe Text)
                   | OtherFailure   (Maybe Text)
                   deriving (Show, Eq)

data PayPalError = PayPalError
            { errorName            :: Text
            , errorDebugId         :: Text
            , errorMessage         :: Text
            , errorInformationLink :: Text
            , errorDetails         :: PayPalErrorDetails
            } deriving (Show, Eq)

data PayPalErrorDetails = PayPalErrorDetails
            { edetailsField :: Text
            , edetailsIssue :: Text
            } deriving (Show, Eq)


$(deriveJSON jsonUnderscore ''Token)
$(deriveJSON jsonUnderscore ''PayPalError)
$(deriveJSON jsonUnderscore ''PayPalErrorDetails)

----

instance Error PayPalFailure where
    noMsg  = OtherFailure Nothing
    strMsg = OtherFailure . Just . T.pack

----
