import { DateTime } from 'luxon'
import { makeYearStats, processPostFile } from './utils.js'
import tagAliases from '../data/tag-aliases.js'

export const searchIndex = (collection) => {
  const searchIndex = []
  let id = 0
  const collectionData = collection.getAll()[0]
  const posts = collectionData.data.collections.posts
  const links = collectionData.data.links
  if (posts) {
    posts.forEach((post) => {
      const url = post.url.includes('http') ? post.url : `https://coryd.dev${post.url}`
      searchIndex.push({
        id,
        url,
        title: `📝: ${post.data.title}`,
        tags: post.data.tags.filter((tag) => tag !== 'posts'),
      })
      id++;
    })
  }
  if (links) {
    links.forEach((link) => {
      searchIndex.push({
        id,
        url: link.url,
        title: `🔗: ${link.title}`,
        tags: link.tags,
      })
      id++;
    })
  }
  return searchIndex
}

export const tagList = (collection) => {
  const tagsSet = new Set()
  collection.getAll().forEach((item) => {
    if (!item.data.tags) return
    item.data.tags
      .filter((tag) => !['posts', 'all'].includes(tag))
      .forEach((tag) => tagsSet.add(tag))
  })
  return Array.from(tagsSet).sort()
}

export const tagMap = (collection) => {
  const tags = {}
  const collectionData = collection.getAll()[0]
  const posts = collectionData.data.collections.posts
  const links = collectionData.data.collections.links
  const books = collectionData.data.books
  const movies = collectionData.data.movies

  if (posts) {
    posts.forEach((post) => {
      const url = post.url.includes('http') ? post.url : `https://coryd.dev${post.url}`
      const tagString = [...new Set(post.data.tags?.map((tag) => tagAliases[tag.toLowerCase()]))]
        .join(' ')
        .trim()
      if (tagString) tags[url] = tagString.replace(/\s+/g,' ')
    })
  }

  if (links) {
    links.forEach((link) => {
      const url = link.data.link
      const tagString = [...new Set(link.data.tags?.map((tag) => tagAliases[tag.toLowerCase()]))]
        .join(' ')
        .trim()
      if (tagString) tags[url] = tagString.replace(/\s+/g,' ')
    })
  }

  if (books) {
    books.forEach((book) => {
      const tagString = book['tags']?.map((tag) => tagAliases[tag.toLowerCase()])
        .join(' ')
        .trim()
      if (tagString) tags[book.url] = tagString.replace(/\s+/g,' ')
    })
  }

  if (movies) {
    movies.forEach((movie) => {
      const tagString = movie['tags']?.map((tag) => tagAliases[tag.toLowerCase()])
        .join(' ')
        .trim()
      if (tagString) tags[movie.url] = tagString.replace(/\s+/g,' ')
    })
  }

  return tags
}

export const tagsSortedByCount = (collection) => {
  const tagStats = {};
  collection.getFilteredByGlob('src/posts/**/*.*').forEach((item) => {
    if (!item.data.tags) return;
    item.data.tags
      .filter((tag) => !['posts', 'all', 'politics', 'net neutrality'].includes(tag))
      .forEach((tag) => {
      if (!tagStats[tag]) tagStats[tag] = 1;
      if (tagStats[tag]) tagStats[tag] = tagStats[tag] + 1;
    });
  });
  return Object.entries(tagStats).sort((a, b) => b[1] - a[1]).map(([key, value]) => `${key}`);
}

export const links = (collection) => collection.getFilteredByGlob('src/links/**/*.*').reverse()

export const booksToRead = (collection) => collection.getAll()[0].data.books.filter(book => book.status === 'want to read').sort((a, b) => a['title'].toLowerCase().localeCompare(b['title'].toLowerCase()))

