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

module Handler.ExternalExam.Users
  ( getEEUsersR, postEEUsersR
  ) where

import Import

import Database.Persist.Sql (deleteWhereCount, updateWhereCount)

import Handler.Utils

import Handler.Utils.ExternalExam.Users

getEEUsersR, postEEUsersR :: TermId -> SchoolId -> CourseName -> ExamName -> Handler Html
getEEUsersR = postEEUsersR
postEEUsersR tid ssh coursen examn = do
  (usersResult, table) <- runDB $ do
    eExam <- getBy404 $ UniqueExternalExam tid ssh coursen examn
    (usersResult, examUsersTable) <- makeExternalExamUsersTable EEUMUsers eExam

    let
      editResults results changeList = fmap getSum . flip foldMapM results $ \result -> do
        now <- liftIO getCurrentTime
        mExtExamRes <- get result
        nrEdit <- updateWhereCount
          [ ExternalExamResultId ==. result ]
          (changeList <> [ ExternalExamResultLastChanged =. now ])
        if
          | Just ExternalExamResult{..} <- mExtExamRes -> do
            forM_ [1..nrEdit] $ const $ audit $ TransactionExternalExamResultEdit externalExamResultExam externalExamResultUser
            return $ Sum nrEdit
          | otherwise -> return mempty

    usersResult' <- formResultMaybe usersResult $ \case
      (ExternalExamUserEditOccurrenceData occ, selectedResults) -> do
        nrEdited <- editResults selectedResults
          [ ExternalExamResultTime =. occ ]
        return . Just $ do
          addMessageI Success $ MsgExternalExamOccurrenceEdited nrEdited
          redirect $ EExamR tid ssh coursen examn EEGradesR

      (ExternalExamUserEditResultData examResult, selectedResults) -> do
        nrEdited <- editResults selectedResults
          [ ExternalExamResultResult =. examResult ]
        return . Just $ do
          addMessageI Success $ MsgExternalExamResultEdited nrEdited
          redirect $ EExamR tid ssh coursen examn EEGradesR

      (ExternalExamUserDeleteData, selectedResults) -> do
        nrDeleted <- fmap getSum . flip foldMapM selectedResults $ \selectedResult -> do
          mExtExamRes <- get selectedResult
          nrDel <- deleteWhereCount [ ExternalExamResultId ==. selectedResult ]
          if
            | Just ExternalExamResult{..} <- mExtExamRes -> do
              forM_ [1..nrDel] $ const $ audit $ TransactionExternalExamResultDelete externalExamResultExam externalExamResultUser
              return $ Sum nrDel
            | otherwise -> return mempty
        return . Just $ do
          addMessageI Success $ MsgExternalExamUserDeleted nrDeleted
          redirect $ EExamR tid ssh coursen examn EEGradesR
      _other -> return Nothing

    return (usersResult', examUsersTable)

  whenIsJust usersResult join

  siteLayoutMsg (MsgExternalExamUsers coursen examn) $ do
    setTitleI MsgBreadcrumbExternalExamUsers
    table
