content: {-# LANGUAGE OverloadedStrings #-}
  
  -- |
  -- SPDX-License-Identifier: BSD-3-Clause
  module Swarm.TUI.View.Achievement where
  
  import Brick
  import Brick.Widgets.Border (borderWithLabel)
  import Brick.Widgets.Center (hCenter)
  import Brick.Widgets.List qualified as BL
  import Control.Lens ((^.))
  import Data.Map (Map)
  import Data.Map qualified as M
  import Data.Time.Format (defaultTimeLocale, formatTime)
  import Swarm.Game.Achievement.Attainment
  import Swarm.Game.Achievement.Definitions
  import Swarm.Game.Achievement.Description
  import Swarm.TUI.Model
  import Swarm.TUI.View.Attribute.Attr
  import Swarm.TUI.View.Util (drawMarkdown)
  import Text.Wrap
  
  padAllEvenly :: Int -> Widget Name -> Widget Name
  padAllEvenly x w = padTopBottom x $ padLeftRight (2 * x) w
  
  getCompletionIcon :: Bool -> Widget Name
  getCompletionIcon = \case
    False -> txt " ○  "
    True -> withAttr greenAttr $ txt " ●  "
  
  drawAchievementsMenuUI :: AppState -> BL.List Name CategorizedAchievement -> Widget Name
  drawAchievementsMenuUI s l =
    vBox
      [ hCenter $ padTopBottom 1 $ str "🏆  Achievements 🏆 "
      , hCenter $
          hBox
            [ hLimitPercent 30
                . padAll 2
                $ BL.renderList (const $ drawAchievementListItem attainedMap) True l
            , hLimitPercent 50
                . maybe emptyWidget (singleAchievementDetails attainedMap . snd)
                $ BL.listSelectedElement l
            ]
      ]
   where
    attainedMap = s ^. playState . progression . attainedAchievements
  
  drawAchievementListItem ::
    Map CategorizedAchievement Attainment ->
    CategorizedAchievement ->
    Widget Name
  drawAchievementListItem attainedMap x =
    getCompletionIcon wasAttained <+> titleWidget
   where
    wasAttained = M.member x attainedMap
    titleWidget = txtWrap $ title details
    details = describe x
  
  singleAchievementDetails ::
    Map CategorizedAchievement Attainment ->
    CategorizedAchievement ->
    Widget Name
  singleAchievementDetails attainedMap x =
    padRight (Pad 1) . borderWithLabel titleWidget . padRight Max . padAllEvenly 1 $ innerContent
   where
    wasAttained = M.member x attainedMap
  
    renderFlavorTextWidget :: FlavorText -> Widget Name
    renderFlavorTextWidget (Freeform t) = drawMarkdown t
    renderFlavorTextWidget (FTQuotation (Quotation author quoteContent)) =
      vBox
        [ txtWrap quoteContent
        , padLeft Max
            . padRight (Pad 2)
            . txtWrapWith (defaultWrapSettings {fillStrategy = FillIndent 2})
            $ "--" <> author
        ]
  
    innerContent =
      vBox
        [ maybe emptyWidget (padAllEvenly 2 . renderFlavorTextWidget) $ humorousElaboration details
        , if wasAttained || not (isObfuscated details)
            then drawMarkdown $ attainmentProcess details
            else txt "???"
        , case M.lookup x attainedMap of
            Nothing -> emptyWidget
            Just attainment ->
              padTop (Pad 1) $
                vBox
                  [ hBox
                      [ txt "Obtained: "
                      , withAttr cyanAttr
                          . str
                          . formatTime defaultTimeLocale "%l:%M%P on %b %e, %Y"
                          $ attainment ^. obtainedAt
                      ]
                  , flip (maybe emptyWidget) (attainment ^. maybeScenarioPath) $ \s ->
                      hBox
                        [ txt "Scenario: "
                        , withAttr cyanAttr $
                            str s
                        ]
                  ]
        , padTop (Pad 1) $
            hBox
              [ txt "Effort: "
              , withAttr boldAttr . str . show $ effort details
              ]
        ]
  
    titleWidget = padLeftRight 1 $ txt $ title details
    details = describe x
  