import fs from 'fs'
import awaitFs from 'await-fs'
import express from 'express'
import moment from 'moment'
import pdfMake from 'pdfmake/build/pdfmake'
import pdfFonts from 'pdfmake/build/vfs_fonts'
import archiver from 'archiver'
import { places } from '../config/sztm'
import Match from '../swisstennis/models/match'
import MatchList from '../swisstennis/models/matchList'
pdfMake.vfs = pdfFonts.pdfMake.vfs

const sztm = express.Router()

sztm.get('/files', async (req, res) => {
  const dirContent = await awaitFs.readdir('sztm_files')
  const fileList = dirContent.map((filename) => {
    const stats = fs.statSync(`sztm_files/${filename}`)
    return { filename, size: stats.size, mtime: stats.mtime }
  })
  return res.json(fileList)
})

sztm.delete('/files', async (req, res) => {
  try {
    const { filename } = req.body
    fs.unlink(`sztm_files/${filename}`, (error) => {
      if (error) throw error
      res.json({ msg: `successfully deleted sztm_files/${filename}.` })
    })
  } catch (error) {
    return res.status(400).json({ msg: error.toString() })
  }
})

sztm.post('/zip', async (req, res) => {
  try {
    const { date } = req.body
    if (!date) {
      throw Error('date is mandatory.')
    }

    const parsedDate = date.match(/(\d{4}\d{2}\d{2})T\d{2}\d{2}\d{2}/)[1]
    const zipFile = `sztm_file_${parsedDate}.zip`
    const zipStream = fs.createWriteStream(`sztm_files/${zipFile}`)
    const archive = archiver('zip', { zlib: { level: 9 } })

    const stream = new Promise((resolve, reject) => {
      zipStream.on('close', resolve)
      zipStream.on('error', reject)
    })

    archive.on('error', (error) => {
      throw error
    })
    archive.pipe(zipStream)

    archive.glob(`*-${parsedDate}.pdf`, { cwd: 'sztm_files/' })
    archive.finalize()

    await stream
    const stats = fs.statSync(`sztm_files/${zipFile}`)
    return res.json({ filename: zipFile, size: stats.size, mtime: stats.mtime })
  } catch (error) {
    return res.status(400).json({ msg: error.toString(), stack: error.stack })
  }
})

