import m from 'mithril'
import {NavHelper} from './helpers/nav.ts'
import htmlPage from './common/htmlPage.ts'

export default async (
  reposConfig: any,
  eleventyConfig: any,
  data: any,
) => {
  const pagesJustForRef = eleventyConfig.getFilter("pagesJustForRef")
  const slugify = eleventyConfig.getFilter("slugify")
  const date = eleventyConfig.getFilter("date")

  const nav = NavHelper({
    reposConfig,
    slugify,
    currentRepoName: data.patchPage.repoName,
    currentRefName: data.patchPage.refName,
    currentRefType: data.patchPage.type,
  })

  const pageContent = [
    m('div', {class: "row mt-3 mb-1"},
      m('div', {class: "col"},
        m('p', {class: "d-inline-block"}, [
          'Showing commits from ',
          m('span', {class: "font-monospace me-2"}, data.patchPage.refName),
          m('a', {
            class: "btn btn-outline-primary badge shadow-none",
            href: nav.rssFeed()
          }, [
            m('img', {
              src: `${nav.rootPath()}frontend/img/rss-icon.svg`,
              style: "width: 11px; margin-right: 5px;"
            }),
            'RSS',
          ])
        ])
      )
    ),
    m('nav', 
      m('ul', {class: "pagination"},
        pagesJustForRef(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.refName,
          data.patchPage.type,
        ).map((pageObj) => {
          return m('li', {class: "page-item"},
            m('a', {
              class: `page-link ${pageObj.pageNumber === data.patchPage.pageNumber ? 'active' : ''}`,
              href: `${nav.commits(pageObj.pageNumber)}`,
            }, pageObj.pageNumber)
          )
        })
      )
    ),
    m('div', {class: "container"}, data.patchPage.commits.map((commit) => {
      // Map of fileExtension => [lines_deleted, lines_added]
      const languageCounts = new Map<string, [number, number]>()

      commit.diffs.forEach((diff) => {
        const fileParts = diff.fileName.split(".")
        const fileExtension = fileParts[fileParts.length - 1]
        const currentCounts = languageCounts.get(fileExtension) || [0, 0]
        currentCounts[0] = currentCounts[0] + diff.removed
        currentCounts[1] = currentCounts[1] + diff.added
        languageCounts.set(fileExtension, currentCounts)
      })

      let totalDiffSizePerExtension = []
      // see which languages have the largest change
      // totalDiffSizePerExtension = [{extension: 'html', total: '50'}]
      for (const entry of languageCounts) {
        totalDiffSizePerExtension.push({ extension: entry[0], total: entry[1][0] + entry[1][1] })
      }

      totalDiffSizePerExtension = totalDiffSizePerExtension.toSorted((a, b) => {
        return b.total - a.total
      })

      const numOfTopLanguages = Math.min(3, totalDiffSizePerExtension.filter(a => a.total).length)
      const topLanguagePercentages = totalDiffSizePerExtension.slice(0, numOfTopLanguages)
      const otherLanguageDiffs = totalDiffSizePerExtension.slice(numOfTopLanguages).reduce((totals, current) => {
        totals[0] += languageCounts.get(current.extension)[0]
        totals[1] += languageCounts.get(current.extension)[1]
        return totals
      }, [0, 0])

      return [
        m('div', {class: "commit row py-2 my-2"}, [
          m('div', {class: "col-md-auto col-12 commit-date"}, [
            m('span', {class: "date mb-1 me-2 font-monospace d-inline-block text-nowrap"}, date(commit.date).split(' ').slice(1).join(' ')),
            commit.isMerge ? m('span', {class: 'badge rounded-pill bg-warning me-1'}, 'merge') : null,
            // TODO: if this commit has any tags, list them here
            // m('span', {class: "bg-danger mb-1 badge rounded-pill d-inline-block"}, 'v1.2')
          ]),
          m('div', { class: 'col' }, [
            m('div', { class: 'row' }, [
              m('div', {class: "col-12 col-md-8"}, [
                m('div', {class: "row mb-1"},
                  m('a', {href: nav.commit(commit.hash), class: "commit-msg"}, commit.message.split('\n').slice(0, 1))
                ),
                m('div', {class: "row mb-3 mb-lg-0"}, [
                  m('div', {class: "col d-flex flex-direction-row align-items-center flex-wrap"}, [
                    m('span', {class: "author me-2"}, commit.author),
                    // TODO: if the user has a verified website, put it here
                    // m('span', {class: "bg-primary badge rounded-pill me-2"}, 'tuckerm.us'),
                  ])
                ])
              ]),
              m('div', {class: "col-12 col-md-4 d-flex"}, [
                m('div', { class: "d-flex flex-column" }, topLanguagePercentages.map((topLangPercent) => {
                  return m('div', {
                    class: 'font-monospace small',
                    style: 'height: 1rem;'
                  }, topLangPercent.extension)
                }).concat(otherLanguageDiffs[0] > 0 || otherLanguageDiffs[1] > 0
                  ? m('div', {
                      class: 'font-monospace small',
                      style: 'height: 1rem;'
                  }, `other ${otherLanguageDiffs[0]} ${otherLanguageDiffs[1]}`)
                  : null,
                )),
                m('div', {
                  class: "d-flex flex-column flex-grow-1"
                }, topLanguagePercentages.map((topLangPercent) => {
                  const langDiffs = languageCounts.get(topLangPercent.extension)
                  // TODO: make the average commit size adjustable
                  const adjustedLength = Math.min(langDiffs[0] + langDiffs[1], 100)
                  return m('div', {
                    style: `height: 1rem; width: ${adjustedLength}%; background: black;`
                  })
                }))
              ]),
            ]),
          ]),
          m('div', {class: 'col-12 col-md-auto'}, [
            m('div', {class: "input-group mb-2 flex-nowrap"}, [
              m('span', {class: "font-monospace input-group-text border-info text-white text-bg-dark overflow-scroll"}, commit.hash.slice(0, 6)),
              m('button', {'data-copy-text': commit.hash, class: "btn btn-sm btn-info shadow-none copy-button"}, 'Copy')
            ])
          ]),
        ]),
      ]
    })),
    m('nav',
      m('ul', {class: "pagination"},
        pagesJustForRef(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.refName,
          data.patchPage.type,
        ).map((pageObj) => {
          return m('li', {class: "page-item"},
            m('a', {
              class: `page-link ${pageObj.pageNumber === data.patchPage.pageNumber ? 'active' : ''}`,
              href: `${nav.commits(pageObj.pageNumber)}`,
            }, pageObj.pageNumber)
          )
        })
      )
    )
  ]

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