import path from 'node:path'
import type { Config, Output } from '@kubb/core'
import type { Oas } from '@kubb/oas'
import { isFunction } from 'remeda'

type Props<TOas extends Oas> = {
  oas: TOas
  output: Output<any>
  config?: Config
}

/**
 * Generate a default banner for files created by Kubb
 * @returns A string with the default banner
 */
function getDefaultBanner({ title, description, version, config }: { title?: string; description?: string; version?: string; config: Config }): string {
  try {
    let source = ''
    if ('path' in config.input) {
      source = path.basename(config.input.path)
    } else if ('data' in config.input) {
      source = 'text content'
    }

    let banner = '/**\n* Generated by Kubb (https://kubb.dev/).\n* Do not edit manually.\n'

    if (config.output.defaultBanner === 'simple') {
      banner += '*/\n'
      return banner
    }

    if (source) {
      banner += `* Source: ${source}\n`
    }

    if (title) {
      banner += `* Title: ${title}\n`
    }

    if (description) {
      const formattedDescription = description.replace(/\n/gm, '\n* ')
      banner += `* Description: ${formattedDescription}\n`
    }

    if (version) {
      banner += `* OpenAPI spec version: ${version}\n`
    }

    banner += '*/\n'
    return banner
  } catch (_error) {
    // If there's any error in parsing the Oas data, return a simpler banner
    return '/**\n* Generated by Kubb (https://kubb.dev/).\n* Do not edit manually.\n*/'
  }
}

export function getBanner<TOas extends Oas>({ output, oas, config }: Props<TOas>): string {
  let banner = ''
  if (config?.output?.defaultBanner !== false && config) {
    const { title, description, version } = oas.api?.info || {}

    banner = getDefaultBanner({ title, description, version, config })
  }

  if (!output.banner) {
    return banner
  }

  if (isFunction(output.banner)) {
    return `${output.banner(oas)}\n${banner}`
  }

  return `${output.banner}\n${banner}`
}
