content: {-# LANGUAGE DeriveGeneric #-}
  {-# LANGUAGE OverloadedStrings #-}
  {-# OPTIONS_GHC -Wno-orphans #-}
  
  module Domain.Types.Extra.RiderConfig where
  
  import Data.Aeson
  import Data.Aeson.Types
  import Data.ByteString (ByteString)
  import qualified Data.HashMap.Strict as HM
  import Data.Hashable
  import qualified Database.Beam as B
  import Database.Beam.Backend
  import Database.Beam.Postgres
  import Database.PostgreSQL.Simple.FromField (FromField (fromField))
  import qualified Database.PostgreSQL.Simple.FromField as DPSF
  import qualified Domain.Types.ServiceTierType
  import Kernel.Prelude hiding (error)
  import qualified Tools.Beam.UtilsTH
  import Prelude
  
  data AppletKey = SosAppletID | RentalAppletID | UnattendedTicketAppletID | PostRideSafetyCheckAppletID deriving (Show, Read, Eq, Ord, Generic)
  
  instance Hashable AppletKey
  
  -- Central conversion functions from AppletKey to Text and vice versa
  appletKeyToString :: AppletKey -> Text
  appletKeyToString = \case
    SosAppletID -> "SosAppletID"
    RentalAppletID -> "RentalAppletID"
    UnattendedTicketAppletID -> "UnattendedTicketAppletID"
    PostRideSafetyCheckAppletID -> "PostRideSafetyCheckAppletID"
  
  stringToAppletKey :: Text -> Maybe AppletKey
  stringToAppletKey = \case
    "SosAppletID" -> Just SosAppletID
    "RentalAppletID" -> Just RentalAppletID
    "UnattendedTicketAppletID" -> Just UnattendedTicketAppletID
    "PostRideSafetyCheckAppletID" -> Just PostRideSafetyCheckAppletID
    _ -> Nothing
  
  instance ToJSON AppletKey where
    toJSON = String . appletKeyToString
  
  instance FromJSON AppletKey where
    parseJSON = withText "AppletKey" $ maybe (fail "Invalid AppletKey") pure . stringToAppletKey
  
  instance ToJSONKey AppletKey where
    toJSONKey = toJSONKeyText appletKeyToString
  
  instance FromJSONKey AppletKey where
    fromJSONKey = FromJSONKeyText $ \t -> maybe (error "Unknown AppletKey") id (stringToAppletKey t)
  
  data ExotelMapping = ExotelMapping
    { exotelMap :: HM.HashMap AppletKey Text
    }
    deriving (Show, Read, Eq, Ord, Generic)
  
  fromFieldExotel ::
    DPSF.Field ->
    Maybe ByteString ->
    DPSF.Conversion ExotelMapping
  fromFieldExotel f mbValue = do
    value <- fromField f mbValue
    case fromJSON value of
      Success a -> pure a
      _ -> DPSF.returnError DPSF.ConversionFailed f "Conversion failed"
  
  instance HasSqlValueSyntax be Value => HasSqlValueSyntax be ExotelMapping where
    sqlValueSyntax = sqlValueSyntax . toJSON
  
  instance FromField ExotelMapping where
    fromField = fromFieldExotel
  
  instance BeamSqlBackend be => B.HasSqlEqualityCheck be ExotelMapping
  
  instance FromBackendRow Postgres ExotelMapping
  
  instance ToJSON ExotelMapping where
    toJSON = \case ExotelMapping m -> object ["exotelMap" .= m]
  
  instance FromJSON ExotelMapping where
    parseJSON = withObject "ExotelMapping" $ \v -> ExotelMapping <$> v .: "exotelMap"
  
  data VehicleServiceTierOrderConfig = VehicleServiceTierOrderConfig {orderArray :: [Domain.Types.ServiceTierType.ServiceTierType], vehicle :: Domain.Types.ServiceTierType.ServiceTierType}
    deriving (Generic, Show, ToJSON, FromJSON, ToSchema, Eq, Read, Ord)
  
  instance HasSqlValueSyntax be String => HasSqlValueSyntax be VehicleServiceTierOrderConfig where
    sqlValueSyntax = autoSqlValueSyntax
  
  $(Tools.Beam.UtilsTH.mkBeamInstancesForList ''VehicleServiceTierOrderConfig)
  