import m from 'mithril'
import htmlPage from './common/htmlPage.ts'
import { type Repository } from '../src/dataTypes.ts'
import { type FlatFileEntry } from '../src/flatFiles.ts'
import { NavHelper } from './helpers/nav.ts'
type Branch = Repository['branches'][0]

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const isDirectory = eleventyConfig.getFilter("isDirectory")
  const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")
  const getDirectoryContents = eleventyConfig.getFilter("getDirectoryContents")
  const getRelativePath = eleventyConfig.getFilter("getRelativePath")
  const slugify = eleventyConfig.getFilter("slugify")
  const lineNumbers = eleventyConfig.getFilter("lineNumbers")
  const highlightCode = eleventyConfig.getFilter("highlightCode")
  const languageExtension = eleventyConfig.getFilter("languageExtension")
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
  const currentRef: Branch = data.currentRef
  const currentRepo: Repository = data.currentRepo
  const fileInfo: FlatFileEntry = data.fileInfo

  const nav = NavHelper({
    reposConfig,
    slugify,
    currentRepoName: currentRepo.name,
    currentRefName: currentRef.name,
    currentRefType: data.currentRefType,
  })

  const pageContent = [  
    m('div', {class: "row mt-3 mb-1"},
      m('div', {class: "col"},
        m('p', [
          'Files snapshot from ',
          m('span', {class: "font-monospace"}, fileInfo.refName)
        ])
      )
    ),
    m('div', {class: "directory-buttons row"},
      m('div', {class: "col"},
        m('h3', [
          m('span', {class: "bezel-gray p-1 my-1 d-inline-block"},
            m('a', {href: `${data.reposPath}/${slugify(fileInfo.repoName)}/${fileInfo.type}/${slugify(fileInfo.refName)}/files`}, './')
          ),
          fileInfo.file.split('/').map((dir, index, arr) => {
            if (index === arr.length - 1) {
              return m('span', {class: "px-2 my-1 d-inline-block"}, dir)
            }
            else {
              return m('span', {class: "bezel-gray p-1 my-1 d-inline-block"}, [
                m('a', {
                  href: `${data.reposPath}/${slugify(fileInfo.repoName)}/${fileInfo.type}/${slugify(fileInfo.refName)}/files/${arr.slice(0, index + 1).map((part) => slugify(part)).join('/')}`}, `${dir}/`)
              ])
            }
          })
        ])
      )
    ),
    (fileInfo.isDirectory ?
      m('div', {class: "row"},
        m('div', {class: "col"},
          m('ul', {class: "list-group"},
            topLevelFilesOnly(getDirectoryContents(fileInfo.repoName, fileInfo.refName, fileInfo.type, fileInfo.file), fileInfo.file + '/').map((dir) => {
              return m('li', {class: 'list-group-item'}, [
                dir.isDirectory ? m('span', m.trust('&#x1F4C1;&nbsp;')) : null,
                m('a', {
                  href: nav.file(dir.fullPath)},
                  getRelativePath(fileInfo.file, dir.name)
                )
              ])
            })
          )
        )
      )
    : [
        m('div', {class: "row my-3"},
          m('div', {class: "col"},
            m('span', m('a', {
              href: nav.raw(fileInfo.file)}, 'View raw file'))
          )
        ),
        (fileInfo.file.endsWith(".md") ?
          [
            m('div', {class: "row my-2"},
              m('div', {class: "col"},
                m('div', {class: "form-check form-switch"}, [
                  m('input', {
                    class: "form-check-input",
                    type: "checkbox",
                    role: "switch",
                    id: "showRenderedContent",
                    checked: true
                  }),
                  m('label', {
                    class: "form-check-label",
                    for: "showRenderedContent"
                  }, 'Show rendered markdown')
                ])
              )
            ),
            m('div', {class: "row rendered-content"},
              m('div', {class: "col"},
                m.trust(await renderContentIfAvailable(
                  (await currentRepo.files(fileInfo.file, currentRef.sha)).contents
                ))
              )
            )
          ]
        : null),
        m('div', {class: `row code-content ${fileInfo.file.endsWith('.md') ? 'd-none' : ''}`},
          m('div', {class: "col"}, [
            m('div', {class: "row"},
              m('div', {class: "col-auto"},
                m('div', {class: "form-check form-switch"}, [
                  m('input', {class: "form-check-input", type: "checkbox", role: "switch", id: "showLastTouch"}),
                  m('label', {class: "form-check-label", for: "showLastTouch"}, 'Show last line change'),
                ])
              )
            ),
            m('div', {class: "row"}, [
              m('div', {class: "col-auto p-0"},
                m('code', {style: "white-space: pre;"},
                  m('pre', {class: "language-text"},
                    lineNumbers((await currentRepo.files(fileInfo.file, currentRef.sha)).contents).map((lineNumber) => {
                      return lineNumber
                    }).join('\n')
                  )
                )
              ),
              m('div', {id: "annotations", class: "col-auto d-none p-0"},
                m('code', {style: "white-space: pre;"}, [
                  m('pre', {class: "language-text"}, m.trust(
                    (await currentRepo.files(fileInfo.file, currentRef.sha)).blameLines.map((annotation) => {
                      return `<a href="${nav.commit(annotation.sha)}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
                    }).join('\n')))
                ])
              ),
              m('div', {class: "col overflow-scroll p-0"},
                m('code', m.trust(highlightCode(
                  (await currentRepo.files(fileInfo.file, currentRef.sha)).contents,
                  languageExtension(
                    fileInfo.file,
                    fileInfo.repoName
                  )
                )))
              )
            ])
          ])
        ),
      ]
    )
  ]

  return await htmlPage(reposConfig, eleventyConfig, data, pageContent)
}
