const config = require('./config.json')
const df = require('date-format')
const fs = require('fs')
const Gitlab = require('gitlab/dist/es5').default
const klaw = require('klaw-sync')
const path = require('path')
const api = new Gitlab({
  token: config.token
})
const months = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December'
]
const year =  new Date().getFullYear().toString()
const month = months[new Date().getMonth()]
if (!fs.existsSync(path.join(__dirname, year))) fs.mkdirSync(path.join(__dirname, year))
if (!fs.existsSync(path.join(__dirname, year, month))) fs.mkdirSync(path.join(__dirname, year, month))
const openedPath = path.join(__dirname, year, month, 'Opened')
const closedPath = path.join(__dirname, year, month, 'Closed')
if (!fs.existsSync(openedPath)) fs.mkdirSync(openedPath)
if (!fs.existsSync(closedPath)) fs.mkdirSync(closedPath)
let args = ''
for (const arg of process.argv) {
  args += arg + ' '
}
if (!args.includes('--no-download')) download()
else {
  createTable()
  createStatistics()
}
function download() {
  api.Projects
    .show('tildes/tildes')
    .then((project) => {
      api.Issues
        .all({
          projectId: project.id
        })
        .then((issues) => {
          for (const issue of issues) {
            if (new Date(issue.created_at).getMonth() === new Date().getMonth()) {
              fs.writeFileSync(path.join(openedPath, issue.iid.toString()) + '.json', JSON.stringify(issue, null, 2))
            }
            if (new Date(issue.closed_at).getMonth() === new Date().getMonth()) {
              fs.writeFileSync(path.join(closedPath, issue.iid.toString()) + '.json', JSON.stringify(issue, null, 2))
            }
          }
        })
        .then(createTable)
        .then(createStatistics)
    })
}
function createTable() {
  let opened = klaw(openedPath)
  let closed = klaw(closedPath)
  opened.sort(function(a,b) {
    const aFile = require(a.path)
    const bFile = require(b.path)
    return (aFile.iid > bFile.iid) ? 1 : ((bFile.iid > aFile.iid) ? -1 : 0)
  })
  closed.sort(function(a,b) {
    const aFile = require(a.path)
    const bFile = require(b.path)
    return (aFile.iid > bFile.iid) ? 1 : ((bFile.iid > aFile.iid) ? -1 : 0)
  })
  let table = '## Issue Table\n'
  table += '\n### Opened\n\n'
  table += '| Issue | Title | Author | Opened | Closed |\n'
  table += '| ----- | ----- | ------ | ------ | ------ |\n'
  for (const file of opened) {
    const issue = require(file.path)
    table += `| ${issue.iid} |`
    let title
    if (issue.title.length >= 50) {
      title = issue.title.substring(0, 47) + '...'
    } else {
      title = issue.title
    }
    table += ` ${title} |`
    table += ` ${issue.author.username} |`
    table += ` ${df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.created_at))} |`
    let closedAt
    if (issue.closed_at === null) {
      closedAt = ''
    } else {
      closedAt = df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.closed_at))
    }
    table += ` ${closedAt} |\n`
  }
  table += '\n### Closed\n\n'
  table += '| Issue | Title | Author | Opened | Closed |\n'
  table += '| ----- | ----- | ------ | ------ | ------ |\n'
  for (const file of closed) {
    const issue = require(file.path)
    table += `| ${issue.iid} |`
    let title
    if (issue.title.length >= 50) {
      title = issue.title.substring(0, 47) + '...'
    } else {
      title = issue.title
    }
    table += ` ${title} |`
    table += ` ${issue.author.username} |`
    table += ` ${df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.created_at))} |`
    let closedAt
    if (issue.closed_at === null) {
      closedAt = ''
    } else {
      closedAt = df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.closed_at))
    }
    table += ` ${closedAt} |\n`
  }
  if (!fs.existsSync(path.join(__dirname, year, month, 'post.md')))
    fs.copyFileSync(path.join(__dirname, 'template.md'), path.join(__dirname, year, month, 'post.md'))
  fs.writeFileSync(path.join(__dirname, year, month, 'table.md'), table, {encoding: 'UTF-8'})
}
function createStatistics() {
  let opened = klaw(openedPath)
  let closed = klaw(closedPath)
  let statistics = '## Statistics\n\n'
  statistics += `In the month of ${month} `
  statistics += `${opened.length} issues were opened and `
  statistics += `${closed.length} issues were closed.\n\n`
  const averageOpenPerDay = (opened.length / 30).toFixed(2)
  const averageClosePerDay = (closed.length / 30).toFixed(2)
  statistics += `An average of ${averageOpenPerDay} issues were opened `
  statistics += `and ${averageClosePerDay} issues were closed each day.\n\n`
  let averageClosedDays
  let averageClosedHours
  for (const file of closed) {
    const issue = require(file.path)
    const openedAt = new Date(issue.created_at)
    const closedAt = new Date(issue.closed_at)
    const diffDays = (closedAt - openedAt) / (1000 * 60 * 60 * 24)
    const diffHours = (closedAt - openedAt) / (1000 * 60 * 60)
    averageClosedDays = (typeof averageClosedDays === 'undefined')
      ? averageClosedDays = diffDays
      : averageClosedDays += diffDays
    averageClosedHours = (typeof averageClosedHours === 'undefined')
      ? averageClosedHours = diffHours
      : averageClosedHours += diffHours
  }
  averageClosedDays = (averageClosedDays / closed.length).toFixed(2)
  averageClosedHours = (averageClosedHours / closed.length).toFixed(2)
  statistics += `The average time to close issues was ${averageClosedDays} days `
  statistics += `or ${averageClosedHours} hours.\n\n`
  let _mostFrequent = {}
  for (const file of opened) {
    const issue = require(file.path)
    if (typeof _mostFrequent[issue.author.username] === 'undefined') _mostFrequent[issue.author.username] = 1
    else _mostFrequent[issue.author.username]++
  }
  let mostFrequent = Object.keys(_mostFrequent)
  mostFrequent.sort((a, b) => _mostFrequent[b] - _mostFrequent[a])
  mostFrequent = mostFrequent.slice(0, 3)
  statistics += 'Most frequent issue creators:\n\n'
  for (const user of mostFrequent) {
    statistics += `* [${user}](https://gitlab.com/${user}) `
    statistics += `with [${_mostFrequent[user]} issues created](https://gitlab.com/tildes/tildes/issues?state=all&author_username=${user}).\n`
  }
  let labels = {}
  for (const file of opened) {
    const issue = require(file.path)
    if (issue.closed_at !== null) continue
    for (const label of issue.labels) {
      if (typeof labels[label] === 'undefined') labels[label] = 1
      else labels[label]++
    }
  }
  let labelsOrdered = {}
  Object.keys(labels).sort().forEach(label => labelsOrdered[label] = labels[label])
  statistics += '\nTotal amount of labels assigned to currently open issues:\n\n'
  for (const label in labelsOrdered) {
    statistics += `* [${label}](https://gitlab.com/tildes/tildes/issues?state=opened&label_name%5B%5D=${label.replace(' ', '+')}): ${labels[label]} times.\n`
  }
  labels = {}
  for (const file of closed) {
    const issue = require(file.path)
    for (const label of issue.labels) {
      if (typeof labels[label] === 'undefined') labels[label] = 1
      else labels[label]++
    }
  }
  labelsOrdered = {}
  Object.keys(labels).sort().forEach(label => labelsOrdered[label] = labels[label])
  statistics += '\nTotal amount of labels assigned to closed issues:\n\n'
  for (const label in labelsOrdered) {
    statistics += `* [${label}](https://gitlab.com/tildes/tildes/issues?state=closed&label_name%5B%5D=${label.replace(' ', '+')}): ${labels[label]} times.\n`
  }
  fs.writeFileSync(path.join(__dirname, year, month, 'statistics.md'), statistics, {encoding: 'UTF-8'})
}