import { Interval } from 'date-fns'
import * as _ from 'lodash'
import { useContext } from 'react'
import { useNetwork } from '../components/useNetwork'
import { EngagementMetric } from '../components/videoEngagement'
import { ArtistContext } from '../contexts/ArtistContext'
import { UserContext } from '../contexts/UserContext'
import { DateData } from '../DateData'
import { periodToPeriodChangePercentage } from '../streams'
import { intervalDates, toQueryString } from '../util'
import { previousInterval as getPreviousInterval } from '../util/date'
import { useCacheKey } from './useCacheKey'

interface VideoEngagementResponse {
  engagement: DateData<{
    likes: number
    dislikes: number
    comments: number
  } | null>[]
}

export function useVideoEngagement(
  videoId: string,
  interval: Interval,
  countryCode?: string
) {
  const user = useContext(UserContext)
  const artist = useContext(ArtistContext)
  const { startDate, endDate } = intervalDates(interval)
  const query = toQueryString({
    startDate,
    endDate,
    countryCode: countryCode ?? null,
  })
  const path = `api/artists/${artist.sonyArtistId}/videos/${videoId}/engagement?${query}`
  const response = useNetwork<VideoEngagementResponse>(path, user, () => {})

  useCacheKey(path)

  return {
    ...response,
    startDate,
    endDate,
  }
}

export type EngagementSummary = Record<
  EngagementMetric,
  {
    currentIntervalSum: number
    changePercentage: number
    currentValues: DateData<number>[]
  }
>

/**
 *
 * @param videoId
 * @param currentInterval
 * @returns Summary of video engagement and change for current and previous interval
 */
export function useEngagementSummary(
  videoId: string,
  currentInterval: Interval,
  countryCode?: string
): EngagementSummary | null {
  const previousInterval = getPreviousInterval(currentInterval)
  const currentIntervalResponse = useVideoEngagement(
    videoId,
    currentInterval,
    countryCode
  )
  const currentIntervalEngagement =
    currentIntervalResponse.data?.engagement ?? null
  const previousIntervalResponse = useVideoEngagement(
    videoId,
    previousInterval,
    countryCode
  )
  const previousIntervalEngagement =
    previousIntervalResponse.data?.engagement ?? null

  if (
    previousIntervalEngagement !== null &&
    currentIntervalEngagement !== null
  ) {
    const summaryForMetric = (metric: EngagementMetric) => {
      const currentValues = currentIntervalEngagement.map((day) => ({
        date: day?.date,
        data: day?.data?.[metric],
      }))

      const currentPeriodByDay = currentIntervalEngagement.map(
        (day) => day?.data?.[metric]
      )

      const previousPeriodByDay = previousIntervalEngagement.map(
        (day) => day?.data?.[metric]
      )

      const valuesByDay = {
        currentPeriodByDay,
        previousPeriodByDay,
      }

      return {
        currentIntervalSum: _.sum(valuesByDay.currentPeriodByDay),
        changePercentage: periodToPeriodChangePercentage(valuesByDay),
        currentValues: currentValues,
      }
    }

    return {
      likes: summaryForMetric('likes'),
      dislikes: summaryForMetric('dislikes'),
      comments: summaryForMetric('comments'),
    }
  } else {
    return null
  }
}
