module Pages.Debate.Gibberish exposing (Model, Msg, page)

import Config.Data.Identity exposing (pageNames)
import Config.Helpers.Cards.Outer.Helpers exposing (cardMaker)
import Config.Helpers.Cards.Outer.Types as C
import Config.Helpers.Converters exposing (toTitleCase)
import Config.Helpers.Format
    exposing
        ( headerFontSizeSmall
        , paragraphFontSize
        , paragraphSpacing
        )
import Config.Helpers.Headers.Helpers exposing (..)
import Config.Helpers.Headers.Records exposing (gibberishHeader)
import Config.Helpers.Headers.Types as R exposing (..)
import Config.Helpers.ImageFolders as M exposing (..)
import Config.Helpers.Response
    exposing
        ( pageList
        , topLevelContainer
        )
import Config.Helpers.ServiceFormat exposing (chunkMaker)
import Config.Helpers.StrengthBar
    exposing
        ( barMaker
        , barPadding
        )
import Config.Helpers.ToolTip exposing (tooltip)
import Config.Helpers.Viewport exposing (resetViewport)
import Config.Pages.Debate.Arguments.Types exposing (..)
import Config.Pages.Debate.Gibberish.List exposing (gibberishList)
import Config.Pages.Debate.Gibberish.Records.Epistemology exposing (epistemologyGibberish)
import Config.Pages.Debate.Gibberish.Records.Metaphysics exposing (metaphysicsGibberish)
import Config.Pages.Debate.Gibberish.Records.Normativity exposing (normativityGibberish)
import Config.Pages.Debate.Gibberish.Records.Ontology exposing (ontologyGibberish)
import Config.Pages.Debate.Gibberish.Records.PhilOfLanguage exposing (philOfLanguageGibberish)
import Config.Pages.Debate.Gibberish.Records.PhilOfMind exposing (philOfMindGibberish)
import Config.Pages.Debate.Gibberish.Records.Theology exposing (theologyGibberish)
import Config.Pages.Debate.Gibberish.Types exposing (..)
import Config.Style.Colour.Helpers exposing (colourTheme)
import Config.Style.Images exposing (imageSquareMaker)
import Effect exposing (Effect)
import Element as E exposing (..)
import Element.Background as B
import Element.Border as D
import Element.Font as F
import Layouts
import List.Extra as L exposing (..)
import Page exposing (Page)
import Route exposing (Route)
import Shared
import View exposing (View)


page : Shared.Model -> Route () -> Page Model Msg
page shared route =
    Page.new
        { init = init
        , update = update
        , subscriptions = subscriptions
        , view = view shared
        }
        |> Page.withLayout toLayout


toLayout : Model -> Layouts.Layout Msg
toLayout model =
    Layouts.Navbar {}



-- INIT


type alias Model =
    {}


init : () -> ( Model, Effect Msg )
init () =
    ( {}
    , Effect.batch
        [ Effect.map
            (\_ -> NoOp)
            (Effect.sendCmd resetViewport)
        , Effect.none
        ]
    )



-- UPDATE


type Msg
    = NoOp


update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
    case msg of
        NoOp ->
            ( model
            , Effect.none
            )



-- SUBSCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.none



-- VIEW


view : Shared.Model -> Model -> View Msg
view shared model =
    { title = "debate (" ++ pageNames.pageGibberish ++ ")"
    , attributes = []
    , element = gibberishContainer shared
    }


gibberishContainer : Shared.Model -> Element msg
gibberishContainer shared =
    topLevelContainer (gibberishList shared)


gibberishList : Shared.Model -> Element msg
gibberishList shared =
    column
        (case ( shared.device.class, shared.device.orientation ) of
            _ ->
                pageList shared.device
        )
    <|
        List.concat
            [ [ headerMaker (R.Gibberish gibberishHeader) ]
            , List.map
                (\gibberish ->
                    cardMaker shared.device (C.Gibberish gibberish) (contentList shared gibberish)
                )
                [ epistemologyGibberish
                , theologyGibberish
                , metaphysicsGibberish
                , normativityGibberish
                , ontologyGibberish
                , philOfMindGibberish
                , philOfLanguageGibberish
                ]
            ]


contentList : Shared.Model -> Gibberish -> List (Element msg)
contentList shared gibberish =
    let
        image : String -> Element msg
        image size =
            el
                [ alignLeft
                , paddingEach
                    { top = 0
                    , right = 10
                    , bottom = 0
                    , left = 0
                    }
                ]
            <|
                imageSquareMaker shared.device (imagePathMaker M.Gibberish gibberish.gibberishImage) True size
    in
    [ paragraph
        [ F.color colourTheme.textLightGrey
        , paragraphSpacing
        , paragraphFontSize
        , width fill
        ]
        [ case ( shared.device.class, shared.device.orientation ) of
            ( Phone, Portrait ) ->
                none

            ( Tablet, Portrait ) ->
                none

            _ ->
                image "Big"
        , text gibberish.gibberishDescription
        ]
    , gibberishMakerBody shared gibberish
    ]


