import fs from 'node:fs'
import readline from 'node:readline'
import { STARTING_CAPITAL, PROFILES, round } from '../core/strategy.js'
import { replay, loadSession } from '../runners/replay.js'
import type { Profile, Bar10s } from '../core/strategy.js'

async function main() {
  const profileList: Profile[] = [PROFILES.TAKER, PROFILES.MAKER_OPT, PROFILES.MAKER_FAST]
  const dirs = fs.readdirSync('data/sessions').map(d => 'data/sessions/' + d).filter(d => {
    try { return fs.statSync(d + '/trades.jsonl').size > 1000 } catch { return false }
  }).sort()
  console.log('Sessions:', dirs.length, '| Profiles:', profileList.map(p => p.name).join(', '))
  console.log()
  const results: Record<string, any[]> = {}
  for (const p of profileList) results[p.name] = []
  for (const dir of dirs) {
    const sessionName = dir.split('/').pop()!
    process.stderr.write(`Loading ${sessionName}...\n`)
    const { bars, obs } = await loadSession(dir)
    if (bars.length < 100 || obs.length < 100) { process.stderr.write(`  skipping (too small)\n`); continue }
    console.log(`=== ${sessionName} (bars=${bars.length} ob=${obs.length}) ===`)
    const header = ['', 'Return', 'MaxDD', 'Trades', 'WinRate', 'AvgWin', 'AvgLoss', 'Fees', 'SL', 'Trail', 'Time', 'TP1', 'PF'].map(h => h.padStart(8)).join('')
    console.log(header)
    for (const profile of profileList) {
      const s = replay(bars, obs, profile)
      const wins = s.closed.filter(t => t.net > 0), losses = s.closed.filter(t => t.net <= 0)
      const r = {
        ret: round(s.capital - STARTING_CAPITAL), maxDdPct: round(s.maxDdPct * 100, 2),
        trades: s.closed.length, wins: wins.length, losses: losses.length,
        winRate: s.closed.length > 0 ? round(wins.length / s.closed.length * 100, 1) : 0,
        avgWin: wins.length > 0 ? round(wins.reduce((a, t) => a + t.net, 0) / wins.length) : 0,
        avgLoss: losses.length > 0 ? round(losses.reduce((a, t) => a + t.net, 0) / losses.length) : 0,
        fees: round(s.fees),
        pf: losses.length > 0 && wins.length > 0 ? round(wins.reduce((a, t) => a + t.net, 0) / Math.abs(losses.reduce((a, t) => a + t.net, 0)), 2) : 0,
        sls: s.closed.filter(t => t.reason === 'sl').length,
        tp1s: s.closed.filter(t => t.reason === 'tp1').length,
        trails: s.closed.filter(t => t.reason === 'trail').length,
        timeExits: s.closed.filter(t => t.reason === 'time' || t.reason === 'force_close').length,
      }
      results[profile.name].push(r)
      const row = [profile.name.slice(0, 8).padStart(8), `$${r.ret}`, `${r.maxDdPct}%`, `${r.trades}`, `${r.winRate}%`, `$${r.avgWin}`, `$${r.avgLoss}`, `$${r.fees}`, `${r.sls}`, `${r.trails}`, `${r.timeExits}`, `${r.tp1s}`, `${r.pf}`].map(v => String(v).padStart(8)).join('')
      console.log(row)
    }
    console.log()
  }
  if (Object.values(results)[0]?.length > 1) {
    console.log('=== AGGREGATE ===')
    for (const [name, arr] of Object.entries(results)) {
      const ret = round(arr.reduce((a: number, r: any) => a + r.ret, 0)), maxDd = round(Math.max(...arr.map((r: any) => r.maxDdPct)), 2)
      const trades = arr.reduce((a: number, r: any) => a + r.trades, 0), wins = arr.reduce((a: number, r: any) => a + r.wins, 0)
      const fees = round(arr.reduce((a: number, r: any) => a + r.fees, 0))
      console.log(`  ${name.padEnd(12)} ret=$${ret} maxDD=${maxDd}% trades=${trades} wins=${wins} fees=$${fees}`)
    }
  }
}

main().catch(e => { console.error(e); process.exit(1) })
