module Examples.Slide exposing (Msg, State, example)

{-|

@docs Msg, State, example

-}

import Accessibility.Styled as Html
import Category exposing (Category(..))
import Css
import Example exposing (Example)
import Html.Styled.Attributes exposing (css)
import Html.Styled.Keyed as Keyed
import List.Zipper as Zipper exposing (Zipper)
import Nri.Ui.Button.V10 as Button
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Slide.V1 as Slide


{-| -}
type Msg
    = TriggerAnimation Slide.AnimationDirection


{-| -}
type alias State =
    { direction : Slide.AnimationDirection
    , panels : Zipper Panel
    , previous : Maybe Panel
    }


{-| -}
example : Example State Msg
example =
    { name = "Nri.Ui.Slide.V1"
    , categories = [ Animations ]
    , state = init
    , update = update
    , subscriptions = \_ -> Sub.none
    , view =
        \state ->
            [ Keyed.node "div"
                [ css
                    [ Slide.withSlidingContents
                    , Css.border3 (Css.px 3) Css.solid Colors.gray75
                    , Css.padding (Css.px 20)
                    , Css.width (Css.px 600)
                    ]
                ]
                (case state.previous of
                    Just previousPanel ->
                        [ viewPanel previousPanel (Slide.animateOut state.direction)
                        , viewPanel (Zipper.current state.panels) (Slide.animateIn state.direction)
                        ]

                    Nothing ->
                        [ viewPanel (Zipper.current state.panels) (Css.batch [])
                        ]
                )
            , Html.div
                [ css
                    [ Css.displayFlex
                    , Css.justifyContent Css.spaceBetween
                    , Css.marginTop (Css.px 20)
                    , Css.width (Css.px 300)
                    ]
                ]
                [ triggerAnimation Slide.FromLTR "Left-to-right"
                , triggerAnimation Slide.FromRTL "Right-to-left"
                ]
            ]
    }


{-| -}
init : State
init =
    { direction = Slide.FromRTL
    , panels = Zipper.from [] One [ Two, Three ]
    , previous = Nothing
    }


{-| -}
update : Msg -> State -> ( State, Cmd Msg )
update msg state =
    case msg of
        TriggerAnimation direction ->
            ( { state
                | direction = direction
                , panels =
                    case direction of
                        Slide.FromRTL ->
                            Zipper.next state.panels
                                |> Maybe.withDefault (Zipper.first state.panels)

                        Slide.FromLTR ->
                            Zipper.previous state.panels
                                |> Maybe.withDefault (Zipper.last state.panels)
                , previous = Just (Zipper.current state.panels)
              }
            , Cmd.none
            )



-- INTERNAL


type Panel
    = One
    | Two
    | Three


viewPanel : Panel -> Css.Style -> ( String, Html.Html msg )
viewPanel panel animation =
    let
        ( color, text, key ) =
            case panel of
                One ->
                    ( Colors.redDark, "Panel One", "panel-1" )

                Two ->
                    ( Colors.ochre, "Panel Two", "panel-2" )

                Three ->
                    ( Colors.green, "Panel Three", "panel-3" )
    in
    ( key
    , Html.div
        [ css
            [ Css.border3 (Css.px 2) Css.dashed color
            , Css.color color
            , Css.padding (Css.px 10)
            , Css.width (Css.px 100)
            , Css.textAlign Css.center
            , animation
            ]
        ]
        [ Html.text text
        ]
    )


triggerAnimation : Slide.AnimationDirection -> String -> Html.Html Msg
triggerAnimation direction label =
    Button.button label
        [ Button.onClick (TriggerAnimation direction), Button.small, Button.secondary ]