content: {-
   Copyright 2022-23, Juspay India Pvt Ltd
  
   This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
  
   as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program
  
   is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  
   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of
  
   the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
  -}
  
  module SharedLogic.CallBAPInternal where
  
  import API.Types.UI.MeterRide
  import qualified API.Types.UI.PickupInstructions as PickupInstructions
  import qualified Data.HashMap.Strict as HM
  import qualified Data.Text
  import Domain.Types.Ride as DRide
  import EulerHS.Types (EulerClient, client)
  import Kernel.External.Slack.Types
  import Kernel.Prelude
  import Kernel.Types.APISuccess
  import Kernel.Types.Id (Id)
  import Kernel.Utils.Common hiding (Error)
  import Kernel.Utils.Dhall (FromDhall)
  import qualified Kernel.Utils.Servant.Client as EC
  import Servant hiding (throwError)
  import Tools.Metrics (CoreMetrics)
  
  data FeedbackReq = FeedbackReq
    { rideId :: Id DRide.Ride,
      ratingValue :: Int,
      feedbackDetails :: Maybe Text
    }
    deriving (Generic, ToJSON, FromJSON, ToSchema)
  
  data AppBackendBapInternal = AppBackendBapInternal
    { name :: Text,
      url :: BaseUrl,
      apiKey :: Text,
      internalKey :: Text
    }
    deriving (Generic, FromDhall)
  
  type FeedBackAPI =
    "internal"
      :> "feedback"
      :> "rateRide"
      :> Header "token" Text
      :> ReqBody '[JSON] FeedbackReq
      :> Post '[JSON] APISuccess
  
  feedbackClient :: Maybe Text -> FeedbackReq -> EulerClient APISuccess
  feedbackClient = client (Proxy @FeedBackAPI)
  
  feedbackApi :: Proxy FeedBackAPI
  feedbackApi = Proxy
  
  feedback ::
    ( MonadFlow m,
      CoreMetrics m,
      HasFlowEnv m r '["internalEndPointHashMap" ::: HM.HashMap BaseUrl BaseUrl]
    ) =>
    Text ->
    BaseUrl ->
    FeedbackReq ->
    m APISuccess
  feedback apiKey internalUrl request = do
    internalEndPointHashMap <- asks (.internalEndPointHashMap)
    EC.callApiUnwrappingApiError (identity @Error) Nothing (Just "BAP_INTERNAL_API_ERROR") (Just internalEndPointHashMap) internalUrl (feedbackClient (Just apiKey) request) "FeedBack" feedbackApi
  
  type StopEventsAPI =
    "internal"
      :> "stopEvents"
      :> "stop"
      :> Header "token" Text
      :> ReqBody '[JSON] StopEventsReq
      :> Post '[JSON] APISuccess
  
  data StopEventsReq = StopEventsReq
    { action :: StopAction,
      rideId :: Id DRide.Ride,
      stopOrder :: Int,
      waitingTimeStart :: UTCTime,
      waitingTimeEnd :: Maybe UTCTime
      -- stopId :: Id DRide.Stop
    }
    deriving (Generic, ToJSON, FromJSON, ToSchema)
  
  data StopAction = Depart | Arrive
    deriving (Generic, ToJSON, FromJSON, ToSchema)
  
  stopEventsClient :: Maybe Text -> StopEventsReq -> EulerClient APISuccess
  stopEventsClient = client (Proxy @StopEventsAPI)
  
  stopEventsApi :: Proxy StopEventsAPI
  stopEventsApi = Proxy
  
  stopEvents ::
    ( MonadFlow m,
      CoreMetrics m,
      HasFlowEnv m r '["internalEndPointHashMap" ::: HM.HashMap BaseUrl BaseUrl]
    ) =>
    Text ->
    BaseUrl ->
    StopEventsReq ->
    m APISuccess
  stopEvents apiKey internalUrl request = do
    internalEndPointHashMap <- asks (.internalEndPointHashMap)
    EC.callApiUnwrappingApiError (identity @Error) Nothing (Just "BAP_INTERNAL_API_ERROR") (Just internalEndPointHashMap) internalUrl (stopEventsClient (Just apiKey) request) "StopEvents" stopEventsApi
  
  -- manually added this for BAP internal API generated by DSL in rider side. (request types is same so didn't had to create one here)
  type MeterRideAddDestinationAPI =
    "internal"
      :> Capture "bppRideId" Text
      :> "addDestination"
      :> Header "token" Text
      :> ReqBody '[JSON] MeterRideAddDestinationReq
      :> Post '[JSON] APISuccess
  
  meterRideAddDestinationClient :: Text -> Maybe Text -> MeterRideAddDestinationReq -> EulerClient APISuccess
  meterRideAddDestinationClient = client (Proxy @MeterRideAddDestinationAPI)
  
  meterRideAddDestinationAPI :: Proxy MeterRideAddDestinationAPI
  meterRideAddDestinationAPI = Proxy
  
  meterRideAddDestination ::
    ( MonadFlow m,
      CoreMetrics m,
      HasFlowEnv m r '["internalEndPointHashMap" ::: HM.HashMap BaseUrl BaseUrl]
    ) =>
    Text ->
    BaseUrl ->
    Text ->
    MeterRideAddDestinationReq ->
    m APISuccess
  meterRideAddDestination apiKey internalUrl rideId request = do
    internalEndPointHashMap <- asks (.internalEndPointHashMap)
    EC.callApiUnwrappingApiError (identity @Error) Nothing (Just "BAP_INTERNAL_API_ERROR") (Just internalEndPointHashMap) internalUrl (meterRideAddDestinationClient rideId (Just apiKey) request) "StopEvents" meterRideAddDestinationAPI
  
  type GetCustomerReferralInfoAPI =
    "internal"
      :> "getCustomerInfo"
      :> Header "token" Data.Text.Text
      :> ReqBody '[JSON] SendRecietRequest
      :> Get '[JSON] CustomerInfoResponse
  
  data CustomerInfoResponse = CustomerInfoResponse
    { alreadyReferred :: Maybe Bool,
      isMultipleDeviceIdExist :: Maybe Bool
    }
    deriving (Generic, ToJSON, FromJSON)
  
  getCustomerReferralInfoClient :: Maybe Text -> SendRecietRequest -> EulerClient CustomerInfoResponse
  getCustomerReferralInfoClient = client (Proxy @GetCustomerReferralInfoAPI)
  
  getCustomerReferralInfoAPI :: Proxy GetCustomerReferralInfoAPI
  getCustomerReferralInfoAPI = Proxy
  
  getCustomerReferralInfo ::
    ( MonadFlow m,
      CoreMetrics m,
      HasFlowEnv m r '["internalEndPointHashMap" ::: HM.HashMap BaseUrl BaseUrl]
    ) =>
    Text ->
    BaseUrl ->
    SendRecietRequest ->
    m CustomerInfoResponse
  getCustomerReferralInfo apiKey internalUrl request = do
    internalEndPointHashMap <- asks (.internalEndPointHashMap)
    EC.callApiUnwrappingApiError (identity @Error) Nothing (Just "BAP_INTERNAL_API_ERROR") (Just internalEndPointHashMap) internalUrl (getCustomerReferralInfoClient (Just apiKey) request) "StopEvents" getCustomerReferralInfoAPI
  
  type GetInsuranceInfoAPI =
    "internal"
      :> "insurance"
      :> Capture "rideId" Text
      :> Header "token" Text
      :> Get '[JSON] InsuranceAPIEntity
  
  data InsuranceAPIEntity = InsuranceAPIEntity
    { certificateUrl :: Maybe Text,
      plan :: Maybe Text,
      policyId :: Maybe Text,
      policyNumber :: Maybe Text,
      message :: Text
    }
    deriving (Generic, ToJSON, FromJSON, ToSchema)
  
  getInsuranceInfo ::
    ( MonadFlow m,
      CoreMetrics m,
      HasFlowEnv m r '["internalEndPointHashMap" ::: HM.HashMap BaseUrl BaseUrl]
    ) =>
    Text ->
    BaseUrl ->
    Text ->
    m InsuranceAPIEntity
  getInsuranceInfo apiKey internalUrl rideId = do
    internalEndPointHashMap <- asks (.internalEndPointHashMap)
    EC.callApiUnwrappingApiError (identity @Error) Nothing (Just "BAP_INTERNAL_API_ERROR") (Just internalEndPointHashMap) internalUrl (getInsuranceInfoClient rideId (Just apiKey)) "GetInsuranceInfo" getInsuranceInfoAPI
  
  getInsuranceInfoClient :: Text -> Maybe Text -> EulerClient InsuranceAPIEntity
  getInsuranceInfoClient = client (Proxy @GetInsuranceInfoAPI)
  
  getInsuranceInfoAPI :: Proxy GetInsuranceInfoAPI
  getInsuranceInfoAPI = Proxy
  
  type RideSearchExpiredAPI =
    "internal"
      :> "rideSearchExpired"
      :> Header "token" Text
      :> ReqBody '[JSON] RideSearchExpiredReq
      :> Post '[JSON] APISuccess
  
  newtype RideSearchExpiredReq = RideSearchExpiredReq
    {transactionId :: Text}
    deriving (Generic, ToJSON, FromJSON)
  
  rideSearchExpiredClient :: Maybe Text -> RideSearchExpiredReq -> EulerClient APISuccess
  rideSearchExpiredClient = client (Proxy @RideSearchExpiredAPI)
  
  rideSearchExpiredAPI :: Proxy RideSearchExpiredAPI
  rideSearchExpiredAPI = Proxy
  
  rideSearchExpired ::
    ( MonadFlow m,
      CoreMetrics m,
      HasFlowEnv m r '["internalEndPointHashMap" ::: HM.HashMap BaseUrl BaseUrl]
    ) =>
    Text ->
    BaseUrl ->
    RideSearchExpiredReq ->
    m APISuccess
  rideSearchExpired apiKey internalUrl request = do
    logInfo "BPP handle rideSearchExpired callBAPInternal"
    internalEndPointHashMap <- asks (.internalEndPointHashMap)
    EC.callApiUnwrappingApiError (identity @Error) Nothing (Just "BAP_INTERNAL_API_ERROR") (Just internalEndPointHashMap) internalUrl (rideSearchExpiredClient (Just apiKey) request) "rideSearchExpired" rideSearchExpiredAPI
  
  type GetPickupInstructionsAPI =
    "internal"
      :> Capture "rideId" Text
      :> "pickupInstructions"
      :> Header "token" Text
      :> Get '[JSON] PickupInstructions.PickupInstructionResp
  
  getPickupInstructionsClient :: Text -> Maybe Text -> EulerClient PickupInstructions.PickupInstructionResp
  getPickupInstructionsClient = client (Proxy @GetPickupInstructionsAPI)
  
  getPickupInstructionsAPI :: Proxy GetPickupInstructionsAPI
  getPickupInstructionsAPI = Proxy
  
  getPickupInstructions ::
    ( MonadFlow m,
      CoreMetrics m,
      HasFlowEnv m r '["internalEndPointHashMap" ::: HM.HashMap BaseUrl BaseUrl]
    ) =>
    Text ->
    BaseUrl ->
    Text ->
    m PickupInstructions.PickupInstructionResp
  getPickupInstructions apiKey internalUrl rideId = do
    logInfo $ "CallBAPInternal: Calling BAP internal API for pickup instructions, rideId: " <> rideId
    internalEndPointHashMap <- asks (.internalEndPointHashMap)
    EC.callApiUnwrappingApiError (identity @Error) Nothing (Just "BAP_INTERNAL_API_ERROR") (Just internalEndPointHashMap) internalUrl (getPickupInstructionsClient rideId (Just apiKey)) "GetPickupInstructions" getPickupInstructionsAPI
  