module Data.TTask.Analysis 
  ( DailyStatuses(..)
  , dailyGroup
  , summaryPointBy 
  ) where
import Control.Lens
import Data.List
import Data.Maybe
import Data.Time
import Data.TTask.Types

data DailyStatuses = DailyStatuses
  { dayStDay :: Day
  , dayStPoint :: Point
  , dayStStatuses :: [StatusLogRec]
  }

dailyGroup :: [StatusLogRec] -> [DailyStatuses]
dailyGroup = catMaybes . map sr2ds . dailyGrouping 
  where
    sr2ds :: [StatusLogRec] -> Maybe DailyStatuses
    sr2ds srs = do
      (d, p) <- calcDaylyPoint srs
      return $ DailyStatuses
        { dayStDay = d
        , dayStPoint = p
        , dayStStatuses = srs
        }

----

calcDaylyPoint :: [StatusLogRec] -> Maybe (Day, Point)
calcDaylyPoint [] = Nothing
calcDaylyPoint xs@(x:_) = Just . (,) (getDay x) $ summaryPointBy isFinishedTask xs
  where
    isFinishedTask :: StatusLogRec -> Bool
    isFinishedTask r 
      = r^.getLogStatus.isFinished && r^.getLogContents.isTask

dailyGrouping :: [StatusLogRec] -> [[StatusLogRec]]
dailyGrouping = groupBy (\l r -> getDay l == getDay r) . sortRecord
  where
    sortRecord :: [StatusLogRec] -> [StatusLogRec]
    sortRecord = sortBy (\l r -> getTime l `compare` getTime r)

----

summaryPointBy :: (StatusLogRec -> Bool) -> [StatusLogRec] -> Point
summaryPointBy f = foldl (+) 0 . map getPoint . filter f 

getDay :: StatusLogRec -> Day
getDay = localDay . getTime

getTime :: StatusLogRec -> LocalTime
getTime = (^.getLogStatus.getStatusTime)

getPoint :: StatusLogRec -> Point
getPoint = (^.getLogContents.point)