-- | Lovelaces

{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE UndecidableInstances #-}

module Blockfrost.Types.Shared.Ada
  ( Lovelaces
  ) where

import Data.Aeson (Encoding, FromJSON (..), ToJSON (..), Value)
import Data.Proxy (Proxy (..))
import Data.Text (Text)
import GHC.TypeLits (KnownSymbol)
import qualified Money
import Servant.Docs (ToSample (..), samples)

type Lovelaces = Money.Discrete "ADA" "lovelace"

instance (KnownSymbol cur, Money.GoodScale sc) => ToSample (Money.Discrete' cur sc) where
  toSamples :: Proxy (Discrete' cur sc) -> [(Text, Discrete' cur sc)]
toSamples Proxy (Discrete' cur sc)
_ = forall a. [a] -> [(Text, a)]
samples forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall (scale :: (Natural, Natural)) (currency :: Symbol).
GoodScale scale =>
Integer -> Discrete' currency scale
Money.discrete [
      Integer
592661
    , Integer
3592661
    , Integer
1337
    , Integer
42
    , Integer
0
    , Integer
3000100
    ]

lovelaceDecimalConfig :: Money.DecimalConf
lovelaceDecimalConfig :: DecimalConf
lovelaceDecimalConfig =
  DecimalConf
Money.defaultDecimalConf
    { decimalConf_digits :: Word8
Money.decimalConf_digits = Word8
0
    , decimalConf_scale :: Scale
Money.decimalConf_scale =
        forall (proxy :: (Natural, Natural) -> *)
       (scale :: (Natural, Natural)).
GoodScale scale =>
proxy scale -> Scale
Money.scale (forall {k} (t :: k). Proxy t
Proxy @(Money.UnitScale "ADA" "lovelace"))
    }

instance ToJSON (Money.Discrete' "ADA" '(1_000_000, 1)) where
  toJSON :: Discrete' "ADA" '(1000000, 1) -> Value
toJSON =
      (forall a. ToJSON a => a -> Value
toJSON :: Text -> Value)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (scale :: (Natural, Natural)) (currency :: Symbol).
GoodScale scale =>
DecimalConf -> Approximation -> Discrete' currency scale -> Text
Money.discreteToDecimal
        DecimalConf
lovelaceDecimalConfig
        Approximation
Money.Round
  toEncoding :: Discrete' "ADA" '(1000000, 1) -> Encoding
toEncoding =
      (forall a. ToJSON a => a -> Encoding
toEncoding :: Text -> Encoding)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (scale :: (Natural, Natural)) (currency :: Symbol).
GoodScale scale =>
DecimalConf -> Approximation -> Discrete' currency scale -> Text
Money.discreteToDecimal
        DecimalConf
lovelaceDecimalConfig
        Approximation
Money.Round

instance FromJSON (Money.Discrete' "ADA" '(1000000, 1)) where
  parseJSON :: Value -> Parser (Discrete' "ADA" '(1000000, 1))
parseJSON Value
v = do
     Text
t <- forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
     forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        (forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Can't parse Discrete ADA value")
        forall (f :: * -> *) a. Applicative f => a -> f a
pure
        (forall (scale :: (Natural, Natural)) (currency :: Symbol).
GoodScale scale =>
DecimalConf -> Text -> Maybe (Discrete' currency scale)
Money.discreteFromDecimal DecimalConf
lovelaceDecimalConfig Text
t)