module Pages.Nutridex exposing (Model, Msg, page)

import Config.Data.Identity exposing (pageNames)
import Config.Helpers.Articles.Article exposing (makeReference)
import Config.Helpers.Articles.Types exposing (References)
import Config.Helpers.Cards.Inner.Helpers exposing (detailBodyMaker, detailFormat, detailTitleMaker)
import Config.Helpers.Cards.Outer.Helpers exposing (cardMaker)
import Config.Helpers.Cards.Outer.Types as C
import Config.Helpers.Format
    exposing
        ( headerFontSizeBig
        , headerFontSizeSmall
        , paragraphFontSize
        , paragraphSpacing
        , smallTextFontSize
        )
import Config.Helpers.Headers.Helpers exposing (..)
import Config.Helpers.Headers.Records exposing (nutriDexHeader)
import Config.Helpers.Headers.Types as R exposing (..)
import Config.Helpers.Price exposing (buyButton)
import Config.Helpers.Response
    exposing
        ( pageList
        , topLevelContainer
        )
import Config.Helpers.ServiceFormat exposing (divider)
import Config.Helpers.StrengthBar
    exposing
        ( barMaker
        , barPadding
        )
import Config.Helpers.ToolTip exposing (tooltip)
import Config.Helpers.Viewport exposing (resetViewport)
import Config.Pages.Products.Records.NutriDex exposing (productNutriDex)
import Config.Pages.Products.Types exposing (..)
import Config.Style.Colour.Helpers exposing (ThemeColor(..), colourTheme)
import Config.Style.Glow exposing (glowDeepDarkGrey)
import Config.Style.Icons.Icons exposing (nutriDexLogo)
import Config.Style.Transitions
    exposing
        ( hoverFontDarkOrange
        , hoverPageButtonDeepDarkOrange
        , transitionStyleFast
        , transitionStyleMedium
        , transitionStyleSlow
        )
import Effect exposing (Effect)
import Element as E exposing (..)
import Element.Background as B
import Element.Border as D
import Element.Events as V
import Element.Font as F
import Html.Attributes as H
import Layouts
import Page exposing (Page)
import Route exposing (Route)
import Shared exposing (..)
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 = pageNames.pageNutriDex
    , attributes = []
    , element = nutriDexContainer shared.device
    }


nutriDexContainer : Device -> Element msg
nutriDexContainer device =
    topLevelContainer (nutriDexList device)


nutriDexList : Device -> Element msg
nutriDexList device =
    column
        (case ( device.class, device.orientation ) of
            _ ->
                pageList device
        )
    <|
        List.concat
            [ case ( device.class, device.orientation ) of
                ( Phone, Portrait ) ->
                    [ headerMaker (R.NutriDex nutriDexHeader) ]

                ( Tablet, Portrait ) ->
                    [ headerMaker (R.NutriDex nutriDexHeader) ]

                _ ->
                    [ none ]
            , List.map
                (\nutriDex ->
                    cardMaker device (C.NutriDex nutriDex) (contentList device nutriDex)
                )
                [ productNutriDex ]
            ]


contentList : Device -> NutriDex -> List (Element msg)
contentList device nutridex =
    [ featureList nutridex device
    , nutriDexBodyMaker device
    , nutriDexAdjustments device
    , column [ spacing 10 ]
        [ nutriDexVitamins
        , nutriDexFattyAcids
        , nutriDexMinerals
        , nutriDexAminoAcids
        ]
    , nutriDexReferences nutridex device
    ]


makeFeature : Features -> Element msg
makeFeature features =
    el
        [ E.width fill
        , alignLeft
        , paddingEach
            { top = 0
            , right = 0
            , bottom = 0
            , left = 8
            }
        ]
    <|
        detailFormat column
            [ detailFormat paragraph
                [ text "• "
                , detailTitleMaker TextLightOrange features.featureTitle
                , detailBodyMaker TextLightGrey (text features.feature |> el [ smallTextFontSize ])
                ]
            ]


