module Gargantext.Components.DocsTable.DocumentFormCreation
  ( documentFormCreation
  , FormData
  ) where

import Gargantext.Prelude

import DOM.Simple.Console (log3)
import Data.Either (Either(..))
import Data.Foldable (foldl, intercalate)
import Effect (Effect)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Hooks.FormValidation (VForm, useFormValidation)
import Gargantext.Hooks.FormValidation.Unboxed as FV
import Gargantext.Hooks.StateRecord (useStateRecord)
import Gargantext.Utils (nbsp, (?))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Record (merge)
import Record.Extra (pick)

type Props =
  ( callback  :: Record FormData -> Effect Unit
  , status    :: ComponentStatus
  | Options
  )

type Options = ( | FormData )

options :: Record Options
options = merge {} defaultData

documentFormCreation :: forall r. R2.OptLeaf Options Props r
documentFormCreation = R2.optLeaf component options

component :: R.Component Props
component = R.hooksComponent "documentFormCreation" cpt where
  cpt props _ = do
    -- Hooks
    { state, bindStateKey } <- useStateRecord (pick props :: Record FormData)
    fv <- useFormValidation

    -- @onSubmit: exec whole form validation and execute callback
    onSubmit <- pure $ do

      result <- fv.try (\_ -> documentFormValidation state)

      case result of
        Left err -> log3 "document form validation error" state err
        Right _  -> props.callback state

    -- Render
    pure $

      H.form
      { className: "document-form-creation" }
      [
        -- Title
        H.div
        { className: intercalate " "
            [ "form-group"
            , (fv.hasError' "title") ?
                "form-group--error" $
                mempty
            ]
        }
        [
          H.div { className: "form-group__label" }
          [
            H.label {} [ H.text "Title" ]
          ]
        ,
          H.div { className: "form-group__field" }
          [
            B.formInput $
              bindStateKey "title"
          ,
            R2.if' (fv.hasError' "title") $
              H.div { className: "form-group__error" }
              [ H.text "Please enter a title" ]
          ]
        ]
      ,
        -- Source
        H.div
        { className: intercalate " "
            [ "form-group"
            , (fv.hasError' "source") ?
                "form-group--error" $
                mempty
            ]
        }
        [
          H.div { className: "form-group__label" }
          [
            H.label {} [ H.text "Source" ]
          ]
        ,
          H.div { className: "form-group__field" }
          [
            B.formInput $
              bindStateKey "source"
          ,
            R2.if' (fv.hasError' "source") $
              H.div { className: "form-group__error" }
              [ H.text "Please enter a source" ]
          ]
        ]
      ,
        -- Authors
        H.div
        { className: intercalate " "
            [ "form-group"
            , (fv.hasError' "authors") ?
                "form-group--error" $
                mempty
            ]
        }
        [
          H.div { className: "form-group__label" }
          [
            H.label {} [ H.text "Authors" ]
          ]
        ,
          H.div { className: "form-group__field" }
          [
            B.formInput $
            { placeholder: "ex: author1, author2, …"
            } `merge` bindStateKey "authors"
          ,
            R2.if' (fv.hasError' "authors") $
              H.div { className: "form-group__error" }
              [ H.text "Please enter at least one author" ]
          ]
        ]
      ,
        -- Abstract
        H.div
        { className: intercalate " "
            [ "form-group"
            ]
        }
        [
          H.div { className: "form-group__label" }
          [
            H.label {} [ H.text $ "Abstract" <> nbsp 1 ]
          ,
            H.span
            { className: "form-group__label--sub" }
            [ H.text "optional" ]
          ]
        ,
          H.div { className: "form-group__field" }
          [
            B.formTextarea $
            bindStateKey "abstract"
          ]
        ]
      ,
        -- Submit
        H.div { className: "document-form-creation__submit" }
        [
          B.button
          { callback: \_ -> onSubmit
          , status: props.status == Deferred ? Deferred $ Enabled
          , variant: "primary"
          , type: "submit"
          , block: true
          }
          [ H.text "Add" ]
        ]
      ]

type FormData =
  ( title     :: String
  , source    :: String
  , authors   :: String
  , abstract  :: String
  )

defaultData :: Record FormData
defaultData =
  { title     : ""
  , source    : ""
  , authors   : ""
  , abstract  : ""
  }

documentFormValidation :: Record FormData -> Effect VForm
documentFormValidation r = foldl append mempty rules
  where
    rules =
      [ FV.nonEmpty "title" r.title
      , FV.nonEmpty "source" r.source
      , FV.nonEmpty "authors" r.authors
      ]