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

import Config.Data.Identity exposing (pageNames)
import Config.Helpers.Cards.Inner.Helpers exposing (detailBodyMaker, detailFormat, detailSpacing, detailTitleLink, detailTitleMaker, numberedListItem)
import Config.Helpers.Cards.Outer.Helpers exposing (cardMaker)
import Config.Helpers.Cards.Outer.Types as C
import Config.Helpers.Converters exposing (formatSocial)
import Config.Helpers.Format
    exposing
        ( headerFontSizeSmall
        , paragraphFontSize
        , paragraphSpacing
        , smallTextFontSize
        )
import Config.Helpers.Headers.Helpers exposing (..)
import Config.Helpers.Headers.Records exposing (cuckListHeader)
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.ToolTip exposing (tooltipImage)
import Config.Helpers.Viewport exposing (resetViewport)
import Config.Pages.Debate.Cuckery.List
    exposing
        ( cuckList
        , cuckListNumber
        )
import Config.Pages.Debate.Cuckery.Types exposing (..)
import Config.Style.Colour.Helpers
    exposing
        ( ThemeColor(..)
        , colourTheme
        )
import Config.Style.Images exposing (imageSquareMaker)
import Config.Style.Transitions
    exposing
        ( hoverFontDarkOrange
        , transitionStyleFast
        , transitionStyleSlow
        )
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 Html.Attributes as H
import Layouts
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.map
        (\_ -> NoOp)
        (Effect.sendCmd resetViewport)
    )



-- 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.pageCucks ++ ")"
    , attributes = []
    , element = cucksContainer shared.device
    }


cucksContainer : Device -> Element msg
cucksContainer device =
    topLevelContainer (cucksList device)


cucksList : Device -> Element msg
cucksList device =
    column
        (case ( device.class, device.orientation ) of
            _ ->
                pageList device
        )
    <|
        List.concat
            [ [ headerMaker (R.CuckList cuckListHeader) ]
            , List.map
                (\cuck ->
                    cardMaker device (C.Cuck cuck) (contentList device cuck)
                )
                cuckList
            ]


contentList : Device -> Cuck -> List (Element msg)
contentList device cuck =
    let
        image : String -> Element msg
        image size =
            el
                [ alignRight
                , alignTop
                , paddingEach
                    { top = 0
                    , right = 10
                    , bottom = 0
                    , left = 0
                    }
                ]
            <|
                imageSquareMaker device (imagePathMaker M.Cuck cuck.cuckImage) True size
    in
    [ detailFormat row
        [ case ( device.class, device.orientation ) of
            ( Phone, Portrait ) ->
                none

            ( Tablet, Portrait ) ->
                none

            _ ->
                image "Fatty"
        , detailFormat column
            [ socialMaker cuck
            , dodgeTitle cuck
            , dodgeMaker device cuck
            ]
        ]
    ]


dodgeMaker : Device -> Cuck -> Element msg
dodgeMaker device cuck =
    column
        [ spacing 10
        , width fill
        ]
    <|
        List.map2 (\x y -> makeDodge device cuck x y)
            cuck.cuckDodges
            (List.range 1 (List.length cuck.cuckDodges))


socialMaker : Cuck -> Element msg
socialMaker cuck =
    newTabLink
        []
        { url = cuck.cuckSocial
        , label =
            detailTitleLink
                TextLightOrange
                (formatSocial cuck.cuckSocial)
        }


dodgeTitle : Cuck -> Element msg
dodgeTitle cuck =
    detailTitleMaker
        TextLightGrey
        "Dodges: "


makeDodge : Device -> Cuck -> Dodge -> Int -> Element msg
makeDodge device cuck dodge index =
    detailFormat row
        [ numberedListItem TextLightGrey index
        , detailFormat column
            (dodgeRows device cuck dodge)
        ]


dodgeWidth =
    width <| px 85


formatProposition : String -> String
formatProposition proposition =
    if proposition == "N/A" then
        proposition

    else
        "\"" ++ proposition ++ "\""


dodgeCounter : Int -> Element msg
dodgeCounter index =
    detailTitleMaker TextLightGrey
        (String.fromInt index ++ ". ")


circumstanceMaker : Cuck -> Dodge -> Element msg
circumstanceMaker cuck dodge =
    newTabLink
        []
        { url = dodge.dodgeLink
        , label = circumstance cuck dodge
        }


