import csvWriter from 'csv-write-stream'
import Promise from 'bluebird'

import config from 'src/config'
import graphQLFetcher from 'src/server/util/graphql'
import {Chapter, Player} from 'src/server/services/dataService'
import getUserSummary from 'src/common/actions/queries/getUserSummary'
import {addPointInTimeOverallStats} from 'src/common/util/userProjectStatsCalculations'
import {STAT_DESCRIPTORS} from 'src/common/models/stat'

const {
  CHALLENGE,
  CULTURE_CONTRIBUTION,
  ELO,
  ESTIMATION_ACCURACY,
  ESTIMATION_BIAS,
  EXPERIENCE_POINTS,
  LEVEL,
  PROJECT_HOURS,
  RELATIVE_CONTRIBUTION,
  TEAM_PLAY,
  TECHNICAL_HEALTH,
} = STAT_DESCRIPTORS

export default function requestHandler(req, res) {
  const {chapter} = req.query
  const writer = csvWriter()
  writer.pipe(res)

  return runReport(writer, chapter)
    .then(() => writer.end())
}

async function runReport(writer, chapterName = 'Oakland') {
  const fetcher = graphQLFetcher(config.server.baseURL)
  const [chapter] = await Chapter.filter(row => row('name').match(`(?i)${chapterName}`))
  const players = await Player.filter({chapterId: chapter.id})

  await Promise.mapSeries(players, async player => {
    const playerCycles = await cyclesForPlayer(player, fetcher)
    playerCycles.forEach(cycle => writer.write(cycle))
  })
}

async function cyclesForPlayer(player, fetcher) {
  const result = await fetcher(getUserSummary(player.id))
  const {getUserSummary: userSummary} = result.data
  const {userProjectSummaries: projectSummaries} = userSummary
  const summariesWithPointInTimeStats = addPointInTimeOverallStats(projectSummaries)
  const playerColumns = {
    name: userSummary.user.name,
    handle: userSummary.user.handle,
    active: userSummary.user.active,
    id: player.id.split('-')[0],
  }

  return summariesWithPointInTimeStats.map(summary => ({
    ...playerColumns,
    ..._presentProjectSummary(summary)
  }))
}

function _presentProjectSummary(projectSummary) {
  const statNames = [
    CHALLENGE,
    CULTURE_CONTRIBUTION,
    ELO,
    ESTIMATION_ACCURACY,
    ESTIMATION_BIAS,
    EXPERIENCE_POINTS,
    PROJECT_HOURS,
    RELATIVE_CONTRIBUTION,
    TEAM_PLAY,
    TECHNICAL_HEALTH,
  ]
  const projectOnlyStatNames = [
    PROJECT_HOURS,
  ]

  /* eslint-disable camelcase */
  const projectLevel = projectSummary.userProjectStats[LEVEL] || {}
  const columns = {
    cycle: projectSummary.project.cycle.cycleNumber,
    project_levelStarting: projectLevel.starting || '',
    project_levelEnding: projectLevel.ending || '',
    overall_level: projectSummary.overallStats[LEVEL],
  }
  statNames.forEach(statName => {
    columns[`project_${statName}`] = projectSummary.userProjectStats[statName]
    if (projectOnlyStatNames.indexOf(statName) < 0) {
      columns[`overall_${statName}`] = projectSummary.overallStats[statName]
    }
  })

  return columns
}

@@ -552,30 +552,152 @@
 ,%0A  
-LEVEL,%0A  PROJECT_HOURS
+EXTERNAL_PROJECT_REVIEW_COUNT,%0A  INTERNAL_PROJECT_REVIEW_COUNT,%0A  LEVEL,%0A  PROJECT_HOURS,%0A  PROJECT_REVIEW_ACCURACY,%0A  PROJECT_REVIEW_EXPERIENCE
 ,%0A  
@@ -1896,16 +1896,636 @@
 -')%5B0%5D,%0A
+    %5BLEVEL%5D: userSummary.user.stats%5BLEVEL%5D,%0A    %5BCHALLENGE%5D: userSummary.user.stats%5BCHALLENGE%5D,%0A    %5BELO%5D: userSummary.user.stats%5BELO%5D,%0A    %5BESTIMATION_ACCURACY%5D: userSummary.user.stats%5BESTIMATION_ACCURACY%5D,%0A    %5BESTIMATION_BIAS%5D: userSummary.user.stats%5BESTIMATION_BIAS%5D,%0A    %5BPROJECT_REVIEW_EXPERIENCE%5D: userSummary.user.stats%5BPROJECT_REVIEW_EXPERIENCE%5D,%0A    %5BPROJECT_REVIEW_ACCURACY%5D: userSummary.user.stats%5BPROJECT_REVIEW_ACCURACY%5D,%0A    %5BEXTERNAL_PROJECT_REVIEW_COUNT%5D: userSummary.user.stats%5BEXTERNAL_PROJECT_REVIEW_COUNT%5D,%0A    %5BINTERNAL_PROJECT_REVIEW_COUNT%5D: userSummary.user.stats%5BINTERNAL_PROJECT_REVIEW_COUNT%5D,%0A
   %7D%0A%0A  r
@@ -3445,16 +3445,17 @@
     if (
+!
 projectO
@@ -3473,13 +3473,14 @@
 s.in
-dexOf
+cludes
 (sta
@@ -3489,12 +3489,8 @@
 ame)
- %3C 0
 ) %7B%0A

add top-level stats as first columns in report