featureList : NutriDex -> Device -> Element msg
featureList nutridex device =
    column
        [ spacing 8
        , width fill
        , height fill
        , paddingEach
            { top = 10
            , bottom = 0
            , left = 0
            , right = 0
            }
        ]
        [ (case ( device.class, device.orientation ) of
            ( Phone, Portrait ) ->
                column
                    [ spacing 20
                    , centerX
                    ]

            ( Tablet, Portrait ) ->
                column
                    [ spacing 20
                    , centerX
                    ]

            _ ->
                row
                    [ spacing 20
                    , width fill
                    , height fill
                    ]
          )
            [ column
                (case ( device.class, device.orientation ) of
                    ( Phone, Portrait ) ->
                        [ spacing 20, centerX ]

                    ( Tablet, Portrait ) ->
                        [ spacing 20, centerX ]

                    _ ->
                        [ spacing 20 ]
                )
                [ row
                    [ centerX
                    , case ( device.class, device.orientation ) of
                        ( Phone, Portrait ) ->
                            E.width <| px 150

                        ( Tablet, Portrait ) ->
                            E.width <| px 150

                        _ ->
                            E.width <| px 250
                    ]
                    [ html nutriDexLogo
                    ]
                , buyButton "$20" "https://uprootnutrition.myshopify.com/cart/31192710807615:1?channel=buy_button"
                , column
                    [ centerX ]
                    [ column
                        [ headerFontSizeSmall
                        , F.bold
                        , F.color colourTheme.textLightOrange
                        ]
                        [ newTabLink []
                            { url = "https://drive.google.com/file/d/1sk7VgjuL2rEqQdnBRdZjr2_Ab9vwrbmo/view?usp=sharing"
                            , label =
                                paragraph
                                    [ centerX
                                    , centerY
                                    ]
                                    [ text "Free Cost Efficiency Score!" ]
                            }
                        ]
                    ]
                ]
            , column [ width fill, smallTextFontSize, spacing 3 ] <|
                List.map2 (\x y -> makeFeature x)
                    nutridex.nutriDexFeatures
                    (List.range 1 (List.length nutridex.nutriDexFeatures))
            ]
        ]


nutriDexTitleMaker : String -> Element msg
nutriDexTitleMaker title =
    column
        [ centerX
        , width fill
        ]
        [ divider
        , paragraph
            [ F.color colourTheme.textLightGrey
            , paragraphSpacing
            , F.bold
            , centerX
            , F.center
            , headerFontSizeBig
            , F.color colourTheme.textLightOrange
            , paddingEach
                { top = 20
                , right = 0
                , bottom = 0
                , left = 0
                }
            ]
            [ text (String.toUpper title) ]
        ]


linkFormat : List (Attr () msg)
linkFormat =
    [ F.color colourTheme.textLightGrey
    , paragraphSpacing
    , paragraphFontSize
    , F.color colourTheme.textLightOrange
    , mouseOver
        [ F.color colourTheme.textDarkOrange
        ]
    , transitionStyleMedium
    ]


nutriDexBodyMaker : Device -> Element msg
nutriDexBodyMaker device =
    column [ spacing 20 ]
        [ nutriDexTitleMaker "Backstory"
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "In May 2019, after losing my job, I sought a way to optimize my diet for nutrient density (ND) while keeping costs low. I initially found a resource called ")
            , newTabLink linkFormat
                { url = "https://efficiencyiseverything.com/food/"
                , label = text "Efficiency Is Everything"
                }
            , detailBodyMaker TextLightGrey (text ", which ranked foods by nutrition per cost, but I found it too simplistic and lacking nuance, especially since it ranked processed foods like white bread highly, despite their limited health benefits. I wanted a more personalized approach—one that took into account both ND and the cost of foods specific to my region. Inspired by Mat Lalonde's AHS12 talk ")
            , newTabLink linkFormat
                { url = "https://www.youtube.com/watch?v=HwbY12qZcF4"
                , label = text "Nutrient Density: Sticking to the Essentials"
                }
            , detailBodyMaker TextLightGrey (text " on nutrient density, I created a rudimentary list of 75 foods and manually assigned them scores based on nutritional content from ")
            , newTabLink linkFormat
                { url = "https://cronometer.com/"
                , label = text "Cronometer"
                }
            , detailBodyMaker TextLightGrey (text ", paired with local grocery prices.")
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "As I refined the list, I found a community on Reddit called ")
            , newTabLink linkFormat
                { url = "https://www.reddit.com/r/EatCheapAndHealthy/"
                , label = text "EatCheapAndHealthy"
                }
            , detailBodyMaker TextLightGrey (text " where I shared my ")
            , newTabLink linkFormat
                { url = "https://www.reddit.com/r/EatCheapAndHealthy/comments/cbmxre/had_no_idea_this_sub_existed_heres_a_nutrient/"
                , label = text "spreadsheet"
                }
            , detailBodyMaker TextLightGrey (text ". The overwhelming response encouraged me to expand it further, incorporating more foods, detailed nutritional data, and more accurate ND scores. To improve accuracy, I turned to the USDA’s ")
            , newTabLink linkFormat
                { url = "https://www.ars.usda.gov/northeast-area/beltsville-md-bhnrc/beltsville-human-nutrition-research-center/nutrient-data-laboratory/docs/sr28-download-files/"
                , label = text "SR28 database"
                }
            , detailBodyMaker TextLightGrey (text ", which provided granular data for over 700 common foods. I developed a more sophisticated scoring system, assigning points based on how well each food met the daily recommended intake for essential nutrients, then normalizing these scores from 0 to 100.")
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "The final ND scores were calculated non-linearly, allowing for a more balanced representation of a food’s nutrient profile rather than allowing one nutrient to dominate the score. For instance, while Brazil nuts are high in selenium, the non-linear formula prevents their score from being artificially inflated by this one nutrient. Ultimately, the system I created allows for a more objective and personalized way to rank foods by both nutrient density and cost, making it a valuable resource for anyone looking to optimize their diet.") ]
        ]


