import { Interval } from 'date-fns'
import { useContext } from 'react'

import { DateData } from '../DateData'
import {
  EngagementMetric,
  engagementMetrics,
} from '../components/videoEngagement'
import { ArtistContext } from '../contexts/ArtistContext'
import { GraphQLContext } from '../contexts/GraphQLContext'
import { streamsSummary } from '../streams'
import {
  intervalToStrings,
  previousInterval as getPreviousInterval,
} from '../util/date'

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

/**
 *
 * @param videoId
 * @param currentInterval
 * @returns Summary of video engagement and change for current and previous interval
 */
export function useEngagementSummary(
  videoId: string,
  currentInterval: Interval,
  market?: string
): EngagementSummary | null {
  const previousInterval = getPreviousInterval(currentInterval)

  const g = useContext(GraphQLContext)
  const artist = useContext(ArtistContext)

  const variables = {
    artistId: artist.sonyArtistId,
    videoId,
    intervalMetricQueries: [currentInterval, previousInterval].map(
      (interval) => ({
        market: market ?? 'worldwide',
        interval: intervalToStrings(interval),
      })
    ),
  }

  const cacheKey = [
    'videoEngagement',
    videoId,
    ...Object.values(intervalToStrings(currentInterval)),
    market,
  ].join('/')

  const videoEngagementResponse = g.useGetArtistVideoEngagement(
    cacheKey,
    variables,
    {
      shouldRetryOnError: false,
    }
  )

  if (videoEngagementResponse.data?.artist?.video == null) {
    return null
  } else {
    const metrics = videoEngagementResponse.data.artist.video.metrics
    const summaries = engagementMetrics.map((metric) => {
      const [currentIntervalMetric, previousIntervalMetric] = metrics.map(
        (interval) =>
          interval.map((dayData) => ({
            date: dayData.date,
            data: dayData[metric],
          }))
      )

      const summary = streamsSummary(
        currentIntervalMetric,
        previousIntervalMetric
      )

      return [
        metric,
        {
          currentIntervalSum: summary.currentIntervalStreamsSum,
          changePercentage: summary.changePercentage,
          currentValues: summary.currentIntervalStreams,
        },
      ]
    })

    return Object.fromEntries(summaries)
  }
}
