module Panes.Interview exposing
    ( component
    , Model
    , Msg
    )

import Html exposing (Html, div, text)
import Html.Attributes as HA exposing (class)
import Html.Events as HE
import Triple exposing (triple)
import Panes exposing (..)
import Lazy exposing (Lazy)
import Data exposing (Interview, Id)
import Network.Messages exposing (ListPersonInfo)
import Tools
import PaneMeta exposing (PaneMeta)
import Editor
import History
import Tools.DeleteButton
import Panes.Special.MissingData

component : RawComponent Id Model Msg
component =
    { init = init
    , view = view
    , title = always ""
    , update = update
    , apply = apply
    , save = save
    , subscription = subscription
    }

type alias Model = Lazy Id (Result Id LoadedModel)

type alias LoadedModel =
    { data: Interview
    , persons: List ListPersonInfo
    , editTime: Editor.Component
    , editLocation: Editor.Component
    , editInterviewer: Editor.Component
    }

type Msg
    = None
    | SendEvent Event
    | DoDelete
    | EditTime Editor.EditorMsg
    | EditLocation Editor.EditorMsg
    | EditInterviewer Editor.EditorMsg

init : Init Id Model Msg
init _ id =
    triple
        (Lazy.Loading id)
        Cmd.none
        [ Send <| Network.Messages.DataInterviewGet id
        ]

view : View Model Msg
view { meta, state } =
    case state of
        Lazy.Loading _ ->
            div [ class "pane-interview" ]
                [ text <| Debug.toString state ]
        Lazy.Loaded (Err _) ->
            Html.map SendEvent
            <| Panes.Special.MissingData.viewMissingData
        Lazy.Loaded (Ok info) ->
            div [ class "pane-interview" ]
                [ Tools.DeleteButton.view DoDelete
                , div [ class "pane-interview-title" ]
                    [ div [ class "pane-interview-title-text" ]
                        [ text "Interview" ]
                    , div [ class "pane-interview-title-id" ]
                        [ text info.data.id ]
                    , div [ class "utils-database" ]
                        [ text info.data.database ]
                    ]
                , viewInfoGrid meta info
                , div [ class "pane-interview-title-2" ]
                    [ div [ class "pane-interview-title-text" ]
                        [ text "People" ]
                    ]
                , viewPersons info
                ]

viewInfoGrid : PaneMeta -> LoadedModel -> Html Msg
viewInfoGrid meta { data, editTime, editLocation, editInterviewer } =
    div [ class "utils-edit-grid" ]
    <| List.map
        (\(title, cell) ->
            div [ class "utils-edit-grid-row" ]
                [ div [ class "utils-edit-grid-name" ]
                    [ text title ]
                , div [ class "utils-edit-grid-cell" ]
                    [ cell ]
                ]
        )
        [ Tuple.pair "created"
            <| Tools.viewDateElement meta.zone meta.now data.created
        , Tuple.pair "modified"
            <| Tools.viewDateElement meta.zone meta.now data.modified
        , Tuple.pair "interviewer"
            <| Html.map EditInterviewer
            <| Editor.view False meta.now editInterviewer
        , Tuple.pair "location"
            <| Html.map EditLocation
            <| Editor.view False meta.now editLocation
        , Tuple.pair "time"
            <| Html.map EditTime
            <| Editor.view False meta.now editTime
        ]

viewPersons : LoadedModel -> Html Msg
viewPersons model =
    div [ class "pane-interview-persons" ]
        [ div [ class "pane-interview-persons-list" ]
            <| (\list ->
                list ++
                    [ div 
                        [ class "pane-interview-persons-add" 
                        , HE.onClick <| SendEvent <| OpenAddPerson model.data.id model.data.database
                        ]
                        [ Html.img
                            [ HA.src "/img/svgrepo/essential-set-2/add-36310.svg"
                            ] []
                        ]
                    ]
                )
            <| List.map
                (\{ id, role } ->
                    div [ class "pane-interview-persons-entry" 
                        , HE.onClick <| SendEvent <| Open <| History.Person id
                        ]
                        [ div [ class "pane-interview-persons-img" ]
                            [ Html.img
                                [ HA.src "/img/svgrepo/essential-set-2/user-13663.svg"
                                ] []
                            ]
                        , div [ class "pane-interview-persons-role" ]
                            [ text role ]
                        , div [ class "pane-interview-persons-id" ]
                            [ text id ]
                        ]
                )
            <| model.persons

        ]

