{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}

module Web.Slack.Types.Message where

import Data.Aeson
import Data.Aeson.TH
import qualified Data.Text as T
import Data.Time.Clock.POSIX
import GHC.Generics
import Web.Slack.Types.Base
import Web.Slack.Types.Id
import Web.Slack.Utils

data MessagePayload = MessagePayload
    { messageId      :: Int
    , messageType    :: T.Text
    , messageChannel :: ChannelId
    , messageText    :: T.Text
    } deriving (Show)

data PingPayload = PingPayload
    { pingId        :: Int
    , pingType      :: T.Text
    , pingTimestamp :: Int
    } deriving (Show)

data Attachment = Attachment
    { attachmentFallback :: T.Text
        -- ^ A plain-text summary of the attachment.
    , attachmentColor :: AttachmentColor
        -- ^ Used to color the border along the left side of the message
        -- attachment.
    , attachmentPretext :: Maybe T.Text
        -- ^ Optional text that appears above the message attachment block.
    , attachmentAuthorName :: Maybe T.Text
        -- ^ Small text used to display the author's name.
    , attachmentAuthorLink :: Maybe URL
        -- ^ A valid URL that will hyperlink the author_name text mentioned
        -- above.
    , attachmentAuthorIcon :: Maybe URL
        -- ^ A valid URL that displays a small 16x16px image to the left of
        -- the author_name text.
    , attachmentTitle :: Maybe T.Text
        -- ^ The title is displayed as larger, bold text near the top of
        -- a message attachment.
    , attachmentTitleLink :: Maybe URL
        -- ^ By passing a valid URL, the title text will be hyperlinked.
    , attachmentText :: Maybe T.Text
        -- ^ This is the main text in a message attachment, and can contain
        -- standard message markup.
    , attachmentFields :: [Field]
    , attachmentImageUrl :: Maybe URL
        -- ^ An image file that will be displayed inside a message
        -- attachment. GIF, JPEG, PNG, or BMP; scaled down to 400x500px.
    , attachmentThumbUrl :: Maybe URL
        -- ^ Displayed as a thumbnail on the right side of a message
        -- attachment. GIF, JPEG, PNG, or BMP; scaled down to 75x75px.
    , attachmentFooter :: Maybe T.Text
        -- ^ Add some brief text to help contextualize and identify an
        -- attachment.
    , attachmentFooterIcon :: Maybe URL
        -- ^ Render a small icon beside your footer text. Scaled to 16x16px.
    , attachmentTs :: Maybe POSIXTime
        -- ^ Display an additional timestamp value as part of the
        -- attachment's footer.
    }

data Field = Field
    { fieldTitle :: Maybe T.Text
        -- ^ Shown as a bold heading above the value text. It cannot
        -- contain markup and will be escaped for you.
    , fieldValue :: T.Text
        -- ^ The text value of the field. It may contain standard message
        -- markup and must be escaped as normal. May be multi-line.
    , fieldShort :: Bool
        -- ^ Whether the value is short enough to be displayed side-by-side
        -- with other values.
    }

data AttachmentColor
    = DefaultColor       -- grey
    | GoodColor          -- green
    | WarningColor       -- yellow
    | DangerColor        -- red
    | CustomColor T.Text -- hexadecimal RGB colour, eg. CustomColor "#439FE0"
    deriving (Generic)

defaultAttachment :: Attachment
defaultAttachment = Attachment
        { attachmentFallback = ""
        , attachmentColor = DefaultColor
        , attachmentPretext = Nothing
        , attachmentAuthorName = Nothing
        , attachmentAuthorLink = Nothing
        , attachmentAuthorIcon = Nothing
        , attachmentTitle = Nothing
        , attachmentTitleLink = Nothing
        , attachmentText = Nothing
        , attachmentFields = []
        , attachmentImageUrl = Nothing
        , attachmentThumbUrl = Nothing
        , attachmentFooter = Nothing
        , attachmentFooterIcon = Nothing
        , attachmentTs = Nothing
        }

instance ToJSON AttachmentColor where
    toEncoding x = toEncoding $ case x of
        DefaultColor  -> Nothing
        GoodColor     -> Just "good"
        WarningColor  -> Just "warning"
        DangerColor   -> Just "danger"
        CustomColor c -> Just c

$(deriveToJSON defaultOptions {fieldLabelModifier = toSnake . drop 7}  ''MessagePayload)
$(deriveToJSON defaultOptions {fieldLabelModifier = toSnake . drop 4}  ''PingPayload)
$(deriveToJSON defaultOptions {fieldLabelModifier = toSnake . drop 10} ''Attachment)
$(deriveToJSON defaultOptions {fieldLabelModifier = toSnake . drop 5}  ''Field)