// -----------------------------------------------------------------
// CONFIG
// -----------------------------------------------------------------

const cols = process.stdout.columns
// const rows = process.stdout.rows
const colWidth = 40
const maxStatLength = colWidth // Math.floor(cols / 4)
const statNameSpacing = 4
const beforeRowSpace = 13
const colsToPrint =
  Math.floor(cols / (colWidth + statNameSpacing + beforeRowSpace / 3 + 5)) || 1
const coloredWords = {
  red: ['lred', 'thanks'],
  cyan: [
    'getveteranpw',
    'pwrequest',
    'getpw',
    'availablepws',
    'login',
    'logout',
  ],
  green: [
    'manual',
    'todos',
    'allquestions',
    'subjectbrowser',
    'contribute',
    'feedback',
    'ranklist',
    'allqr',
    'possibleAnswers',
    'faq',
    '/script',
    'listUserDir',
    'forumEntries',
    'contacts.json',
    'patreon',
    'donate',
    'userfiles',
  ],
  blue: [
    'isadding',
    'react',
    'ask',
    'newUserDir',
    'updateQuestion',
    'uploadUserFile',
    'votetodo',
    'registerscript',
    'install',
  ],
  magenta: ['addPost', 'comment', 'postfeedback', 'quickvote'],
}
const filterFromDailyStats = [
  'savedQuestions',
  'sio/f',
  'sound/',
  '/img/',
  '.php',
  '/wordpress/',
  '/wp/',
  '/wp-includes/',
  'favicon',
  'robots.txt',
  'ads.txt',
  '/f/',
  '.git',
  'apple-touch-icon',
  '/.env',
  '/userFiles/',
  '.min.js',
  '.xml',
  '.aspx',
  '/questionDbs/',
]

// -----------------------------------------------------------------

const fs = require('fs') // eslint-disable-line

const dir = process.argv[2]
if (!dir) {
  console.log('No params')
  process.exit()
}

function getDayIndex(offset) {
  if (!offset) {
    offset = 0
  }

  const date = new Date()
  if (offset) {
    date.setDate(date.getDate() + offset)
  }
  return (
    date.getFullYear() +
    '-' +
    ('0' + (date.getMonth() + 1)).slice(-2) +
    '-' +
    ('0' + date.getDate()).slice(-2)
  )
}

function hr(char) {
  console.log(C('blue') + getLetterNTimes(char || '=', cols) + C())
}

function printHeader(text) {
  hr()
  console.log(C('green') + text + C())
  hr()
}

function C(color) {
  if (color !== undefined) {
    color = color.toLowerCase()
  }

  if (color === 'redbg') {
    return '\x1b[41m'
  }
  if (color === 'bluebg') {
    return '\x1b[44m'
  }
  if (color === 'green') {
    return '\x1b[32m'
  }
  if (color === 'red') {
    return '\x1b[31m'
  }
  if (color === 'yellow') {
    return '\x1b[33m'
  }
  if (color === 'blue') {
    return '\x1b[34m'
  }
  if (color === 'magenta') {
    return '\x1b[35m'
  }
  if (color === 'cyan') {
    return '\x1b[36m'
  }
  return '\x1b[0m'
}

function readJSON(name) {
  return JSON.parse(fs.readFileSync(name, 'utf8'))
}

function tail(text, number) {
  const splitedText = text.split('\n')
  return splitedText.slice(Math.max(splitedText.length - number, 1)).join('\n')
}

function head(text, number) {
  return text.split('\n').slice(0, number).join('\n')
}

function countLinesMatching(text, toMatch) {
  let count = 0
  text.split('\n').forEach((line) => {
    if (line.includes(toMatch.toLowerCase())) {
      count++
    }
  })
  return count
}

function getDayName(day) {
  switch (day) {
    case 0:
    case undefined:
      return 'Today'
    case -1:
      return 'Yesterday'
    case -2:
      return 'Before yesterday'
    default:
      return `Day ${day.toString()}`
  }
}

function readFile(name) {
  if (fs.existsSync(name)) {
    return fs.readFileSync(name, 'utf8')
  }
}

function getLetterNTimes(letter, number) {
  let res = ''
  while (res.length < number) {
    res += letter
  }
  return res
}

function pCols(cols, rowTitles, colorNames, firstRowColor) {
  // console.log(cols)
  let maxLength = 0
  cols.reverse().forEach((col, i) => {
    if (i >= colsToPrint) {
      return
    }
    if (col.length > maxLength) {
      maxLength = col.length
    }
  })

  cols.reverse()

  for (let i = 0; i < maxLength; i++) {
    const row = []

    cols.forEach((val, colIndex) => {
      if (colIndex >= colsToPrint) {
        return
      }
      if (!val[i]) {
        row.push(getLetterNTimes(' ', maxStatLength + statNameSpacing + 2))
        return
      }

      const keyName = val[i].name || val[i]

      let slicedName = keyName.slice(0, maxStatLength)
      const toColor = colorNames
        ? Object.keys(coloredWords).reduce((acc, key) => {
            const colorArray = coloredWords[key]

            const includes = colorArray.some((colorableIdName) => {
              return keyName
                .toLowerCase()
                .includes(colorableIdName.toLowerCase())
            })

            if (includes) {
              return key
            }

            return acc
          }, '')
        : false

      const sep = (i + 1) % 5 === 0 ? '.' : ' '

      while (slicedName.length < maxStatLength) {
        slicedName = slicedName + sep
      }

      let ammount = val[i].val ? val[i].val.toString() : ''
      while (ammount.length < 5) {
        ammount = ammount + ' '
      }

      if (toColor) {
        row.push(C(toColor) + slicedName + ' ' + ammount + C())
      } else {
        row.push(slicedName + ' ' + ammount)
      }
    })

    // ROW TITLE ---------------------------------------------------
    let currRowTitle =
      rowTitles && rowTitles[i]
        ? rowTitles[i]
        : getLetterNTimes(' ', beforeRowSpace)

    while (currRowTitle.length < beforeRowSpace) {
      currRowTitle = currRowTitle + ' '
    }
    currRowTitle = C('blue') + currRowTitle + C()
    // COLORING ----------------------------------------------------
    let res = ''
    if (firstRowColor && i === 0) {
      res =
        currRowTitle +
        C('green') +
        row.join(getLetterNTimes(' ', statNameSpacing)) +
        C()
    } else {
      res = currRowTitle + row.join(getLetterNTimes(' ', statNameSpacing))
    }
    // SHOW DIFF ---------------------------------------------------
    console.log(res)
  }
}

