module Pages.Services.Nix 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.NixBuilds exposing (servicesNixBuilds)
import Config.Style.Colour.Helpers
    exposing
        ( ThemeColor(..)
        , getThemeColor
        , syntaxTheme
        )
import Config.Style.Colour.Types exposing (SyntaxColors)
import Effect exposing (Effect)
import Element as E
    exposing
        ( Device
        , DeviceClass(..)
        , Element
        , Orientation(..)
        , centerX
        , column
        , el
        , fill
        , paddingEach
        , paddingXY
        , paragraph
        , 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 (nixConfigs)"
    , attributes = []
    , element = nixBuildsContainer shared.device
    }


nixBuildsContainer : Device -> Element Msg
nixBuildsContainer device =
    topLevelContainer (nixBuildsList device)


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


nixBuilds : BlogArticle
nixBuilds =
    { articleName = String.toUpper "Nix Builds"
    , articleLink = ""
    , articleAuthor = ""
    , isNewTabLink = False
    , hasReferences = False
    , hasTableOfContents = False
    , articleImage = ""
    , articlePublished = ""
    , articleBody = """
NixOS has become popular in my community, with many people choosing to explore it over Windows, MacOS, and other Linux distributions. Naturally, as a consequence of this, I receive numerous requests for help regarding the Nix programming language and NixOS system configuration. So, to fast-track newcomers and to make my life a little bit easier for both of us, I'm offering to build custom NixOS configurations for interested clients.
If you're interested in having a custom Nix configuration, or having a pre-existing configuration refactored, please inquire at [contact@upRootNutrition.com](mailto:).

Below is an example of a nix flake that I wrote for the devshell that I used to manage and isolate the development environment for this site. All of the packages, pre-defined settings, and tooling used for this site are managed through this flake.

The source code for my Nix server is viewable on upRootNutrition's [Forgejo](https://source.uprootnutrition.com/upRootNutrition/dotfiles).

# WHAT YOU GET

1. A NixOS configuration written to your specifications.

2. Two refactors for the purposes of improving ergonomics.

3. Instructions for how to use and build upon your configuration.

# REQUIREMENTS

• A comprehensive list of packages you'd like included.

• A list of configuration architecture specifications.

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


renderCodeLine : SyntaxColors -> List (Element msg) -> Element msg
renderCodeLine colors elements =
    paragraph
        [ F.color colors.text
        , F.alignLeft
        , F.family
            [ F.monospace ]
        ]
        elements


nixCodeRenderer : Device -> Element msg
nixCodeRenderer 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 [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 8 0 ]
                , text "description"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "\"Elm/Haskell Environment\""
                    |> el [ F.color syntaxTheme.string ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 8 0 ]
                , text "inputs"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "{"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "nixpkgs.url"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "\"github:NixOS/nixpkgs/nixos-unstable\""
                    |> el [ F.color syntaxTheme.string ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "nixpkgs-stable.url"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "\"github:NixOS/nixpkgs/nixos-23.11\""
                    |> el [ F.color syntaxTheme.string ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "haskell-flake.url"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "\"github:srid/haskell-flake\""
                    |> el [ F.color syntaxTheme.string ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 8 0 ]
                , text "}"
                    |> el [ F.color syntaxTheme.punctuation ]
                , text ";"
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 8 0 ]
                , text "outputs"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "inputs"
                    |> el [ F.color syntaxTheme.keyword ]
                , text " @ "
                    |> el [ F.color syntaxTheme.operator ]
                , text "{"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "flake-parts"
                    |> el [ F.color syntaxTheme.keyword ]
                , text ","
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "self"
                    |> el [ F.color syntaxTheme.keyword ]
                , text ","
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "..."
                    |> el [ F.color syntaxTheme.operator ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 8 0 ]
                , text "}"
                    |> el [ F.color syntaxTheme.punctuation ]
                , text ": "
                    |> el [ F.color syntaxTheme.operator ]
                , text "let"
                    |> el [ F.color syntaxTheme.keyword ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "system"
                    |> el [ F.color syntaxTheme.keyword ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "\"x86_64-linux\""
                    |> el [ F.color syntaxTheme.string ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 8 0 ]
                , text "in"
                    |> el [ F.color syntaxTheme.keyword ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "flake-parts.lib.mkFlake"
                    |> el [ F.color syntaxTheme.keyword ]
                , text " { "
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "inherit inputs"
                    |> el [ F.color syntaxTheme.keyword ]
                , text " } "
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "{"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 24 0 ]
                , text "imports"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "["
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "./parts"
                    |> el [ F.color syntaxTheme.string ]
                , text ","
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "inputs.haskell-flake.flakeModule"
                    |> el [ F.color syntaxTheme.keyword ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 24 0 ]
                , text "]"
                    |> el [ F.color syntaxTheme.punctuation ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 24 0 ]
                , text "systems"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "[ "
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "system"
                    |> el [ F.color syntaxTheme.keyword ]
                , text " ]"
                    |> el [ F.color syntaxTheme.punctuation ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 24 0 ]
                , text "perSystem"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "{ "
                    |> el [ F.color syntaxTheme.punctuation ]
                , text "pkgs"
                    |> el [ F.color syntaxTheme.keyword ]
                , text ", ... "
                    |> el [ F.color syntaxTheme.operator ]
                , text "} "
                    |> el [ F.color syntaxTheme.punctuation ]
                , text ": "
                    |> el [ F.color syntaxTheme.operator ]
                , text "{"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "_module.args.pkgs"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "import"
                    |> el [ F.color syntaxTheme.keyword ]
                , text " inputs.nixpkgs "
                    |> el [ F.color syntaxTheme.keyword ]
                , text "{ "
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 40 0 ]
                , text "inherit system"
                    |> el [ F.color syntaxTheme.key ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "}"
                    |> el [ F.color syntaxTheme.punctuation ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "_module.args.pkgs-stable"
                    |> el [ F.color syntaxTheme.key ]
                , text " = "
                    |> el [ F.color syntaxTheme.operator ]
                , text "import"
                    |> el [ F.color syntaxTheme.keyword ]
                , text " inputs.nixpkgs-stable "
                    |> el [ F.color syntaxTheme.keyword ]
                , text "{ "
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 40 0 ]
                , text "inherit system"
                    |> el [ F.color syntaxTheme.key ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 32 0 ]
                , text "}"
                    |> el [ F.color syntaxTheme.punctuation ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 24 0 ]
                , text "}"
                    |> el [ F.color syntaxTheme.punctuation ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text ""
                    |> el [ paddingXY 16 0 ]
                , text "}"
                    |> el [ F.color syntaxTheme.punctuation ]
                , text ";"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            , renderCodeLine syntaxTheme
                [ text "}"
                    |> el [ F.color syntaxTheme.punctuation ]
                ]
            ]
