module Gargantext.Components.Bootstrap.BaseModal (baseModal) where

import Gargantext.Prelude

import DOM.Simple (Window)
import Data.Foldable (intercalate)
import Effect (Effect)
import Effect.Uncurried (EffectFn2, runEffectFn2)
import Gargantext.Utils (nbsp, (?))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T

foreign import _addClassName :: EffectFn2 Window String Unit
foreign import _removeClassName :: EffectFn2 Window String Unit

type Props =
  ( isVisibleBox :: T.Box Boolean
  | Options
  )

type Options =
  ( id :: String
  , title :: String
  , hasBackground :: Boolean
  , hasCollapsibleBackground :: Boolean
  )

options :: Record Options
options =
  { id: ""
  , title: ""
  , hasBackground: true
  , hasCollapsibleBackground: true
  }

componentName :: String
componentName = "b-modal"

vendorName :: String
vendorName = "modal"

baseModal :: forall r. R2.OptComponent Options Props r
baseModal = R2.optComponent component options

component :: R.Component Props
component = R.hooksComponent componentName cpt where
  cpt { isVisibleBox
      , id
      , title
      , hasBackground
      , hasCollapsibleBackground
      } children = do
    -- State
    isVisible <- R2.useLive' isVisibleBox

    -- Hooks
    -- R.useEffect1' isVisible $
      -- (isVisible ? addClassName $ removeClassName) window "modal-open"

    -- Computed
    let
      className = intercalate " "
        -- Component
        [ componentName
        , isVisible ?
            componentName <> "--visible" $
            componentName <> "--hidden"
        -- Vendor
        , vendorName
        ]

      hasHeader = not $ eq title ""

    -- Render
    R.createPortal
      [
        H.div
        { id
        , className
        , role: "dialog"
        , data: { show: true }
        }
        [
          R2.if' (hasBackground) $
            H.div
            { className: intercalate " "
                [ componentName <> "__overlay"
                , hasCollapsibleBackground ?
                    componentName <> "__overlay--collapsible" $
                    ""
                ]
            , on: { click: hasCollapsibleBackground ?
                      toggle isVisibleBox $
                      const $ pure unit
                  }
            }
            [ H.text $ nbsp 1 ]
        ,
          H.div
          { className: "modal-dialog modal-lg"
          , role: "document"
          }
          [
            H.div
            { className: intercalate " "
                [ componentName <> "__content"
                , vendorName <> "-content"
                ]
            }
            [
              R2.if' (hasHeader) $
                H.div
                { className: intercalate " "
                    [ componentName <> "__header"
                    , vendorName <> "-header"
                    ]
                }
                [
                  H.div
                  { className: componentName <> "__header__content" }
                  [ H.text title ]
                ,
                  H.button
                  { type: "button"
                  , className: "close"
                  , data: { dismiss: "modal" }
                  }
                  [
                    H.a
                    { on: { click: toggle isVisibleBox }
                    , className: "btn fa fa-times" }
                    []
                  ]
                ]
            ,
              H.div
              { className: "modal-body" }
              children
            ]
          ]
        ]
      ]
      <$> R2.getPortalHost


toggle :: forall event. T.Box Boolean -> event -> Effect Unit
toggle box _ = T.modify_ not box

addClassName :: Window -> String -> Effect Unit
addClassName = runEffectFn2 _addClassName

removeClassName :: Window -> String -> Effect Unit
removeClassName = runEffectFn2 _removeClassName