-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later

module Handler.Tutorial.New
  ( getCTutorialNewR, postCTutorialNewR
  ) where

import Import
import Handler.Utils
import Handler.Utils.Invitations
import Jobs.Queue

import qualified Data.Set as Set

import Handler.Tutorial.Form
import Handler.Tutorial.TutorInvite


getCTutorialNewR, postCTutorialNewR :: TermId -> SchoolId -> CourseShorthand -> Handler Html
getCTutorialNewR = postCTutorialNewR
postCTutorialNewR tid ssh csh = do
  Entity{entityKey=cid, entityVal=course} <- runDB . getBy404 $ TermSchoolCourseShort tid ssh csh -- TODO: use getKeyBy404 if was optimized to no longer retrieve the full entity from the DB anyway

  ((newTutResult, newTutWidget), newTutEnctype) <- runFormPost $ tutorialForm cid Nothing

  formResult newTutResult $ \TutorialForm{..} -> do
    insertRes <- runDBJobs $ do      
      now <- liftIO getCurrentTime
      term <- get404 $ course ^. _courseTerm
      insertRes <- insertUnique Tutorial
        { tutorialName            = tfName
        , tutorialCourse          = cid
        , tutorialType            = tfType
        , tutorialCapacity        = tfCapacity
        , tutorialRoom            = tfRoom
        , tutorialRoomHidden      = tfRoomHidden
        , tutorialTime            = tfTime
        , tutorialRegGroup        = tfRegGroup
        , tutorialRegisterFrom    = tfRegisterFrom
        , tutorialRegisterTo      = tfRegisterTo
        , tutorialDeregisterUntil = tfDeregisterUntil
        , tutorialLastChanged     = now
        , tutorialTutorControlled = tfTutorControlled
        , tutorialFirstDay        = fst $ occurrencesBounds term tfTime
        }
      whenIsJust insertRes $ \tutid -> do
        audit $ TransactionTutorialEdit tutid

        let (invites, adds) = partitionEithers $ Set.toList tfTutors
        insertMany_ $ map (Tutor tutid) adds
        memcachedByInvalidate AuthCacheTutorList $ Proxy @(Set UserId)
        sinkInvitationsF tutorInvitationConfig $ map (, tutid, (InvDBDataTutor, InvTokenDataTutor)) invites
      return insertRes
    case insertRes of
      Nothing -> addMessageI Error $ MsgTutorialNameTaken tfName
      Just _  -> do
        addMessageI Success $ MsgTutorialCreated tfName
        redirect $ CourseR tid ssh csh CTutorialListR

  let heading = prependCourseTitle tid ssh csh MsgTutorialNew

  siteLayoutMsg heading $ do
    setTitleI heading
    let
      newTutForm = wrapForm newTutWidget def
        { formMethod = POST
        , formAction = Just . SomeRoute $ CourseR tid ssh csh CTutorialNewR
        , formEncoding = newTutEnctype
        }
    $(widgetFile "tutorial-new")
