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

import Html exposing (Html, div, text)
import Html.Attributes as HA exposing (class)
import Html.Events as HE
import Html.Lazy as HL
import Triple exposing (triple)
import Panes exposing (..)
import Panes.Search.Result
import Panes.Search.View
import Network.Messages
import Task
import Browser.Dom
import Json.Decode as JD
import Tools

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

type alias Model =
    { query: String
    , result: Maybe Panes.Search.Result.Result
    }

type Msg
    = None
    | SendEvent Event
    | SetQuery String
    | SetPage Int
    | Submit

init : Init String Model Msg
init _ query =
    triple
        { query = query
        , result = Nothing
        }
        ( Cmd.batch
            [ Task.attempt (always None)
                <| Browser.Dom.focus "Panes-Search-viewInput-input"
            , if String.isEmpty query
                then Cmd.none
                else Task.perform identity
                    <| Task.succeed Submit
            ]
        )
        []

view : View Model Msg
view data =
    div [ class "pane-search" ]
        [ viewInput data.state.query
        , case data.state.result of
            Nothing -> text ""
            Just result ->
                HL.lazy
                    (Panes.Search.Result.view
                        (Panes.Search.View.view SendEvent)
                        SetPage
                    )
                    result
        ]

viewInput : String -> Html Msg
viewInput query =
    div [ class "pane-search-query-box" ]
        [ div [ class "pane-search-query" ]
            [ Html.input
                [ HA.type_ "text"
                , HA.id "Panes-Search-viewInput-input"
                , HA.value query
                , HE.onInput SetQuery
                , Tools.onNotShiftEnter Submit
                ] []
            , Html.img
                [ HA.src "/img/svgrepo/essential-set-2/search-22197.svg"
                , HE.onClick Submit
                ] []
            ]
        ]

update : Update Model Msg
update msg { meta, state } =
    case msg of
        None -> triple
            state
            Cmd.none
            []
        SendEvent event -> triple
            state
            Cmd.none
            [ event ]
        SetQuery query -> triple
            { state | query = query }
            Cmd.none
            [ EditSearchHistoryQuery query ]
        SetPage page -> triple
            { state
            | result = Maybe.map (Panes.Search.Result.setPage page) state.result
            }
            Cmd.none
            []
        Submit -> 
            Panes.Search.Result.nextOrInit
                state.query
                meta.now
                state.result
            |> \result -> 
                triple
                    { state
                    | result = Just result
                    }
                    Cmd.none
                <| List.filterMap identity
                    [ Just
                        <| Panes.Send
                        <| Network.Messages.SearchSend
                            { query = state.query
                            , uiId = result.id
                            }
                    , Maybe.map
                        (\old ->
                            Panes.Send
                            <| Network.Messages.SearchCancel
                                { query = old.query
                                , uiId = old.id
                                }
                        )
                        state.result
                    ]


apply : Apply Model Msg
apply event { state } =
    case event of
        Network.Messages.SearchResponse response ->
            case state.result of
                Nothing -> triple state Cmd.none []
                Just result -> 
                    triple
                        { state
                        | result = Just <| Panes.Search.Result.add response result
                        }
                        Cmd.none
                        []
        _ -> triple state Cmd.none []

save : Save Model
save model =
    case model.result of
        Nothing -> []
        Just result ->
            [ Panes.Send
                <| Network.Messages.SearchCancel
                    { query = result.query
                    , uiId = result.id
                    }
            ]

subscription : Subscription Model Msg
subscription data = Sub.none

