module Pages.Services.Elm exposing (Model, Msg, page)

import Config.Helpers.Articles.Article exposing (contentList)
import Config.Helpers.Articles.Markdown as Markdown
import Config.Helpers.Cards.Inner.BuyButton exposing (buyButton)
import Config.Helpers.Cards.Inner.Text exposing (renderCodeLine)
import Config.Helpers.Cards.Outer.Helpers exposing (cardMaker)
import Config.Helpers.Cards.Outer.Types as C exposing (Cardable(..))
import Config.Helpers.Headers.Types exposing (Header)
import Config.Helpers.Response
    exposing
        ( pageList
        , topLevelContainer
        )
import Config.Helpers.Viewport exposing (resetViewport)
import Config.Pages.Blogs.Types exposing (BlogArticle)
import Config.Pages.Services.Records.ElmBuilds exposing (servicesElmBuilds)
import Config.Style.Colour.Helpers
    exposing
        ( ThemeColor(..)
        , getThemeColor
        , syntaxTheme
        )
import Effect exposing (Effect)
import Element as E
    exposing
        ( Device
        , DeviceClass(..)
        , Element
        , Orientation(..)
        , centerX
        , column
        , el
        , fill
        , paddingEach
        , paddingXY
        , spacing
        , text
        , width
        )
import Element.Background as B exposing (color)
import Element.Border as D exposing (rounded)
import Element.Font as F exposing (color)
import Layouts
import Page exposing (Page)
import Ports
import Route exposing (Route)
import Route.Path as Path
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
    | MarkdownMsg Markdown.Msg


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

        MarkdownMsg (Markdown.ScrollToElement elementId) ->
            ( model
            , Effect.sendCmd (Ports.scrollToElement elementId)
            )



-- SUBSCRIPTIONS


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



-- VIEW


view : Shared.Model -> Model -> View Msg
view shared model =
    { title = "services (elmBuilds)"
    , attributes = []
    , element = elmBuildsContainer shared.device
    }


elmBuildsContainer : Device -> Element Msg
elmBuildsContainer device =
    topLevelContainer (elmBuildsList device)


elmBuildsList : Device -> Element Msg
elmBuildsList device =
    column
        (case ( device.class, device.orientation ) of
            _ ->
                pageList device
        )
    <|
        List.concat
            [ List.map
                (\service ->
                    cardMaker device
                        (C.BlogArticle service)
                        (contentList service
                            []
                            MarkdownMsg
                        )
                )
                [ elmBuilds ]
            ]


elmBuilds : BlogArticle
elmBuilds =
    { articleName = String.toUpper "Elm Builds"
    , articleLink = ""
    , articleAuthor = ""
    , isNewTabLink = False
    , hasReferences = False
    , hasTableOfContents = False
    , articleImage = ""
    , articlePublished = ""
    , articleBody = """
The site that you're currently viewing this on was written by me in the Elm programming language, and I'm offering frontend development as a service at a fee that reflects my skill level. If you're in the market for a new frontend for your website, please inquire at [contact@upRootNutrition.com](mailto:).

Below is an example of a helper function that I wrote for this site. This particular function extracts the first 80 words from all of my articles' markdown strings, and displays them as blurbs, followed by an ellipsis, in my article cards using my markdown parser.

The source code for this website is viewable on upRootNutrition's [Forgejo](https://source.uprootnutrition.com/upRootNutrition/dotfiles/src/branch/main/packages/website).

# WHAT YOU GET

1. An static Elm-based website written to your specifications.

2. Two revisions to better meet your needs and vision.

3. Six months of free support to correct mistakes.

# REQUIREMENTS

• A clear vision of what you want your site to look like.

• A clear description of your site's pages and structure.

• Any bespoke frontend functionality you want included.
"""
    , articleReferences =
        [ { author = ""
          , title = ""
          , journal = ""
          , year = ""
          , link = ""
          }
        ]
    }