sztm.post('/pdf', async (req, res) => {
  try {
    const { matchListId, date, place } = req.body
    if (!matchListId || !date || !place) {
      console.log('matchListId, date and place are mandatory.', req.body)
      throw Error('matchListId, date and place are mandatory.')
    }

    const matchList = await MatchList.findOne({ _id: matchListId })
    const dateString = date.match(/(\d{4}\d{2}\d{2})T\d{2}\d{2}\d{2}/)[1]
    const parsedDate = moment(dateString)
    const query = {
      _id: { $in: matchList.matches },
      place,
      date: {
        $gte: parsedDate.toDate(),
        $lt: parsedDate.add(1, 'day').toDate(),
      },
    }

    const matches = await Match.find(query)
      .sort({ date: 1 })
      .populate('player1')
      .populate('player2')
    const players = []
    const allPlaces = []
    matches.forEach((match) => {
      console.log(match.idString, match.place)
      if (match.player1) players.push(match.player1)
      if (match.player2) players.push(match.player2)
      if (match.place && !allPlaces.includes(match.place))
        allPlaces.push(match.place)
    })

    const tableRows = []
    matches
      .filter((match) => match.place && match.place == place)
      .forEach((match) => {
        if (match.player1)
          tableRows.push([
            match.player1.paid ? 'OK' : '',
            match.category,
            moment(match.date).format('HH:mm'),
            `(${match.player1.junior ? '30.-' : '50.-'}) ${
              match.player1.fullName
            }`,
            '',
          ])
        if (match.player2)
          tableRows.push([
            match.player2.paid ? 'OK' : '',
            match.category,
            moment(match.date).format('HH:mm'),
            `(${match.player2.junior ? '30.-' : '50.-'}) ${
              match.player2.fullName
            }`,
            '',
          ])
      })
    const paylistDoc = {
      pageSize: 'A4',
      pageOrientation: 'portrait',
      content: [
        { text: 'Stadtzürcher Tennismeisterschaft', style: 'header' },
        {
          text: `Nenngelder für den ${parsedDate
            .subtract(1, 'day')
            .format('DD.MM.YYYY')}`,
          style: 'subheader',
        },
        {
          columns: [
            { text: places[place] },
            { text: '50.- oder 30.- (Junioren Jg. 2003 oder jünger)' },
          ],
        },
        {
          table: {
            headerRows: 1,
            widths: ['10%', '20%', '10%', '*', '15%'],
            heights: 30,
            body: [
              [
                { text: 'bezahlt', fillColor: '#eeeeee' },
                { text: 'Kategorie', fillColor: '#eeeeee' },
                { text: 'Zeit', fillColor: '#eeeeee' },
                { text: 'Name', fillColor: '#eeeeee' },
                { text: 'Betrag bez.', fillColor: '#eeeeee' },
              ],
              ...tableRows,
            ],
          },
          style: 'tableStyle',
        },
        {
          table: {
            dontBreakRows: true,
            widths: ['25%', '*', '25%', '25%'],
            body: [
              [{ text: 'Datum', bold: true }, { text: '', colSpan: 3 }, {}, {}],
              [
                {
                  text: 'Turnierleiter',
                  colSpan: 2,
                  margin: [0, 10, 0, 0],
                  bold: true,
                },
                {},
                {
                  text: 'Kassierer',
                  colSpan: 2,
                  margin: [0, 10, 0, 0],
                  bold: true,
                },
                {},
              ],
              [
                {
                  text: 'Betrag von Spielern erhalten',
                  colSpan: 2,
                  margin: [0, 25, 0, 0],
                },
                {},
                {
                  text: 'Betrag von Turnierleiter erhalten',
                  colSpan: 2,
                  margin: [0, 25, 0, 0],
                },
                {},
              ],
            ],
          },
          style: 'tableStyle',
        },
      ],
      styles: {
        header: {
          fontSize: 22,
          bold: true,
          margin: [0, 20, 0, 8],
        },
        subheader: {
          fontSize: 14,
          margin: [0, 15, 0, 12],
        },
        tableStyle: {
          margin: [0, 15, 0, 5],
        },
      },
    }

    const scheduleDoc = {
      pageSize: 'A4',
      pageOrientation: 'landscape',
      header: {
        stack: [
          {
            text: `Spielplan für den ${moment(parsedDate).format(
              'DD.MM.YYYY'
            )} (${places[place]})`,
            style: 'subheader',
          },
        ],
        margin: [40, 0],
      },
      content: [
        { text: 'Stadtzürcher Tennismeisterschaft', style: 'header' },
        {
          table: {
            headerRows: 1,
            widths: [
              '5%',
              '5%',
              '12%',
              '*',
              '5%',
              '*',
              '5%',
              '7%',
              '7%',
              '7%',
              '10%',
            ],
            heights: 30,
            body: [
              [
                { text: 'Platz', fillColor: '#eeeeee' },
                { text: 'Zeit', fillColor: '#eeeeee' },
                { text: 'Kategorie', fillColor: '#eeeeee' },
                { text: 'Spieler 1', fillColor: '#eeeeee', colSpan: 2 },
                {},
                { text: 'Spieler 2', fillColor: '#eeeeee', colSpan: 2 },
                {},
                { text: '1. Satz', fillColor: '#eeeeee' },
                { text: '2. Satz', fillColor: '#eeeeee' },
                { text: '3. Satz', fillColor: '#eeeeee' },
                { text: 'WO Grund', fillColor: '#eeeeee' },
              ],
              ...matches
                .filter((match) => match.place && match.place == place)
                .map((match) => {
                  return [
                    '',
                    moment(match.date).format('HH:mm'),
                    match.category,
                    match.player1 && match.player1.fullName,
                    match.player1 && match.player1.ranking,
                    match.player2 && match.player2.fullName,
                    match.player2 && match.player2.ranking,
                    '',
                    '',
                    '',
                    '',
                  ]
                }),
            ],
          },
          style: 'tableStyle',
        },
      ],
      styles: {
        header: {
          fontSize: 22,
          bold: true,
          margin: [0, 20, 0, 8],
        },
        subheader: {
          fontSize: 14,
          margin: [0, 15, 0, 12],
        },
        tableStyle: {
          margin: [0, 15, 0, 5],
        },
      },
    }

    const paylistGenerator = pdfMake.createPdf(paylistDoc)
    const paylistFile = `Zahlliste-${place}-${dateString}.pdf`
    paylistGenerator.getBuffer((buffer) => {
      fs.writeFileSync(
        `sztm_files/${paylistFile}`,
        new Buffer(new Uint8Array(buffer))
      )
    })
    const scheduleGenerator = pdfMake.createPdf(scheduleDoc)
    const scheduleFile = `Spielliste-${place}-${dateString}.pdf`
    scheduleGenerator.getBuffer((buffer) => {
      fs.writeFileSync(
        `sztm_files/${scheduleFile}`,
        new Buffer(new Uint8Array(buffer))
      )
    })

    /*
        const payListStats = fs.statSync(`sztm_files/${paylistFile}`)
        const scheduleStats = fs.statSync(`sztm_files/${scheduleFile}`)
        
        res.json({ 
            place,
            paylistFile: {filename: paylistFile, size: payListStats.size, mtime: payListStats.mtime}, 
            scheduleFile: {filename: scheduleFile, size: scheduleStats.size, mtime: scheduleStats.mtime} 
        }) */

    res.json({
      place,
      paylistFile: { filename: paylistFile, size: 0, mtime: new Date() },
      scheduleFile: { filename: scheduleFile, size: 0, mtime: new Date() },
    })
  } catch (error) {
    return res.status(400).json({ msg: error.toString(), stack: error.stack })
  }
})

export default sztm
