import { readdir } from 'node:fs/promises'
import * as path from 'node:path'

export const debugLogger =
  (debug: boolean) =>
  (message: string, clean: boolean = false) => {
    if (debug) {
      const timestamp = new Date().toLocaleTimeString('en-US', {
        hour12: false,
      })
      if (clean) {
        console.log(`${message}`)
        return
      }

      console.log(`◉  [${timestamp}] [@based/metaExtractor] ${message}`)
    }
  }

export async function getAllFiles(
  dir: string,
  ext: string,
  files: string[] = [],
): Promise<string[]> {
  const entries = await readdir(dir, { withFileTypes: true })
  for (const entry of entries) {
    const fullPath = path.join(dir, entry.name)
    if (entry.isDirectory()) {
      getAllFiles(fullPath, ext, files)
    } else if (entry.isFile() && fullPath.endsWith(ext)) {
      files.push(fullPath)
    }
  }

  return files
}

export function generateID(name: string): string {
  if (!name) {
    return ''
  }

  const removeAccents = (str: string): string => {
    return str.normalize('NFD').replace(/\p{Diacritic}/gu, '')
  }

  return removeAccents(name)
    .trim()
    .toLowerCase()
    .replace(/\s+/g, '')
    .replace(/[^a-z0-9-]/g, '')
}

export function setCache(
  path: string,
  entry: Based.UI.Extractor.CacheEntry,
  cache: Based.UI.Extractor.Cache,
  cacheSize: number,
): void {
  if (cache.size >= cacheSize) {
    const firstKey = cache.keys().next().value as string
    cache.delete(firstKey)
  }

  cache.set(path, entry)
}

export function makeContents(
  metaData: Based.UI.Extractor.MetaResult,
  blocksData: Based.UI.Extractor.BlocksResult,
) {
  return `
export const metaData = ${JSON.stringify(metaData, null, 2)};
export const blocksData = ${JSON.stringify(blocksData, null, 2)};`
}

export function isCached(
  path: string,
  mtimeMs: number,
  cache: Based.UI.Extractor.Cache,
): boolean {
  const cached = cache.get(path)

  if (!cached) {
    return false
  }

  if (cached.mtimeMs === mtimeMs) {
    return true
  }

  return false
}
