import { readdirSync, statSync } from 'node:fs'
import { join } from 'node:path'
import process from 'node:process'
import { Command } from 'commander'
import { logger } from '../../core/logger.ts'
import { paths } from '../../core/paths.ts'
import { formatTable } from '../tui/table.ts'

type ArchiveOptions = { json: boolean }

type ArchiveFile = { day: string; bytes: number; path: string }

export const archiveCommand = new Command('archive')
  .description(
    'List the per-day cold archive files prune wrote (in ~/.openthomas/wire/traces/archive).',
  )
  .option('--json', 'Output JSON for piping.', false)
  .action((options: ArchiveOptions) => {
    let files: ArchiveFile[]
    try {
      files = readdirSync(paths.wire.tracesArchive)
        .filter((f) => f.endsWith('.db'))
        .map((f) => {
          const path = join(paths.wire.tracesArchive, f)
          return { day: f.replace(/\.db$/, ''), bytes: statSync(path).size, path }
        })
        .sort((a, b) => b.day.localeCompare(a.day))
    } catch {
      files = []
    }

    if (options.json) {
      process.stdout.write(`${JSON.stringify(files, null, 2)}\n`)
      return
    }

    if (files.length === 0) {
      logger.print('(no archives yet — prune writes a per-day .db when it evicts old data)')
      return
    }

    const rows = files.map((f) => [f.day, formatBytes(f.bytes), f.path])
    logger.print(formatTable(['DAY', 'SIZE', 'PATH'], rows))
    const total = files.reduce((n, f) => n + f.bytes, 0)
    logger.print(`\n${files.length} archive file(s), ${formatBytes(total)} total.`)
    logger.print('Each is a standalone Thomas-schema SQLite DB — copy, inspect, or delete freely.')
  })

function formatBytes(n: number): string {
  if (n < 1024) return `${n}B`
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)}KB`
  if (n < 1024 * 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)}MB`
  return `${(n / 1024 / 1024 / 1024).toFixed(2)}GB`
}