elmCodeRenderer : Device -> Element msg
elmCodeRenderer device =
    el
        [ paddingEach
            { top = 15
            , bottom = 15
            , left = 20
            , right = 20
            }
        , case ( device.class, device.orientation ) of
            ( Phone, Portrait ) ->
                B.color (getThemeColor BackgroundDarkGrey)

            ( Tablet, Portrait ) ->
                B.color (getThemeColor BackgroundDarkGrey)

            _ ->
                B.color (getThemeColor BackgroundLightGrey)
        , D.rounded 10
        , width fill
        , spacing 8
        ]
    <|
        column
            [ F.size 14
            , spacing 5
            , width fill
            ]
            [ renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 0 0 ]
                , text "extractFirstWords"
                    |> el [ F.color syntaxTheme.key ]
                , text " : "
                    |> el [ F.color syntaxTheme.operator ]
                , text "String"
                    |> el [ F.color syntaxTheme.keyword ]
                , text " -> "
                    |> el [ F.color syntaxTheme.operator ]
                , text "String"
                    |> el [ F.color syntaxTheme.keyword ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 0 0 ]
                , text "extractFirstWords"
                    |> el [ F.color syntaxTheme.key ]
                , text " text"
                , text " ="
                    |> el [ F.color syntaxTheme.operator ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "let"
                    |> el [ F.color syntaxTheme.keyword ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "words"
                , text " ="
                    |> el [ F.color syntaxTheme.operator ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 48 0 ]
                , text "text"
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 64 0 ]
                , text "|>"
                    |> el [ F.color syntaxTheme.operator ]
                , text " String"
                , text "."
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "split"
                , text " "
                    |> el [ F.color syntaxTheme.string ]
                , text "\""
                    |> el [ F.color syntaxTheme.string ]
                , text " "
                    |> el [ F.color syntaxTheme.string ]
                , text "\""
                    |> el [ F.color syntaxTheme.string ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 64 0 ]
                , text "|>"
                    |> el [ F.color syntaxTheme.operator ]
                , text " List"
                , text "."
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "filter"
                , text " ("
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "not"
                , text " << "
                    |> el [ F.color syntaxTheme.operator ]
                , text "String"
                , text "."
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "isEmpty"
                , text ")"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "truncatedWords"
                , text " ="
                    |> el [ F.color syntaxTheme.operator ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 48 0 ]
                , text "List"
                , text "."
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "take"
                , text " 80"
                    |> el [ F.color syntaxTheme.string ]
                , text " words"
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "wasTextTruncated"
                , text " ="
                    |> el [ F.color syntaxTheme.operator ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 48 0 ]
                , text "List"
                , text "."
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "length"
                , text " words"
                , text " > "
                    |> el [ F.color syntaxTheme.operator ]
                , text "80"
                    |> el [ F.color syntaxTheme.string ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "result"
                , text " ="
                    |> el [ F.color syntaxTheme.operator ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 48 0 ]
                , text "String"
                , text "."
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "join"
                , text " "
                    |> el [ F.color syntaxTheme.string ]
                , text "\""
                    |> el [ F.color syntaxTheme.string ]
                , text " "
                    |> el [ F.color syntaxTheme.string ]
                , text "\""
                    |> el [ F.color syntaxTheme.string ]
                , text " truncatedWords"
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "in"
                    |> el [ F.color syntaxTheme.keyword ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "if"
                    |> el [ F.color syntaxTheme.keyword ]
                , text " wasTextTruncated"
                , text " then"
                    |> el [ F.color syntaxTheme.keyword ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "result"
                , text " ++ "
                    |> el [ F.color syntaxTheme.operator ]
                , text "\""
                    |> el [ F.color syntaxTheme.string ]
                , text "..."
                    |> el [ F.color syntaxTheme.string ]
                , text "\""
                    |> el [ F.color syntaxTheme.string ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "else"
                    |> el [ F.color syntaxTheme.keyword ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "result"
                ]
            ]
