{-# Language OverloadedStrings #-}
{-|
Module      : Client.View.ChannelList
Description : Line renderer for searchable channel lists
Copyright   : (c) TheDaemoness, 2023
License     : ISC
Maintainer  : emertens@gmail.com

This module renders the lines used in the channel user list.
-}
module Client.View.ChannelList ( channelListLines ) where

import           Client.Image.LineWrap (lineWrapPrefix)
import           Client.Image.Message (IdentifierColorMode(NormalIdentifier), coloredIdentifier)
import           Client.Image.PackedImage
import           Client.Image.Palette
import           Client.State
import           Client.State.Network
import           Control.Lens
import           Data.Text (Text)
import qualified Data.Text as Text
import           Graphics.Vty.Attributes (defAttr)
import           Irc.Identifier
import qualified Data.HashMap.Strict as HashMap
import Client.State.Focus (Subfocus(FocusChanList))

-- |
-- | Render the lines used by the @/list@ command in normal mode.
channelListLines ::
  Text        {- ^ network           -} ->
  Int         {- ^ window width      -} ->
  ClientState {- ^ client state      -} ->
  (Maybe Int, Maybe Int) {- ^ bounds -} ->
  [Image']
channelListLines network width st bounds =
  case preview (clientConnection network) st of
    Just cs -> channelListLines' cs width st bounds
    Nothing -> [text' (view palError pal) "No connection"]
  where
    pal = clientPalette st

channelListLines' ::
  NetworkState ->
  Int -> ClientState -> (Maybe Int, Maybe Int) -> [Image']
channelListLines' cs width st (min', max')
  | chanList^.clsDone = countImage <> queryPart : images
  | otherwise = countImagePending <> queryPart : images
  where
    chanList = cs^.csChannelList
    els = chanList^.clsElist
    pal = clientPalette st

    countImagePending = countImage <> text' (view palLabel pal) "..."
    countImage = text' (view palLabel pal) "Channels (visible/total): " <>
                 string defAttr (show (length entries')) <>
                 char (view palLabel pal) '/' <>
                 string defAttr (show (length entries))

    queryPart = mconcat $
      [text' (view palLabel pal) " More-than: " <> string defAttr (show lo) | FocusChanList _ (Just lo) _ <- [st^.clientSubfocus]] ++
      [text' (view palLabel pal) " Less-than: " <> string defAttr (show hi) | FocusChanList _ _ (Just hi) <- [st^.clientSubfocus]] ++
      [text' (view palLabel pal) " Elist: " <> text' defAttr txt | Just txt <- [els], not (Text.null txt)]

    entries = chanList^.clsItems
    entries' = clientFilterChannels st min' max' entries

    images = concatMap listItemImage entries'

    listItemImage :: (Identifier, Int, Text) -> [Image']
    listItemImage (chan, users, topic)
      | Text.null topic = [baseImage]
      | otherwise = reverse $ lineWrapPrefix width (baseImage <> label " topic:") (text' defAttr topic)
      where
        chanImage = coloredIdentifier pal NormalIdentifier HashMap.empty chan
        baseImage = chanImage <> label " users: " <> text' defAttr (Text.pack . show $ users)
        label = text' (view palLabel pal)