update : Update Model Msg
update msg { meta, state } =
    case (msg, state) of
        (None, _) -> triple
            state
            Cmd.none
            []
        (SendEvent event, _) -> triple
            state
            Cmd.none
            [ event ]
        (_, Lazy.Loading _) -> triple state Cmd.none []
        (DoDelete, Lazy.Loaded (Ok d)) ->
            triple
                state
                Cmd.none
                [ Panes.RemoveHistory <| History.Interview d.data.id
                , Panes.Open <| History.Home
                , Panes.Send <| Network.Messages.EditInterviewSend
                    { id = d.data.id
                    , delete = True
                    , time = Nothing
                    , location = Nothing
                    , interviewer = Nothing
                    }
                ]
        (EditTime sub, Lazy.Loaded (Ok d)) ->
            Editor.update meta.now sub d.editTime
            |> Triple.mapAll
                (\x -> Lazy.Loaded <| Ok { d | editTime = x })
                (Cmd.map EditTime)
                identity
        (EditLocation sub, Lazy.Loaded (Ok d)) ->
            Editor.update meta.now sub d.editLocation
            |> Triple.mapAll
                (\x -> Lazy.Loaded <| Ok { d | editLocation = x })
                (Cmd.map EditLocation)
                identity
        (EditInterviewer sub, Lazy.Loaded (Ok d)) ->
            Editor.update meta.now sub d.editInterviewer
            |> Triple.mapAll
                (\x -> Lazy.Loaded <| Ok { d | editInterviewer = x })
                (Cmd.map EditInterviewer)
                identity
        (_, Lazy.Loaded (Err _)) -> triple state Cmd.none []

apply : Apply Model Msg
apply event { meta, state } =
    case event of
        Network.Messages.InfoSend _ ->
            case state of
                Lazy.Loaded (Err id) ->
                    triple state Cmd.none
                        [ Send <| Network.Messages.DataInterviewGet id ]
                _ -> triple state Cmd.none []
        Network.Messages.DataInterviewSend id Nothing ->
            if Lazy.Loading id == state
            then triple
                (Lazy.Loaded <| Err id)
                Cmd.none
                []
            else triple state Cmd.none []
        Network.Messages.DataInterviewSend id (Just info) ->
            if Lazy.Loading id == state || Lazy.Loaded (Err id) == state
            then triple
                (Lazy.Loaded <| Ok
                    { data = info
                    , persons = []
                    , editTime = Editor.initDateTime
                        (Editor.TargetInterviewTime id)
                        meta.zoneName meta.zone meta.now
                        info.time
                    , editLocation = Editor.initSingleLine
                        (Editor.TargetInterviewLocation id)
                        info.location
                    , editInterviewer = Editor.initSingleLine
                        (Editor.TargetInterviewInterviewer id)
                        info.interviewer
                    }
                )
                Cmd.none
                [ Send <| Network.Messages.DataInterviewListPersonRequest id
                ]
            else triple state Cmd.none []
        Network.Messages.DataInterviewListPersonSend id list ->
            case state of
                Lazy.Loading _ -> triple state Cmd.none []
                Lazy.Loaded (Err _) -> triple state Cmd.none []
                Lazy.Loaded (Ok model) -> triple
                    (Lazy.Loaded <| Ok
                        { model | persons = model.persons ++ list }
                    )
                    Cmd.none
                    []
        Network.Messages.EditDenied data ->
            case state of
                Lazy.Loading _ -> triple state Cmd.none []
                Lazy.Loaded (Err _) -> triple state Cmd.none []
                Lazy.Loaded (Ok model) ->
                    if data.id == model.data.id 
                        && data.target == Network.Messages.EditTargetAttribute
                    then triple
                        (Lazy.Loaded
                            <| Ok
                            <| case data.key of
                                Just "time" -> 
                                    { model | editTime = Editor.setDenied data model.editTime }
                                Just "location" -> 
                                    { model | editLocation = Editor.setDenied data model.editLocation }
                                Just "interviewer" -> 
                                    { model | editInterviewer = Editor.setDenied data model.editInterviewer }
                                _ -> model
                        )
                        Cmd.none
                        []
                    else triple state Cmd.none []
        _ -> triple state Cmd.none []

save : Save Model
save model = 
    case model of
        Lazy.Loading _ -> []
        Lazy.Loaded (Err _) -> []
        Lazy.Loaded (Ok { editTime }) -> Editor.save editTime

subscription : Subscription Model Msg
subscription data = Sub.none