gibberishMakerBody : Shared.Model -> Gibberish -> Element msg
gibberishMakerBody shared gibberish =
    column
        [ paddingEach
            { top = 0
            , bottom = 0
            , left = 15
            , right = 15
            }
        , spacing 8
        , width fill
        ]
        [ column
            [ spacing 8
            , width fill
            ]
            [ paragraph
                [ F.color colourTheme.textLightGrey
                , paragraphSpacing
                , headerFontSizeSmall
                , F.center
                ]
                [ domainList shared gibberish
                ]
            ]
        ]


gibberishImage : Gibberish -> { src : String, description : String }
gibberishImage gibberish =
    { src = "/gibberish/" ++ gibberish.gibberishImage ++ ".png"
    , description = gibberish.gibberishTitle
    }


gibberishTitle : Shared.Model -> Gibberish -> String
gibberishTitle shared gibberish =
    gibberish.gibberishTitle


domainList : Shared.Model -> Gibberish -> Element msg
domainList shared gibberish =
    column
        [ spacing 8
        , E.width fill
        ]
        (List.indexedMap (makeTerms (intelligibilityBar shared)) gibberish.gibberishTerms)


descriptionMaker : Gibberish -> Element msg
descriptionMaker gibberish =
    column
        [ E.width fill
        , centerX
        ]
        [ paragraph
            [ F.color colourTheme.textLightGrey
            , paragraphSpacing
            , paragraphFontSize
            , spacing 3
            , F.regular
            , F.alignLeft
            ]
            [ text gibberish.gibberishDescription
            ]
        ]


makeTerms : (Terms -> Element msg) -> Int -> Terms -> Element msg
makeTerms bar index terms =
    column
        [ F.color colourTheme.textLightGrey
        , paragraphSpacing
        , paragraphFontSize
        , F.bold
        , E.alignLeft
        , spacing 8
        , E.width fill
        ]
        [ row
            [ F.color colourTheme.textLightGrey
            , F.regular
            , headerFontSizeSmall
            , F.bold
            , F.alignLeft
            , E.width fill
            ]
            [ column
                [ E.alignRight
                , alignTop
                ]
                [ paragraph
                    []
                    [ text (String.fromInt (index + 1) ++ ". ") ]
                ]
            , column
                [ E.width fill
                , paddingEach
                    { top = 0
                    , bottom = 0
                    , left = 10
                    , right = 10
                    }
                , spacing 3
                ]
                [ paragraph
                    []
                    [ el [ F.color colourTheme.textLightOrange ] <|
                        text <|
                            "\""
                                ++ String.toLower terms.term
                                ++ "\""
                    ]
                , bar terms
                , paragraph
                    [ F.color colourTheme.textLightGrey
                    , F.regular
                    , paragraphFontSize
                    , F.alignLeft
                    ]
                    [ text
                        (case terms.explanation of
                            NoClue ->
                                "I have no fucking clue what this means."

                            SpecificExplanation str ->
                                str
                        )
                    ]
                ]
            ]
        ]


intelligibilityBar : Shared.Model -> Terms -> Element msg
intelligibilityBar shared terms =
    row
        [ E.width fill
        , height fill
        ]
        [ column
            [ E.alignTop
            , E.alignLeft
            ]
            [ paragraph
                [ F.color colourTheme.textLightGrey
                , F.bold
                , headerFontSizeSmall
                , paragraphSpacing
                , E.alignLeft
                , E.width fill
                ]
                [ el
                    (if not shared.isNavbarExpanded then
                        [ tooltip
                            tooltipMessage
                        ]

                     else
                        []
                    )
                  <|
                    (el
                        [ paddingEach
                            { top = 0
                            , right = 10
                            , bottom = 0
                            , left = 0
                            }
                        ]
                     <|
                        text barTitle
                    )
                ]
            ]
        , barPadding
            [ barMaker getIntelligibilityTooltip terms.strength ]
        ]


tooltipMessage : String
tooltipMessage =
    "This represents my confidence that the term can be understood from at least one viewpoint."


barTitle : String
barTitle =
    "Intelligibility:"


getIntelligibilityTooltip : Int -> String
getIntelligibilityTooltip num =
    case num of
        0 ->
            "Total fucking gibberish."

        1 ->
            "Extremely unclear, speaking in tongues."

        2 ->
            "Mostly unclear, hard to make any sense of."

        3 ->
            "Somewhat unclear, difficult to understand."

        4 ->
            "Slightly unclear, understandable with effort."

        5 ->
            "Neutral, not sure what to make of it."

        6 ->
            "Slightly clear, with unanswered questions."

        7 ->
            "Somewhat clear, kinda get the idea."

        8 ->
            "Very clear, usefulness questionable."

        9 ->
            "Extremely clear, usefulness dubious."

        10 ->
            "Perfectly clear, but also useless."

        _ ->
            "Intelligibility rating is out of bounds."
