import express from 'express'
import { readFileSync, writeFileSync } from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
import { createServer as createViteServer } from 'vite'

const port = 5173
const cachePath = './cache.json'

const __dirname = path.dirname(fileURLToPath(import.meta.url))

// Using cache to reload parsed feeds from disk instead of remote
// Since every change of the email is a full render it feels wasteful retrieving the RSS
const getCache = () => {
  try {
    let cache = readFileSync(cachePath, 'utf-8')
    return JSON.parse(cache)
  } catch {
    return
  }
}

async function createServer() {
  const app = express()

  const vite = await createViteServer({
    server: { middlewareMode: true },
    appType: 'custom',
  })

  app.use(vite.middlewares)

  app.use('/preview.html', async (_, res, next) => {
    try {
      const { renderEmail } = await vite.ssrLoadModule('/src/renderEmail.tsx')

      const { html, feeds } = await renderEmail({
        pretty: true,
        limit: 3, // Limit to the last n posts of every feed in feeds.ts
        actionUrl: 'http://localhost:5173',
        cache: getCache(),
      })

      writeFileSync(cachePath, JSON.stringify(feeds), { flag: 'w' })

      res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
    } catch (e) {
      vite.ssrFixStacktrace(e)
      next(e)
    }
  })

  app.use('/', async (req, res, next) => {
    const url = req.originalUrl

    try {
      let template = readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8')
      template = await vite.transformIndexHtml(url, template)

      res.status(200).set({ 'Content-Type': 'text/html' }).end(template)
    } catch (e) {
      vite.ssrFixStacktrace(e)
      next(e)
    }
  })

  app.listen(port)

  console.log(`Preview started on: http://localhost:${port}`)
}

createServer()