import fs from 'fs';
import path from 'path';
import { v4 as uuidv4 } from 'uuid';

export type SwapMonitorRecord = {
  id: string;
  officeId: number;
  chainId: number;
  tokenIn: string;
  tokenOut: string;
  amountIn: string;
  amountOut?: string;
  txHash?: string;
  wallet?: string;
  routeProviders?: string[];
  status: 'QUOTED' | 'SUBMITTED' | 'CONFIRMED' | 'FAILED';
  settlementRef?: string;
  createdAt: string;
  updatedAt: string;
};

const base =
  process.env.DBIS_SWAP_MONITOR_DIR ||
  path.resolve(__dirname, '../../../data/dbis-exchange/swap-monitor');

function dir(): string {
  if (!fs.existsSync(base)) fs.mkdirSync(base, { recursive: true });
  return base;
}

export function recordSwap(entry: Omit<SwapMonitorRecord, 'id' | 'createdAt' | 'updatedAt'>): SwapMonitorRecord {
  const now = new Date().toISOString();
  const rec: SwapMonitorRecord = { id: uuidv4(), createdAt: now, updatedAt: now, ...entry };
  fs.writeFileSync(path.join(dir(), `${rec.id}.json`), JSON.stringify(rec, null, 2));
  return rec;
}

export function updateSwap(id: string, patch: Partial<SwapMonitorRecord>): SwapMonitorRecord | null {
  const p = path.join(dir(), `${id}.json`);
  if (!fs.existsSync(p)) return null;
  const rec = JSON.parse(fs.readFileSync(p, 'utf8')) as SwapMonitorRecord;
  const updated = { ...rec, ...patch, updatedAt: new Date().toISOString() };
  fs.writeFileSync(p, JSON.stringify(updated, null, 2));
  return updated;
}

export function listSwaps(limit = 100): SwapMonitorRecord[] {
  return fs
    .readdirSync(dir())
    .filter((f) => f.endsWith('.json'))
    .slice(0, limit)
    .map((f) => JSON.parse(fs.readFileSync(path.join(dir(), f), 'utf8')) as SwapMonitorRecord)
    .sort((a, b) => b.createdAt.localeCompare(a.createdAt));
}

export function swapStats(): { total: number; confirmed: number; failed: number; last24h: number } {
  const all = listSwaps(5000);
  const dayAgo = Date.now() - 86400000;
  return {
    total: all.length,
    confirmed: all.filter((s) => s.status === 'CONFIRMED').length,
    failed: all.filter((s) => s.status === 'FAILED').length,
    last24h: all.filter((s) => new Date(s.createdAt).getTime() > dayAgo).length,
  };
}
