module Yore.Time (addYears, getCurrentDay, getSecondsUntilMidnight) where

import Data.Text (Text)
import Data.Time
  ( Day
  , addGregorianYearsClip
  , getZonedTime
  , isLeapYear
  , localDay
  , localTimeOfDay
  , sinceMidnight
  , toGregorian
  , zonedTimeToLocalTime
  )
import Text.Printf (printf)

import qualified Data.Text as Text

addYears :: Integer -> Day -> Either Text Day
addYears yearOffset date
  | isFebruary29th && not (isLeapYear year') =
      Left $ Text.pack $ printf "year %d is not a leap year"
  | otherwise =
      Right $ addGregorianYearsClip yearOffset date
  where
    (year, month, day) = toGregorian date
    year' = year + yearOffset

    isFebruary29th = month == 2 && day == 29

getCurrentDay :: IO Day
getCurrentDay = do
  localDay . zonedTimeToLocalTime <$> getZonedTime

getSecondsUntilMidnight :: IO Int
getSecondsUntilMidnight = do
  timeOfDay <- localTimeOfDay . zonedTimeToLocalTime <$> getZonedTime
  pure $ 86400 - ceiling (sinceMidnight timeOfDay)