referenceFormat : List (Attr () msg)
referenceFormat =
    [ paragraphFontSize
    , F.color colourTheme.textLightOrange
    , alignTop
    , hoverFontDarkOrange
    , transitionStyleMedium
    ]


nutriDexAdjustments : Device -> Element msg
nutriDexAdjustments device =
    column
        [ width fill
        , height fill
        , spacing 20
        ]
        [ nutriDexTitleMaker "Nutrient Density Score Adjustments"
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "No adjustments are made to vitamin B1, vitamin B2, vitamin B3, manganese, phosphorus, and potassium, due to their DRIs only representing total daily intake, or due to the nutrient having close to 100% bioavailability. ")
            , row [ F.regular, smallTextFontSize ]
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/books/NBK114331/"
                    , label = text "1"
                    }
                , text ", "
                , newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/books/NBK114322/"
                    , label = text "2"
                    }
                , text ", "
                , newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/books/NBK114304/"
                    , label = text "3"
                    }
                , text ", "
                , newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/books/NBK56056/"
                    , label = text "4"
                    }
                , text ", "
                , newTabLink referenceFormat
                    { url = "https://www.nap.edu/read/11537/chapter/39"
                    , label = text "5"
                    }
                , text ", "
                , newTabLink referenceFormat
                    { url = "https://www.nap.edu/read/11537/chapter/41"
                    , label = text "6"
                    }
                , text ", "
                , newTabLink referenceFormat
                    { url = "https://www.nap.edu/read/11537/chapter/42"
                    , label = text "7"
                    }
                ]
            ]
        ]


nutridexSubTitleMaker : String -> Element msg
nutridexSubTitleMaker title =
    el
        [ centerX
        , paddingXY 0 10
        ]
    <|
        detailTitleMaker TextLightOrange title


nutriDexVitamins : Element msg
nutriDexVitamins =
    column
        [ spacing 20
        , width fill
        , height fill
        ]
        [ nutridexSubTitleMaker "Vitamins"
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for vitamin B5 is multiplied by 2 in order to accommodate its average 50% bioavailability from food. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/books/NBK114311/"
                    , label = text "8"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for plant-derived vitamin B6 is multiplied by 1.74 in order to accommodate the average ~42.5% reduction in bioavailability of pyridoxine glucoside. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/2843032"
                    , label = text "9"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for animal-derived vitamin B6 is multiplied by 1.33 in order to accommodate the average ~25% reduction in bioavailability of as a result of cooking. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://pdfs.semanticscholar.org/b844/5e60d87753144ef856e0ae207b551aa75b9c.pdf"
                    , label = text "10"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The contribution of vitamin B12 is capped at 1.5mcg in order to account for the average absorption cap of ~1.5mcg per serving in healthy people. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/18606874"
                    , label = text "11"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for folate has been multiplied by 2 in order to accommodate its average 50% bioavailbility from food. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3257685/"
                    , label = text "12"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The contribution of plant-derived vitamin A (as retinol activity equivalents) is capped at 900mcg. This is to accommodate the fact that it is unlikely that the body can convert more than the DRI of vitamin A from carotenoids. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2855261/"
                    , label = text "13"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for plant-derived vitamin K, phylloquinone, is multiplied by 10 in order to accommodate its 10% bioavailability from plant foods. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/8813897"
                    , label = text "14"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for vitamin C has been multiplied by 1.25 in order to accommodate its average ~80% bioavailability. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/12134712"
                    , label = text "15"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for vitamin E has been multiplied by 4.65 in order to accommodate its average 21.5% bioavailability. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5745505/"
                    , label = text "16"
                    }
                ]
            ]
        ]