circumstance : Cuck -> Dodge -> Element msg
circumstance cuck dodge =
    detailFormat paragraph
        [ detailTitleLink TextLightOrange
            (case dodge.dodgeDescription of
                NoReply ->
                    "Debate invitation extended with no response"

                RanAway ->
                    "Engaged in written debate and ran away when cornered"

                GhostedMe ->
                    "Debate invitation accepted with no follow-up"

                OutrightNo ->
                    "Debate invitation declined"

                InTooDeep ->
                    "Debate invitation accepted and subsequently retracted"

                KillScreen ->
                    "All further debate invitations preemptively declined"

                VagueGesture ->
                    "Chose to gesture vaguely instead of engaging"

                EmptyHanded ->
                    "Engaged in written debate and ran away when pressed for specifics"
            )
        , el [ F.color colourTheme.textLightGrey ] <|
            text "."

        -- , receipts cuck dodge
        ]


receipts : Cuck -> Dodge -> Element msg
receipts cuck dodge =
    row
        [ spacing 3
        , smallTextFontSize
        , paddingEach
            { top = 0
            , right = 0
            , bottom = 0
            , left = 3
            }
        , htmlAttribute (H.style "position" "relative")
        , htmlAttribute (H.style "top" "-5px")
        ]
    <|
        List.indexedMap
            (\index2 link ->
                paragraph
                    [ alignTop
                    , F.color colourTheme.textLightOrange
                    ]
                    [ el
                        [ transitionStyleSlow
                        , hoverFontDarkOrange
                        ]
                        (text (String.fromInt (index2 + 1)))
                    , text ", " |> el [ F.color colourTheme.textLightGrey ]
                    ]
            )
            dodge.dodgeReceipts


infoRow : Device -> String -> Element msg -> Element msg
infoRow device label value =
    detailFormat
        (case ( device.class, device.orientation ) of
            ( Phone, Portrait ) ->
                column

            ( Tablet, Portrait ) ->
                column

            _ ->
                row
        )
        (if String.isEmpty label then
            [ detailBodyMaker TextLightGrey value ]

         else
            [ el
                [ width <| px 75
                , alignTop
                ]
              <|
                detailTitleMaker TextLightGrey label
            , detailBodyMaker TextLightGrey value
            ]
        )


dodgeRows : Device -> Cuck -> Dodge -> List (Element msg)
dodgeRows device cuck dodge =
    [ infoRow device "" (circumstanceMaker cuck dodge)
    , infoRow device "Prop:" (text (formatProposition dodge.dodgeProposition))
    , case dodge.dodgeFallacy of
        Nothing ->
            none

        _ ->
            infoRow device "Fallacy:" (reductioMaker device dodge)
    , infoRow device "Attitude:" (attitudeMaker device dodge)
    , infoRow device "Reason:" (reasonMaker device dodge)
    ]


attitudeMaker : Device -> Dodge -> Element msg
attitudeMaker device dodge =
    detailFormat paragraph
        [ case dodge.dodgeNicksDoxasticState of
            Nothing ->
                paragraph [ F.regular ] [ text "I don't form a doxastic state." ]

            Just Belief ->
                paragraph [ F.regular ]
                    [ text "I lean more toward "
                    , el [ F.bold ] (text "TRUE")
                    , text " than false."
                    ]

            Just Disbelief ->
                paragraph [ F.regular ]
                    [ text "I lean more toward "
                    , text "FALSE" |> el [ F.bold ]
                    , text " than true."
                    ]

            Just Agnostic ->
                el [ F.regular ] (text "I don't form beliefs about this proposition.")
        ]


reductioMaker : Device -> Dodge -> Element msg
reductioMaker device dodge =
    let
        displayFallacy : String -> Element msg
        displayFallacy fallacyText =
            detailFormat paragraph
                [ text fallacyText ]
    in
    case dodge.dodgeFallacy of
        Nothing ->
            none

        Just fallacy ->
            case fallacy of
                SpecificFallacy str ->
                    displayFallacy str

                AppealToNature ->
                    displayFallacy "Appeal to Nature"

                AppealToTradition ->
                    displayFallacy "Appeal to Tradition"

                AppealToIgnorance ->
                    displayFallacy "Appeal to Ignorance"

                AppealFromIncredulity ->
                    displayFallacy "Appeal from Incredulity"

                RedHerring ->
                    displayFallacy "Red Herring"

                BeggingTheQuestion ->
                    displayFallacy "Begging the Question"

                Strawman ->
                    displayFallacy "Strawman"

                Equivocation ->
                    displayFallacy "Equivocation"

                GeneticFallacy ->
                    displayFallacy "Genetic Fallacy"

                MotteAndBailey ->
                    displayFallacy "Motte and Bailey"

                MechanisticMasturbation ->
                    displayFallacy "Mechanistic Masturbation"
                Vaguemongering ->
                    displayFallacy "Vaguemongering"


reasonMaker : Device -> Dodge -> Element msg
reasonMaker device dodge =
    detailFormat paragraph
        [ text <|
            case dodge.dodgeNicksDoxasticReason of
                NoProp ->
                    "There is no proposition to evaluate."

                VagueProp ->
                    "The proposition is too vague to evaluate."

                SpecificPropReason str ->
                    str
        ]
