import { existsSync, mkdtempSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { resolve, join } from 'node:path'
import { pathToFileURL } from 'node:url'

const CONFIG_FILES = ['deck.config.js', 'marp.config.mjs', 'marp.config.js']

function findUserConfig(root) {
  return CONFIG_FILES.map(f => resolve(root, f)).find(existsSync)
}

export function buildConfig(root) {
  const pluginFileUrl = import.meta.resolve('./marp-inline-svg.js')
  const attrsPluginUrl = import.meta.resolve('markdown-it-attrs')
  const bracketedSpansUrl = import.meta.resolve('markdown-it-bracketed-spans')
  const userConfigPath = findUserConfig(root)

  let src
  if (userConfigPath) {
    const userConfigUrl = pathToFileURL(userConfigPath).href
    src = `import { inlineSvg } from ${JSON.stringify(pluginFileUrl)}
import markdownItAttrs from ${JSON.stringify(attrsPluginUrl)}
import markdownItBracketedSpans from ${JSON.stringify(bracketedSpansUrl)}
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
const userConfigUrl = ${JSON.stringify(userConfigUrl)}
const userConfigDir = dirname(fileURLToPath(userConfigUrl))
const { engine: userEngine, deck: _, themeSet: userThemeSet, ...userPrefs } = (await import(userConfigUrl)).default ?? {}
const themeSet = (Array.isArray(userThemeSet) ? userThemeSet : userThemeSet ? [userThemeSet] : [])
  .map(p => typeof p === 'string' ? resolve(userConfigDir, p) : p)
export default {
  ...userPrefs,
  ...(themeSet.length ? { themeSet } : {}),
  html: true,
  engine: ({ marp }) => (userEngine ? userEngine({ marp }) : marp).use(inlineSvg).use(markdownItBracketedSpans).use(markdownItAttrs),
}
`
  } else {
    src = `import { inlineSvg } from ${JSON.stringify(pluginFileUrl)}
import markdownItAttrs from ${JSON.stringify(attrsPluginUrl)}
import markdownItBracketedSpans from ${JSON.stringify(bracketedSpansUrl)}
export default {
  html: true,
  engine: ({ marp }) => marp.use(inlineSvg).use(markdownItBracketedSpans).use(markdownItAttrs),
}
`
  }

  const tmpDir = mkdtempSync(join(tmpdir(), 'deck-compose-'))
  const outPath = join(tmpDir, 'marp.config.mjs')
  writeFileSync(outPath, src)
  return outPath
}

export async function loadDeckMeta(root) {
  const userConfigPath = findUserConfig(root)
  if (!userConfigPath) return {}
  const config = (await import(pathToFileURL(userConfigPath).href)).default ?? {}
  return config.deck ?? {}
}