export const postStats = (collection) => {
  const oneDayMilliseconds = 1000 * 60 * 60 * 24
  const statsObject = {
    avgDays: 0,
    avgCharacterCount: 0,
    avgCodeBlockCount: 0,
    avgParagraphCount: 0,
    avgWordCount: 0,
    totalWordCount: 0,
    totalCodeBlockCount: 0,
    postCount: 0,
    firstPostDate: new Date(),
    lastPostDate: new Date(),
    highPostCount: 0,
    years: [],
    postsByDay: {},
  }

  let avgDays = 0
  let totalDays = 0
  let totalPostCount = 0
  let totalCharacterCount = 0
  let totalCodeBlockCount = 0
  let totalParagraphCount = 0
  let totalWordCount = 0
  let yearCharacterCount = 0
  let yearCodeBlockCount = 0
  let yearParagraphCount = 0
  let yearWordCount = 0
  let yearPostCount = 0
  let yearPostDays = 0
  let highPostCount = 0
  let yearProgress = 0

  const posts = collection.getFilteredByGlob('src/posts/**/*.*').sort((a, b) => {
    return a.date - b.date
  })

  const postCount = posts.length
  if (postCount < 1) {
    console.log(`No articles found`)
    return statsObject
  }

  statsObject.postCount = postCount
  statsObject.firstPostDate = posts[0].data.page.date
  statsObject.lastPostDate = posts[postCount - 1].data.page.date

  let prevPostDate = posts[0].data.page.date
  let currentYear = prevPostDate.getFullYear()

  for (let post of posts) {
    let postDate = post.data.page.date
    const dateIndexKey = `${DateTime.fromISO(postDate).year}-${DateTime.fromISO(postDate).ordinal}`
    if (!statsObject.postsByDay[dateIndexKey]) {
      statsObject.postsByDay[dateIndexKey] = 0
    }
    statsObject.postsByDay[dateIndexKey]++
    let daysBetween = (postDate - prevPostDate) / oneDayMilliseconds
    let thisYear = postDate.getFullYear()
    if (thisYear != currentYear) {
      avgDays = yearPostDays / yearPostCount
      highPostCount = Math.max(highPostCount, yearPostCount)
      yearProgress = (yearPostCount / highPostCount) * 100
      statsObject.years.push(
        makeYearStats(
          currentYear,
          yearPostCount,
          yearWordCount,
          yearCodeBlockCount,
          avgDays,
          yearCharacterCount,
          yearParagraphCount,
          yearProgress
        )
      )
      yearCharacterCount = 0
      yearCodeBlockCount = 0
      yearParagraphCount = 0
      yearWordCount = 0
      yearPostCount = 0
      yearPostDays = 0
      currentYear = thisYear
    }
    prevPostDate = postDate
    totalDays += daysBetween
    yearPostDays += daysBetween
    totalPostCount++
    yearPostCount++
    const postStats = processPostFile(post.page.inputPath)
    totalCharacterCount += postStats.characterCount
    yearCharacterCount += postStats.characterCount
    totalCodeBlockCount += postStats.codeBlockCount
    yearCodeBlockCount += postStats.codeBlockCount
    totalParagraphCount += postStats.paragraphCount
    yearParagraphCount += postStats.paragraphCount
    totalWordCount += postStats.wordCount
    yearWordCount += postStats.wordCount
  }
  if (yearPostCount > 0) {
    avgDays = yearPostDays / yearPostCount
    highPostCount = Math.max(highPostCount, yearPostCount)
    yearProgress = (yearPostCount / highPostCount) * 100
    statsObject.years.push(
      makeYearStats(
        currentYear,
        yearPostCount,
        yearWordCount,
        yearCodeBlockCount,
        avgDays,
        yearCharacterCount,
        yearParagraphCount,
        yearProgress
      )
    )
  }
  statsObject.avgDays = parseFloat((totalDays / totalPostCount).toFixed(2))
  statsObject.avgCharacterCount = parseFloat((totalCharacterCount / totalPostCount).toFixed(2))
  statsObject.avgCodeBlockCount = parseFloat((totalCodeBlockCount / totalPostCount).toFixed(2))
  statsObject.avgParagraphCount = parseFloat((totalParagraphCount / totalPostCount).toFixed(2))
  statsObject.avgWordCount = parseFloat((totalWordCount / totalPostCount).toFixed(2))
  statsObject.totalWordCount = totalWordCount
  statsObject.totalCodeBlockCount = totalCodeBlockCount
  statsObject.highPostCount = highPostCount

  return statsObject
}