module Editor.DateTime exposing (..)

import Time exposing (Posix, Zone)
import DateTime
import DatePicker
import DatePicker.Types
import Triple exposing (Triple)
import TimePicker.Types
import Clock
import Html exposing (Html, div)
import Html.Attributes exposing (class)
import Iso8601
import DateTime exposing (DateTime)
import Tools

type alias Model =
    { picker: DatePicker.Model
    , current: Posix
    , zone: Zone
    }

type Msg
    = Wrap DatePicker.Msg

{-| This will fix the time offset, so we have an input in local time -}
toLocal : Zone -> Posix -> DateTime
toLocal zone utc =
    DateTime.fromPosix
        <| Time.millisToPosix
        <| (DateTime.getTimezoneOffset zone utc)
            + (Time.posixToMillis utc)

{-| This will fix the time offset, so we have universal time again -}
toUtc : Zone -> DateTime -> Posix
toUtc zone local =
    DateTime.toPosix local
    |> \posix ->
        Time.millisToPosix
        <| (Time.posixToMillis posix)
             - (DateTime.getTimezoneOffset zone posix)

init : Maybe String -> Zone -> Posix -> Posix -> Model
init zoneName zone now time =
    { picker =
        DatePicker.initialise
            DatePicker.Types.Single
            { today = toLocal zone now
            , startingWeekday = Time.Mon
            , primaryDate = Just <| toLocal zone time
            , dateLimit = DatePicker.Types.NoLimit
            }
            (Just
                { pickerType = TimePicker.Types.HH_MM
                    { hoursStep = 1
                    , minutesStep = 5
                    }
                , defaultTime = Clock.fromPosix <| DateTime.toPosix <| toLocal zone time
                , pickerTitle =
                    case zoneName of
                        Nothing -> "Local Time"
                        Just name -> "Local Time in " ++ name
                }
            )
            Nothing
        |> DatePicker.setSelectedDate (toLocal zone time)
    , current = time
    , zone = zone
    }

view : Bool -> Posix -> Model -> Html Msg
view readonly now { picker, current, zone } =
    div [ class "editor-datetime" ]
        [ if not readonly
            then Html.map Wrap
                <| DatePicker.view picker
            else Tools.viewDateElement zone now current
        ]

update : Msg -> Model -> Triple Model (Cmd Msg) (Maybe Posix)
update msg model =
    case msg of
        Wrap sub ->
            DatePicker.update sub model.picker
            |> Triple.mapAll
                (\x -> { model | picker = x })
                (Cmd.map Wrap)
                (\result ->
                    case result of
                        DatePicker.None -> Nothing
                        DatePicker.DateSelected Nothing -> Nothing
                        DatePicker.DateSelected (Just date) ->
                            Just <| toUtc model.zone date
                )
            |> \(m, c, r) ->
                case r of
                    Just result ->
                        ( { m | current = result }, c, r)
                    Nothing -> (m, c, r)
