module Handler.Workflow.Definition.Instantiate
  ( getAWDInstantiateR, postAWDInstantiateR
  ) where

import Import
import Utils.Workflow
import Handler.Utils
import Handler.Utils.Workflow.Form

import Handler.Workflow.Instance.Form


getAWDInstantiateR, postAWDInstantiateR :: WorkflowScope' -> WorkflowDefinitionName -> Handler Html
getAWDInstantiateR = postAWDInstantiateR
postAWDInstantiateR wds' wdn = do
  (((_, instForm), instEncoding), act) <- runDB $ do
    wdId <- getKeyBy404 $ UniqueWorkflowDefinition wdn wds'
    form@((instRes, _), _) <- runFormPost $ workflowInstanceForm (Just wdId) Nothing

    act <- formResultMaybe instRes $ \WorkflowInstanceForm{..} -> do
      wifGraph' <- fromWorkflowGraphForm wifGraph
      let wifScope' = wifScope
            & over _wisTerm   unTermKey
            & over _wisSchool unSchoolKey
            & over _wisCourse (view _SqlKey)
      workflowInstanceGraph <- insertSharedWorkflowGraph wifGraph'
      instId <- insertUnique WorkflowInstance
        { workflowInstanceDefinition = Just wdId
        , workflowInstanceGraph
        , workflowInstanceScope = wifScope'
        , workflowInstanceName = wifName
        , workflowInstanceCategory = wifCategory
        }

      for_ instId $ \instId' -> iforM_ wifDescriptions $ \widLang (widTitle, widDesc) ->
        insert WorkflowInstanceDescription
          { workflowInstanceDescriptionInstance = instId'
          , workflowInstanceDescriptionLanguage = widLang
          , workflowInstanceDescriptionTitle = widTitle
          , workflowInstanceDescriptionDescription = widDesc
          }

      return . Just $ case instId of
        Nothing -> addMessageI Error MsgWorkflowInstanceCollision
        Just _ -> do
          addMessageI Success MsgWorkflowDefinitionInstantiated
          redirect AdminWorkflowInstanceListR
    
    return (form, act)

  forM_ act id

  let instWidget = wrapForm instForm def
        { formAction = Just . SomeRoute $ AdminWorkflowDefinitionR wds' wdn AWDInstantiateR
        , formEncoding = instEncoding
        }

  siteLayoutMsg MsgWorkflowDefinitionInstantiateTitle $ do
    setTitleI MsgWorkflowDefinitionInstantiateTitle

    instWidget
