module Handler.Admin.Avs
  ( getAdminAvsR
  , postAdminAvsR  
  ) where

import Import
import qualified Control.Monad.State.Class as State
-- import Data.Aeson (encode)
import qualified Data.Text as Text
import qualified Data.Set  as Set

import Handler.Utils

import Utils.Avs


makeAvsPersonForm :: Maybe AvsPersonQuery -> Form AvsPersonQuery
makeAvsPersonForm tmpl = identifyForm FIDAvsPersonQuery . validateForm validateAvsPersonQuery $ \html -> 
  flip (renderAForm FormStandard) html $ AvsPersonQuery 
    <$> aopt textField (fslI MsgAvsCardNo)             (avsPersonQueryCardNo              <$> tmpl)
    <*> aopt textField (fslI MsgAvsFirstName)          (avsPersonQueryFirstName           <$> tmpl)
    <*> aopt textField (fslI MsgAvsLastName)           (avsPersonQueryLastName            <$> tmpl)
    <*> aopt textField (fslI MsgAvsInternalPersonalNo) (avsPersonQueryInternalPersonalNo  <$> tmpl)
    <*> aopt textField (fslI MsgAvsVersionNo)          (avsPersonQueryVersionNo           <$> tmpl)

validateAvsPersonQuery :: FormValidator AvsPersonQuery Handler ()
validateAvsPersonQuery = do 
  AvsPersonQuery{..} <- State.get
  guardValidation MsgAvsQueryEmpty $
    is _Just avsPersonQueryCardNo             ||
    is _Just avsPersonQueryFirstName          ||
    is _Just avsPersonQueryLastName           ||
    is _Just avsPersonQueryInternalPersonalNo ||
    is _Just avsPersonQueryVersionNo

makeAvsStatusForm :: Maybe AvsStatusQuery -> Form AvsStatusQuery
makeAvsStatusForm tmpl = identifyForm FIDAvsStatusQuery . validateForm validateAvsStatusQuery $ \html -> 
  flip (renderAForm FormStandard) html $
     parseAvsIds <$> areq textField (fslI MsgAvsCardNo) (unparseAvsIds <$> tmpl)
  where 
    parseAvsIds :: Text -> AvsStatusQuery
    parseAvsIds txt = AvsStatusQuery $ Set.fromList ids
      where         
        nonemptys = filter (not . Text.null) $ Text.strip <$> Text.split (==',') txt 
        ids = catMaybes $ readMay <$> nonemptys
    unparseAvsIds :: AvsStatusQuery -> Text 
    unparseAvsIds (AvsStatusQuery ids) = Text.intercalate ", " $ tshow <$> Set.toAscList ids 

validateAvsStatusQuery :: FormValidator AvsStatusQuery Handler ()
validateAvsStatusQuery = do 
  AvsStatusQuery ids <- State.get
  guardValidation (MsgAvsStatusQueryInvalid $ tshow ids) $ not (null ids)

getAdminAvsR, postAdminAvsR :: Handler Html
getAdminAvsR = postAdminAvsR
postAdminAvsR = do 
  AvsQuery{..} <- getsYesod $ view _appAvsQuery

  ((presult, pwidget), penctype) <- runFormPost $ makeAvsPersonForm Nothing

  let procFormPerson fr = do 
        res <- avsQueryPerson fr
        case res of 
          Left err -> return . Just $ tshow err
          Right jsn -> return . Just $ tshow jsn
  mbPerson <- formResultMaybe presult procFormPerson

  ((sresult, swidget), senctype) <- runFormPost $ makeAvsStatusForm Nothing
  let procFormStatus fr = do 
        res <- avsQueryStatus fr
        case res of 
          Left err -> return . Just $ tshow err 
          Right jsn -> return . Just $ tshow jsn         
  mbStatus <- formResultMaybe sresult procFormStatus

  actionUrl <- fromMaybe AdminAvsR <$> getCurrentRoute
  siteLayoutMsg MsgMenuAvs $ do
    setTitleI MsgMenuAvs
    let personForm = wrapForm pwidget def 
                      { formAction = Just $ SomeRoute actionUrl
                      , formEncoding = penctype
                      }
        statusForm = wrapForm swidget def 
                      { formAction = Just $ SomeRoute actionUrl
                      , formEncoding = senctype
                      }
    -- TODO: use i18nWidgetFile instead if this is to become permanent
    $(widgetFile "avs")  
