{-# LANGUAGE DeriveDataTypeable, OverloadedStrings, FlexibleContexts, ConstraintKinds #-}
-- | refunds on payins and transfers
module Web.MangoPay.Refunds where

import Web.MangoPay.Monad
import Web.MangoPay.Payins
import Web.MangoPay.Types
import Web.MangoPay.Users
import Web.MangoPay.Wallets

import Data.Text
import Data.Typeable (Typeable)
import Data.Aeson
import Data.Time.Clock.POSIX (POSIXTime)
import Control.Applicative

-- | refund a transfer
refundTransfer ::  (MPUsableMonad m) => TransferId -> AnyUserId -> AccessToken -> MangoPayT m Refund
refundTransfer tid authId at= do
    url<-getClientURLMultiple ["/transfers/",tid,"/refunds"]
    postExchange url (Just at) (RefundRequest authId Nothing Nothing)

-- | refund a pay-in
refundPayin ::  (MPUsableMonad m) => AnyPayinId -> RefundRequest -> AccessToken -> MangoPayT m Refund
refundPayin pid rr at= do
    url<-getClientURLMultiple ["/payins/",pid,"/refunds"]
    postExchange url (Just at) rr

-- | fetch a refund from its Id
fetchRefund :: (MPUsableMonad m) => RefundId -> AccessToken -> MangoPayT m Refund
fetchRefund = fetchGeneric "/refunds/"

-- | refund request
data RefundRequest=RefundRequest{
  rrAuthorId :: AnyUserId -- ^ The user Id of the author
  ,rrDebitedFunds :: Maybe Amount -- ^ Strictly positive amount. In cents.
  ,rrFees :: Maybe Amount -- ^ In cents
  }deriving (Show,Eq,Ord,Typeable)

-- | to json as per MangoPay format
instance ToJSON RefundRequest  where
    toJSON rr=object ["AuthorId" .= rrAuthorId rr,"DebitedFunds" .= rrDebitedFunds rr,
      "Fees" .= rrFees rr]


-- | id of a refund
type RefundId = Text

-- | refund of a transfer
data Refund=Refund{
  rId :: RefundId -- ^ Id of the refund
  ,rCreationDate :: POSIXTime
  ,rTag :: Maybe Text -- ^ Custom data
  ,rAuthorId :: AnyUserId -- ^ The user Id of the author
  ,rDebitedFunds :: Amount -- ^ Strictly positive amount. In cents.
  ,rFees :: Amount -- ^ In cents
  ,rCreditedFunds :: Amount -- ^ In cents
  ,rStatus  :: TransferStatus
  ,rResultCode  :: Text -- ^ The transaction result code
  ,rResultMessage :: Maybe Text -- ^ The transaction result Message
  ,rExecutionDate :: POSIXTime
  ,rType :: TransactionType
  ,rNature :: TransactionNature
  ,rCreditedUserId :: Maybe AnyUserId -- ^ Id of the user owner of the credited wallet
  ,rInitialTransactionId  :: TransactionId -- ^ Id of the transaction being refunded
  ,rInitialTransactionType  :: TransactionType -- ^  The type of the transaction before being refunded (PayIn, Refund)
  ,rDebitedWalletId :: WalletId -- ^ The Id of the debited Wallet
  ,rCreditedWalletId  :: Maybe WalletId -- ^ The Id of the credited Wallet
  } deriving (Show,Eq,Ord,Typeable)

-- | from json as per MangoPay format
instance FromJSON Refund where
        parseJSON (Object v) =Refund <$>
                         v .: "Id" <*>
                         v .: "CreationDate" <*>
                         v .:? "Tag" <*>
                         v .: "AuthorId" <*>
                         v .: "DebitedFunds" <*>
                         v .: "Fees" <*>
                         v .: "CreditedFunds" <*>
                         v .: "Status" <*>
                         v .: "ResultCode" <*>
                         v .:? "ResultMessage" <*>
                         v .: "ExecutionDate" <*>
                         v .: "Type" <*>
                         v .: "Nature" <*>
                         v .:? "CreditedUserId" <*>
                         v .: "InitialTransactionId" <*>
                         v .: "InitialTransactionType" <*>
                         v .: "DebitedWalletId" <*>
                         v .:? "CreditedWalletID"
        parseJSON _=fail "Refund"