module Panes.Modal.AddPerson 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 Data exposing (Id)
import Data.Schema exposing (Schema)
import Network.Messages
import PaneMeta exposing (PaneMeta)
import Dict

component : RawComponent (Id, String) Model Msg
component =
    { init = init
    , view = view
    , title = title
    , update = update
    , apply = apply
    , save = save
    , subscription = subscription
    }

type alias Model =
    { interview: Id
    , database: String
    , selected: Maybe String
    , modalId: Maybe Int
    }

type Msg
    = None
    | SendEvent Event
    | Select String
    | Submit Int String

init : Init (Id, String) Model Msg
init _ (id, database) =
    triple
        { interview = id
        , database = database
        , selected = Nothing
        , modalId = Nothing
        }
        Cmd.none
        []

getSchema : PaneMeta -> String -> Maybe Schema
getSchema meta database =
    meta.info
    |> Maybe.andThen
        (\info ->
            info.database
            |> List.filter ((==) database << .name)
            |> List.head
            |> Maybe.map .roleSchema
        )
    |> Maybe.andThen
        (\schema -> Dict.get schema meta.schemas)

view : View Model Msg
view { meta, state } =
    div [ class "modal-add-person" ]
        [ div [ class "modal-add-person-hint" ]
            [ text <| "Select a role for the person."
            , Html.br [] []
            , text "Keep in mind that you cannot change your selection afterwards!"
            ]
        , div [ class "modal-add-person-container" ]
            <| case getSchema meta state.database of
                Nothing ->
                    [ div [ class "modal-add-person-not-found" ]
                        [ text "No entries found" ]
                    ]
                Just schema ->
                    [ viewRoleList schema state.selected
                    , case viewPreview schema state.selected of
                        Ok html -> html
                        Err error ->
                            div [ class "modal-add-person-err" ]
                                [ text error ]
                    ]
        , div [ class "modal-add-person-buttons" ]
            [ case state.selected of
                Nothing -> text ""
                Just role ->
                    div [ class "modal-add-person-button" 
                        , HE.onClick
                            <| Maybe.withDefault None
                            <| Maybe.map (\x -> Submit x role)
                            <| state.modalId
                        ]
                        [ text <| "Add " ++ role ]
            ]
        ]

viewRoleList : Schema -> Maybe String -> Html Msg
viewRoleList schema selection =
    div [ class "modal-add-person-roles" ]
    <| List.map
        (\(key, _) ->
            div [ HA.classList
                    [ ("modal-add-person-role", True)
                    , ("modal-add-person-role-selected", Just key == selection)
                    ]
                , HE.onClick <| Select key
                ]
                [ text key ]
        )
    <| List.filter
        (Tuple.second >> .abstract >> not)
    <| Dict.toList schema

viewPreview : Schema -> Maybe String -> Result String (Html Msg)
viewPreview schema selection =
    case selection of
        Nothing -> Err "select a role to get a preview"
        Just selected -> case Dict.get selected schema of
            Nothing -> Err "selected role not found"
            Just role -> Ok <|
                div [ class "modal-add-person-preview" ]
                    [ div [ class "modal-add-person-preview-name" ]
                        [ text selected ]
                    , div [ class "modal-add-person-preview-list" ]
                        <| List.map
                            (\(name, attribute) ->
                                viewPreviewSingle name attribute
                            )
                        <| Dict.toList role.attributes
                    ]

viewPreviewSingle : String -> Data.Schema.Attribute -> Html Msg
viewPreviewSingle name attribute = 
    div [ class "modal-add-person-preview-single" ] 
        [ div [ class "modal-add-person-preview-single-name" ]
            [ text name ]
        , div [ class "modal-add-person-preview-single-type" ]
            [ text attribute.type_ ]
        , if attribute.protected
            then div 
                [ class "modal-add-person-preview-icon-protected"
                , HA.title <| "This is a protected attribute. The data will only be stored in the "
                    ++ "confidential database."
                ]
                [ Html.img
                    [ HA.src "/img/svgrepo/essential-set-2/locked-36369.svg" 
                    ] []
                ]
            else div [ class "modal-add-person-preview-icon" ] []
        , if attribute.history
            then div 
                [ class "modal-add-person-preview-icon-history"
                , HA.title <| "For this attribute will a history be created. You can inspect and "
                    ++ "revert any changes to this."
                ]
                [ Html.img
                    [ HA.src "/img/svgrepo/essential-set-2/calendar-22186.svg" 
                    ] []
                ]
            else div [ class "modal-add-person-preview-icon" ] []
        ]

title : Title Model
title { state } =
    "Add Person to Interview #" ++ state.interview

update : Update Model Msg
update msg { state } =
    case msg of
        None -> triple
            state
            Cmd.none
            []
        SendEvent event -> triple
            state
            Cmd.none
            [ event ]
        Select name -> triple
            { state | selected = Just name }
            Cmd.none
            []
        Submit id role -> triple
            state
            Cmd.none
            [ Panes.CloseModal id
            , Panes.Send 
                <| Network.Messages.DataPersonAddRequest
                    { database = state.database
                    , interview = state.interview
                    , role = role
                    }
            ]

apply : Apply Model Msg
apply event { state } =
    case event of
        _ -> triple state Cmd.none []

save : Save Model
save _ = []

subscription : Subscription Model Msg
subscription _ = Sub.none
