{-|
Module      : Gargantext.API.Node.Contact
Description :
Copyright   : (c) CNRS, 2017-Present
License     : AGPL + CECILL v3
Maintainer  : team@gargantext.org
Stability   : experimental
Portability : POSIX

-}

{-# LANGUAGE ConstraintKinds      #-}
{-# LANGUAGE ScopedTypeVariables  #-}
{-# LANGUAGE TypeFamilies         #-}


module Gargantext.API.Node.Contact
      where

import Conduit ( yield )
import Control.Monad.Catch (MonadCatch)
import Gargantext.API.Admin.Auth.Types ( AuthenticatedUser(AuthenticatedUser) )
import Gargantext.API.Admin.EnvTypes (Env)
import Gargantext.API.Errors.Types ( BackendInternalError )
import Gargantext.API.Node ( nodeNodeAPI )
import Gargantext.API.Node.Contact.Types (AddContactParams(..))
import Gargantext.API.Prelude (GargM, simuLogs)
import Gargantext.API.Routes.Named.Contact qualified as Named
import Gargantext.API.Worker (serveWorkerAPI)
import Gargantext.Core (Lang(..))
import Gargantext.Core.Text.Terms (TermType(..))
import Gargantext.Core.Types.Individu (User(..))
import Gargantext.Core.Worker.Jobs.Types qualified as Jobs
import Gargantext.Database.Action.Flow (flow)
import Gargantext.Database.Action.Flow.Types (FlowCmdM)
import Gargantext.Database.Admin.Types.Hyperdata.Contact ( HyperdataContact, hyperdataContact )
import Gargantext.Database.Admin.Types.Hyperdata.Corpus ( HyperdataAnnuaire(..) )
import Gargantext.Database.Admin.Types.Node ( CorpusId, NodeId )
import Gargantext.Database.Query.Tree.Root (MkCorpusUser(MkCorpusUserNormalCorpusIds))
import Gargantext.Prelude (($), Maybe(..))
import Gargantext.Utils.Jobs.Monad (MonadJobStatus(..))
import Servant
import Servant.Server.Generic (AsServerT)


contactAPI :: AuthenticatedUser -> CorpusId -> Named.ContactAPI (AsServerT (GargM Env BackendInternalError))
contactAPI authUser@(AuthenticatedUser userNodeId _userUserId) cid = Named.ContactAPI
  { contactAsyncAPI = apiAsync (RootId userNodeId) cid
  , getContactEp    = nodeNodeAPI (Proxy :: Proxy HyperdataContact) authUser cid
  }

----------------------------------------------------------------------
apiAsync :: User -> NodeId -> Named.ContactAsyncAPI (AsServerT (GargM Env BackendInternalError))
apiAsync u nId = Named.ContactAsyncAPI {
    addContactAsyncEp = serveWorkerAPI $ \p ->
        Jobs.AddContact { _ac_args = p
                        , _ac_node_id = nId
                        , _ac_user = u }
    }

addContact :: (FlowCmdM env err m, MonadJobStatus m, MonadCatch m)
    => User
    -> NodeId
    -> AddContactParams
    -> JobHandle m
    -> m ()
addContact u nId (AddContactParams fn ln) jobHandle = do

  markStarted 2 jobHandle
  _ <- flow (Nothing :: Maybe HyperdataAnnuaire) (MkCorpusUserNormalCorpusIds u [nId]) (Multi EN) Nothing (1, yield $ hyperdataContact fn ln) jobHandle

  markComplete jobHandle
addContact _uId _nId _p jobHandle = do
  simuLogs jobHandle 10

