// Copyright IBM Corp. 2020, 2025

import debug from 'debug'
import express from 'express'
import fs from 'node:fs'
import PromiseRouter from 'express-promise-router'
import path from 'node:path'
import {fileURLToPath} from 'node:url'

import openBrowser from './utils/open-browser.js'

import _debugging from './api/debugging.js'
import details from './api/details.js'
import ping from './api/ping.js'
import _predicates from './api/predicates.js'
import proxy from './api/proxy.js'
import samples from './api/samples.js'
import helmet from 'helmet'

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

export default async function (options) {
  const {
    /** @deprecated use zenservUrl */
    account,
    adminkey,
    apikey,
    cli = {version: ''},
    /** @deprecated use zenservUrl */
    domain = 'us-east-a.ibm.stepzen.net',
    port = 5000,
    predicates = {
      available: false,
      enabled: false,
      onTogglePredicates: async () => {},
    },
    debugging = {
      enabled: false,
      onToggleDebugging: async () => {},
    },
    workspace,
    zenservUrl,
  } = options

  const warnIfUsingDeprecatedOption = option => {
    if (options[option]) {
      debug('stepzen:dashboard')(
        `The account ${option} is deprecated.` +
          ` Please use zenservUrl instead.`,
      )
    }
  }
  warnIfUsingDeprecatedOption('account')
  warnIfUsingDeprecatedOption('domain')

  const app = express()

  app.use(express.json())

  app.use(helmet.frameguard())

  app.use(express.static(`${__dirname}/../ui/build`))
  app.use((req, res, next) => {
    req.stepzen = {
      adminkey,
      apikey,
      cli,
      debugging,
      predicates,
      workspace,
      zenservUrl: zenservUrl || `https://${account}.${domain}`,
    }
    next()
  })

  const router = PromiseRouter()

  router.all('/api/predicates', _predicates)
  router.all('/api/debugging', _debugging)
  router.get('/api/details', details)
  router.get('/api/ping', ping)
  router.get('/api/samples', samples)
  router.post('*', proxy)

  const dashboard = fs.readFileSync(
    `${__dirname}/../ui/build/index.html`,
    'utf8',
  )
  router.get('*', (req, res) => res.send(dashboard))

  // generic failsafe error handler
  // (to avoid printing 'unhandled promise rejection' errors to the console)
  router.use((err, req, res, next) => {
    debug('stepzen:dashboard')('router error', err)

    err.statusCode = err.statusCode || 500
    err.status = err.status || 'error'

    res.status(err.statusCode).json({
      status: err.status,
      message: err.message,
    })
  })

  app.use(router)

  const open = () =>
    openBrowser(`http://localhost:${port}/${workspace.endpoint}`)

  const start = async () =>
    new Promise(resolve => {
      let server = app.listen(port, () => {
        resolve(server)
      })
    })

  return {
    app,
    open,
    start,
  }
}
