open Dash.NET
open System

let dslLayout = 
    Html.div [
        Attr.children [
            Html.button [ Attr.id "button_1"; Attr.children "Execute callbacks" ]
            Html.div [ Attr.id "output_1"; Attr.children "callback not executed" ]
            Html.div [ Attr.id "output_2"; Attr.children "callback not executed" ]
            Html.div [ Attr.id "output_3"; Attr.children "callback not executed" ]
            Html.div [ Attr.id "output_4"; Attr.children "callback not executed" ]
        ]
    ]

let updateFirstCallback =
    Callback.multiOut (
        "button_1" @. (CustomProperty "n_clicks"),
        [ "output_1" @. Children
          "output_2" @. Children ],
        fun (nClicks: int) -> 
            let now = DateTimeOffset.Now
            [ "output_1" @. Children => sprintf "In the first callback it is %s" (now.ToString())
              "output_2" @. Children => sprintf "In the first callback it is %s" (now.ToString()) ]
        , PreventInitialCall = true
    )

let updateSecondCallback =
    Callback.singleOut (
        "output_2" @. Children,
        "output_3" @. Children,
        fun (o: obj) -> 
            async { do! Async.Sleep 5000 } |> Async.RunSynchronously
            let now = DateTimeOffset.Now
            "output_3" @. Children => sprintf "In the second callback it is %s" (now.ToString())
        , PreventInitialCall = true
    )

let updateThirdCallback =
    Callback.singleOut (
        [ "output_2" @. Children 
          "output_3" @. Children ],
        "output_4" @. Children,
        fun (o1: obj) (o2: obj) -> 
            let now = DateTimeOffset.Now
            "output_4" @. Children => sprintf "In the third callback it is %s" (now.ToString())
        , PreventInitialCall = true
    )

[<EntryPoint>]
let main args =
    DashApp.initDefault()
    |> DashApp.withLayout dslLayout
    |> DashApp.addCallback updateFirstCallback
    |> DashApp.addCallback updateSecondCallback
    |> DashApp.addCallback updateThirdCallback
    |> DashApp.run args