module Model exposing (..)

import PaneMeta exposing (PaneMeta)
import History exposing (History)
import Panes.Controller
import Triple exposing (Triple)
import Panes.Navigation
import Panes exposing (Event)
import Panes.Modals
import Time exposing (Posix)
import Browser.Navigation exposing (Key)
import Url exposing (Url)
import Notification
import Json.Decode

type alias Model =
    { key: Key
    , url: Url
    , notification: Notification.Model
    , login: LoginPane
    , paneMeta: PaneMeta
    , modal: Panes.Modals.Modals
    , pane: Maybe Pane
    , nav: Panes.Navigation.Model
    }

type LoginPane
    = LoginPaneEmpty
    | LoginPaneRegister
        { database: String
        , key: Maybe String
        , username: String
        , password1: String
        , password2: String
        }
    | LoginPaneRegisterFido
        { database: Maybe String
        , fidoData: Json.Decode.Value
        , error: Maybe String
        }
    | LoginPaneLogin
        { database: Maybe String
        , username: String
        , password: String
        , error: Maybe String
        }

type alias Pane = Panes.Controller.Pane

initPane : History -> PaneMeta.PaneMeta -> Triple Pane (Cmd Panes.Controller.Msg) (List Event)
initPane history meta =
    case history of
        History.Home ->
            Panes.Controller.initHome meta
        History.Search _ query -> 
            Panes.Controller.initSearch meta query
        History.Interview id ->
            Panes.Controller.initInterview meta id
        History.Person id ->
            Panes.Controller.initPerson meta id

openPane : History -> Model -> Triple Model (Cmd Panes.Controller.Msg) (List Event)
openPane history model =
    Triple.mapFirst
        (\x ->
            { model 
            | paneMeta = PaneMeta.pushHistory history model.paneMeta
            , pane = Just x
            }
        )
    <| Triple.mapThird
        (\list ->
            case model.pane of
                Nothing -> list
                Just pane -> Panes.Controller.save pane ++ list
        )
    <| initPane history model.paneMeta

initWithPane : (imsg -> msg)
    -> Triple a (Cmd imsg) (List event)
    -> Triple (a -> b) (Cmd msg) (List event)
    -> Triple b (Cmd msg) (List event)
initWithPane tagger data =
    Triple.mapAll
        (\x -> x <| Triple.first data)
        (\x -> Cmd.batch [ x, Cmd.map tagger <| Triple.second data ])
        (\x -> x ++ Triple.third data)
