open Dash.NET

type Country =
    { Name: string 
      Cities: string list }

let countries =
    [ { Name = "America"; Cities = ["New York City"; "San Francisco"; "Cincinnati"]}
      { Name = "Canada"; Cities = ["Montreal"; "Toronto"; "Ottawa"]} ]

let dslLayout = 
    Html.div [
        Attr.children [
            RadioItems.radioItems "countries-radio" [
                RadioItems.Attr.options (countries |> List.map (fun c -> {Label = c.Name; Value = c.Name; Disabled = false}))
                RadioItems.Attr.value "America"
            ]
            Html.hr []
            RadioItems.radioItems "cities-radio" []
            Html.hr []
            Html.div [Attr.id "display-selected-values"]
        ]
    ]

let setCitiesOptions =
    Callback.singleOut (
        "countries-radio" @. Value,
        "cities-radio" @. (CustomProperty "options"),
        fun (selectedCountry: string) -> 
            "cities-radio" @. (CustomProperty "options") => 
                (countries 
                 |> List.tryFind (fun c -> c.Name = selectedCountry)
                 |> Option.map (fun c -> c.Cities)
                 |> Option.map (List.map (fun c -> {|Label = c; Value = c|}))
                 |> Option.defaultValue [])
        , PreventInitialCall = false
    )

let setCitiesValue =
    Callback.singleOut (
        "cities-radio" @. (CustomProperty "options"),
        "cities-radio" @. Value,
        fun (availableOptions: {|Label: string; Value: string|} list) -> 
            "cities-radio" @. Value => availableOptions.[0].Value
        , PreventInitialCall = false
    )

let setDisplayChildren =
    Callback.singleOut (
        [ "countries-radio" @. Value
          "cities-radio" @. Value ],
        "display-selected-values" @. (CustomProperty "children"),
        fun (selectedCountry: string) (selectedCity: string) -> 
            "display-selected-values" @. (CustomProperty "children") => sprintf "%s is a city in %s" selectedCity selectedCountry
        , PreventInitialCall = false
    )

[<EntryPoint>]
let main args =
    DashApp.initDefault()
    |> DashApp.withLayout dslLayout
    |> DashApp.addCallback setCitiesOptions
    |> DashApp.addCallback setCitiesValue
    |> DashApp.addCallback setDisplayChildren
    |> DashApp.run args