nutriDexFattyAcids : Element msg
nutriDexFattyAcids =
    column
        [ spacing 20
        , width fill
        , height fill
        ]
        [ nutridexSubTitleMaker "Fatty Acids"
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRIs for omega-3 and omega-6 have been recalculated to 250mg/day and 500mg/day, respectively. This better reflects our actual physiological requirements for these fatty acids as provided by their pre-elongated, animal-derived varieties. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5946201/"
                    , label = text "17"
                    }
                , newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5452278/"
                    , label = text "18"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRIs for plant-derived omega-3 and omega-6 have been multiplied by 6.66 in order to reflect their maximal ~15% conversion rate. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/12323090"
                    , label = text "19"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The contributions of plant-derived omega-3 and omega-6 are capped at 4.4444g before conversion rates are factored, in order to accommodate their conversion rate cap of 2% of calories per day. ")
            , detailFormat row
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3132704/"
                    , label = text "20"
                    }
                ]
            ]
        ]


nutriDexMinerals : Element msg
nutriDexMinerals =
    column [ spacing 10 ]
        [ nutridexSubTitleMaker "Minerals"
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for calcium has been adjusted dynamically based on the oxalate-to-calcium ratio of each food. ")
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for plant-derived copper has been multiplied by 2.94 in order to accommodate its average ~34% bioavailability from plant foods. ")
            , row [ F.regular, smallTextFontSize ]
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/8615369"
                    , label = text "21"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for animal-derived copper has been multiplied by 2.43 in order to accommodate its average ~41% bioavailability from animal foods. ")
            , row [ F.regular, smallTextFontSize ]
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/8615369"
                    , label = text "21"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for magnesium has been multiplied by 2.85 in order to accommodate its 35% bioavailability. ")
            , row [ F.regular, smallTextFontSize ]
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/1864954"
                    , label = text "22"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for iron has been adjusted dynamically based on the phytate-to-iron ratio of each food.")
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for selenium has been multiplied by 1.11 in order to accommodate its 90% bioavailability. ")
            , row [ F.regular, smallTextFontSize ]
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/20200264"
                    , label = text "23"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The contribution of zinc is capped at 7mg in order to account for the average absorption cap of 7mg per serving in healthy people. ")
            , row [ F.regular, smallTextFontSize ]
                [ newTabLink referenceFormat
                    { url = "https://www.ncbi.nlm.nih.gov/pubmed/10801947"
                    , label = text "24"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRI for zinc has been adjusted dynamically based on the phytate-to-zinc ratio of each food. ")
            ]
        ]


nutriDexAminoAcids : Element msg
nutriDexAminoAcids =
    column [ spacing 20 ]
        [ nutridexSubTitleMaker (String.toUpper "Amino Acids")
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "The DRIs for all essential amino acids from non-animal sources have been multiplied by 1.492 in order to accommodate their average PDCAAS score of .67. ")
            , row [ F.regular, smallTextFontSize ]
                [ newTabLink referenceFormat
                    { url = "https://en.wikipedia.org/wiki/Protein_Digestibility_Corrected_Amino_Acid_Score"
                    , label = text "25"
                    }
                ]
            ]
        , detailFormat paragraph
            [ detailBodyMaker TextLightGrey (text "• ")
            , detailBodyMaker TextLightGrey (text "All scores reflecting total protein yield of non-animal foods have been multiplied by .67 in order to accommodate the average 67% bioavailability of protein from non-animal sources. ")
            , row [ F.regular, smallTextFontSize ]
                [ newTabLink referenceFormat
                    { url = "https://en.wikipedia.org/wiki/Protein_Digestibility_Corrected_Amino_Acid_Score"
                    , label = text "25"
                    }
                ]
            ]
        ]


nutriDexReferences : NutriDex -> Device -> Element msg
nutriDexReferences nutridex device =
    column
        [ width fill
        , height fill
        ]
        [ nutriDexTitleMaker "BIBLIOGRAPHY"
        , column
            [ width fill
            , F.size 15
            , spacing 10
            , paddingEach
                { top = 20
                , right = 0
                , bottom = 0
                , left = 0
                }
            ]
          <|
            List.map2 (\x y -> makeReference x y)
                nutridex.nutriDexReference
                (List.range 1 (List.length nutridex.nutriDexReference))
        ]