// ------------------------------------------------------------------------------
printHeader('Daily stats')

const dailyStats = readJSON(`${dir}stats/vstats`)
function preProcessDailyStats(obj) {
  const formatted = Object.keys(obj).reduce((acc, key) => {
    const includes = filterFromDailyStats.some((keyword) => {
      return key.toLowerCase().includes(keyword.toLowerCase())
    })
    if (!includes) {
      acc.push({ name: key.replace(/\.html/g, ''), val: obj[key] })
    }
    return acc
  }, [])

  const merged = formatted.reduce((acc, x) => {
    const index = acc.findIndex((y) => {
      return x.name === y.name
    })

    if (index !== -1) {
      acc = acc.map((z, i) => {
        if (i === index) {
          return {
            ...x,
            val: z.val + x.val,
          }
        }
        return z
      })
    } else {
      acc.push(x)
    }

    return acc
  }, [])

  return merged.sort((a, b) => {
    if (a.name > b.name) {
      return 1
    } else if (a.name < b.name) {
      return -1
    } else {
      return 0
    }
  })
}
function getDailyStat(day) {
  return preProcessDailyStats(dailyStats[getDayIndex(day)])
}

pCols(
  [
    ...[...Array(colsToPrint).keys()].map((x) => {
      return getDailyStat(-x)
    }),
  ],
  null,
  true
)

// ------------------------------------------------------------------------------
printHeader('User id test solving')
const userIdTestSolving = readJSON(`${dir}stats/idvstats`)
function preProcessUIdTestSolving(obj, minLength) {
  if (!obj) {
    return '0'
  }
  if (minLength) {
    return Object.keys(obj)
      .filter((key) => {
        return obj[key] > minLength
      })
      .length.toString()
  } else {
    return Object.keys(obj).length.toString()
  }
}
function getUserIdTestSolving(day) {
  return [
    getDayName(day),
    preProcessUIdTestSolving(userIdTestSolving[getDayIndex(day)]),
  ]
}

pCols(
  [
    ...[...Array(colsToPrint).keys()].map((x) => {
      return getUserIdTestSolving(-x)
    }),
  ],
  null,
  false,
  'green'
)

// ------------------------------------------------------------------------------
printHeader('User id requests')
const clientIdTestSolving = readJSON(`${dir}stats/uvstats`)
function getUserIdRequests(day) {
  return [
    getDayName(day),
    preProcessUIdTestSolving(clientIdTestSolving[getDayIndex(day)]),
    preProcessUIdTestSolving(clientIdTestSolving[getDayIndex(day)], 5),
  ]
}

pCols(
  [
    ...[...Array(colsToPrint).keys()].map((x) => {
      return getUserIdRequests(-x)
    }),
  ],
  ['', 'All', 'More than 5'],
  false,
  'green'
)

// ------------------------------------------------------------------------------
printHeader('Daily data count')
const dailyDataCount = readFile(`${dir}stats/dailyDataCount`)
function getDailyDataCount(count) {
  return [...Array(count).keys()].map((x) => {
    return JSON.parse(head(tail(dailyDataCount, x + 1), 1))
  })
}

printLastDataCount(getDailyDataCount(colsToPrint))

function printLastDataCount(data) {
  const res = [...Array(colsToPrint).keys()].map((x) => {
    return [getDayName(-x)]
  })
  data.forEach((dataCount, i) => {
    res[i].push(dataCount.userCount.toString())
    res[i].push(dataCount.subjectCount.toString())
    res[i].push(dataCount.questionCount.toString())
  })

  pCols(res, ['', 'Users', 'Subjects', 'Questions'], false, 'green')
}
// ------------------------------------------------------------------------------
printHeader('Daily script install / update check count')
function getDailyScriptStat(day) {
  const log =
    !day || day === 0
      ? readFile(`${dir}stats/vlogs/log`)
      : readFile(`${dir}stats/vlogs/${getDayIndex(day)}`)

  if (!log) {
    return [getDayName(day), 0, 0]
  }
  return [
    getDayName(day),
    countLinesMatching(log, '?install').toString(),
    countLinesMatching(log, '?up').toString(),
  ]
}

const installs = [...Array(colsToPrint).keys()].map((x) => {
  return getDailyScriptStat(-x)
})

pCols(installs, ['', 'Installs', 'Updates'], false, 'green')