import { EventEmitter } from 'node:events';

export interface FundingRate { rate: number; timestamp: number; venue?: string; }

export interface FundingRateMonitorOptions {
  fetchPrimary: () => Promise<FundingRate>;
  fetchHedge: () => Promise<FundingRate>;
  pollIntervalMs?: number;
}

export interface FundingMetrics {
  primaryRate: FundingRate;
  hedgeRate: FundingRate;
  correlation?: number;
  sameSign?: boolean;
}

export class FundingRateMonitor extends EventEmitter {
  private readonly fetchPrimary: () => Promise<FundingRate>;
  private readonly fetchHedge: () => Promise<FundingRate>;
  private readonly pollIntervalMs: number;
  private timer?: NodeJS.Timeout;
  private running = false;

  constructor(options: FundingRateMonitorOptions) {
    super();
    this.fetchPrimary = options.fetchPrimary;
    this.fetchHedge = options.fetchHedge;
    this.pollIntervalMs = options.pollIntervalMs ?? 60_000;
  }

  async start(): Promise<void> {
    if (this.running) return;
    this.running = true;
    await this.poll();
    this.timer = setInterval(() => {
      this.poll().catch(error => this.emit('error', error));
    }, this.pollIntervalMs);
  }

  stop(): void {
    if (!this.running) return;
    if (this.timer) clearInterval(this.timer);
    this.timer = undefined;
    this.running = false;
  }

  private async poll(): Promise<void> {
    try {
      const [primaryRate, hedgeRate] = await Promise.all([
        this.fetchPrimary(),
        this.fetchHedge()
      ]);
      const metrics: FundingMetrics = {
        primaryRate,
        hedgeRate,
        sameSign: Math.sign(primaryRate.rate) === Math.sign(hedgeRate.rate)
      };
      this.emit('metrics', metrics);
    } catch (error) {
      this.emit('error', error);
    }
  }
}
