import m from 'mithril'
import { type Repository } from '../src/dataTypes.ts'
import { NavHelper } from './helpers/nav.ts'
import htmlPage from './common/htmlPage.ts'

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const repo: Repository = data.currentRepo
  const branch: Repository['branches'][0] = data.currentBranch
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
  const slugify = eleventyConfig.getFilter("slugify")
  const getReadMe = eleventyConfig.getFilter("getReadMe")
  const latestCommit = repo.commits.get(branch.head)
  const latestCommitMessage = latestCommit.message.length > 72
    ? latestCommit.message.split('\n')[0].substr(0, 72) + '...'
    : latestCommit.message

  const nav = NavHelper(reposConfig, slugify, repo.name, branch.name)

  const languageCounts = branch.fileList.reduce((counts, currentFile) => {
    const fileParts = currentFile.split(".")
    const fileExtension = fileParts[fileParts.length - 1]
// todo: add more ignoreable extensions or specific files
// (like package-lock.json). Allow glob patterns?
    if (fileExtension === 'gitignore') {
      return counts
    }

    counts.set(fileExtension, (counts.get(fileExtension) + 1) || 1)
    return counts
  }, new Map<string, number>())

  // todo: this is probably broken for repos that use fewer than 6 languages
  let languagePercentages: Array<[string, number]> = []
  const total = branch.fileList.length

  for (const entry of languageCounts) {
    languagePercentages.push([entry[0], entry[1] / total])
  }
  languagePercentages.sort((a, b) => {
    return b[1] - a[1]
  })
  const topLanguagePercentages = languagePercentages.slice(0, 5)
  const otherLanguagePercent = languagePercentages.slice(6, languagePercentages.length - 6).reduce((sum, current) => {
    return sum + current[1]
  }, 0)

  const largestPercent = Math.max(...topLanguagePercentages.map(tuple => tuple[1]), otherLanguagePercent)

  const readmeContent = await renderContentIfAvailable(await getReadMe(repo.name, branch.name), branch.name)

  const pageContent = [
    m('div', {class: "row"}, [
      m('div', {class: "col"}, [
        m('div', {class: "px-4 pt-3 bezel-header"}, [
          m('div', {class: "row"}, [
            m('div', {class: "col-12 col-lg-6"}, [
              m('h1', {class: "display-3 text-white"},
                m('em', repo.name)
              ),
              repo.description
                ? m('p', {class: "text-white fs-4 fw-light"}, repo.description)
                : null
            ]),
            m('div', {class: "col-12 col-lg-6 d-flex flex-column justify-content-around"}, [
              m('div', {class: "row flex-grow-1 align-items-stretch language-percent-row"}, [
                m('div', {class: "col-12 d-flex align-items-stretch"}, [
                  m('div', {class: "language-cols d-flex flex-grow-1 flex-nowrap"}, topLanguagePercentages.map((percentTuple) => {
                    return m('div', {class: 'language-col flex-grow-1 overflow-hidden'}, [
                      m('div', {class: "language-name text-light font-monospace"}, percentTuple[0]),
                      m('div', {class: "language-percent", style: `flex-grow: ${percentTuple[1] / largestPercent};`})
                    ])
                  }).concat([m('div', {class: 'language-col flex-grow-1 overflow-hidden'},
                    m('div', {class: "language-name text-light font-monospace"}, 'other'),
                      m('div', {class: "language-percent", style: `flex-grow: ${otherLanguagePercent / largestPercent};`})
                  )])),
                ])
              ]),
              m('div', {class: "row align-items-center"}, [
                m('div', {class: "col-12"}, [
                  m('div', {class: "header-button-container"}, [
                    m('button', {class: "btn btn-info btn-lg dropdown-toggle clone-popover-btn"}, 'Clone'),
                    nav.homepageButtons.map((buttonConfig) => {
                      return m('a', {
                        class: "btn btn-outline-info btn-lg shadow-none",
                        href: buttonConfig.url,
                        target: buttonConfig.newTab ? "_blank" : "_self"
                      }, m.trust(buttonConfig.text + `${buttonConfig.newTab ? ' <span>&#x29C9;</span>' : ''}`))
                    })
                  ])
                ])
              ])
            ])
          ]),
          m('noscript',
            m('div', {class: "row mt-2"},
              m('div', {class: "col"},
                m('p', {class: "font-monospace text-white"},
                  `Clone URL: ${repo.cloneUrl}`
                )
              )
            )
          ),
          m('div', {class: "row mt-2"}, [
            m('div', {class: "col"}, [
              m('p', {class: "font-monospace text-white mb-2 d-inline-block"}, [
                m('a', {class: "btn btn-outline-info badge shadow-none me-2", href: nav.repoCurrentBranchRssFeed()}, [
                  m('img', {src: `${nav.rootPath()}frontend/img/rss-icon.svg`, style: "width: 11px; margin-right: 5px;"}),
                  'RSS'
                ]),
                `Latest commit: ${latestCommit.date.toDateString()} `,
                m('a', {class: "fw-bold link-info", href: `${nav.repoBranchCommitsBase()}${latestCommit.hash}`}, latestCommit.hash.substr(0, 6)),
                ' ',
                latestCommitMessage,
              ])
            ])
          ])
        ])
      ])
    ]),
    m('div', {class: "row my-4 mx-1"},
      m('div', {class: "col readme"}, m.trust(readmeContent))
    )
  ]

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