// @ts-check
import * as td from 'typedoc'
import { ReflectionKind } from 'typedoc'

class WrapTableTheme extends td.DefaultTheme {
  /** @param {td.Renderer} renderer */
  constructor(renderer) {
    super(renderer)
    // Let write everything to a string, which is not optimal but easier to code.
    this.result = ''
  }

  /** @param {td.DeclarationReflection} declaration  */
  renderDeclaration(declaration) {
    if (declaration.kind === ReflectionKind.Method) {
      this.renderMethod(declaration)
      return
    }
    if (!declaration.children) {
      return
    }
    // eslint-disable-next-line no-restricted-syntax
    for (const child of declaration.children) {
      this.renderDeclaration(child)
    }
  }

  renderMethod(declaration) {
    let s = declaration.name
    const signature = declaration.signatures[0] // at least one signature must exist
    if (signature.parameters) {
      s += `(${signature.parameters.map((p) => p.name).join(', ')})`
    }
    if (signature.type) {
      s += ` → ${signature.type.name}`
      if (signature.type.typeArguments) {
        s += `&lt;${signature.type.typeArguments.map((a) => a.name).join(', ')}>`
      }
    }
    this.result += `
            <div class="row">
                <div class="cell" id="${declaration.id}">${s}</div>
                <div class="cell">${signature.comment?.summary[0]?.text}</div>
            </div>`
  }

  render(page) {
    this.result = `    
    <div class="wrap-table100">
        <div class="table">
            <div class="row header">
                <div class="cell">
                    Function
                </div>
                <div class="cell">
                    Description
                </div>
            </div>
`
    this.renderDeclaration(page.model)
    this.result += `
            </div>
    </div>
`
    return this.result
  }
}

/** @param {td.Application} app */
export function load(app) {
  app.renderer.defineTheme('wrap_table', WrapTableTheme)
  // Add event listeners to app, app.converter, etc.
  // this function may be async
}
