/**
 * File-based event store implementation.
 * Appends events as JSON lines to a file on disk.
 * Suitable for single-instance dev/staging deployments.
 */

import { readFile, appendFile, writeFile, mkdir } from 'node:fs/promises';
import { dirname } from 'node:path';
import type { EventStore, StoredEvent, EventStoreQuery } from './types.js';

export interface FileStoreOptions {
  filePath: string;
}

export class FileEventStore implements EventStore {
  private readonly filePath: string;

  constructor(options: FileStoreOptions) {
    this.filePath = options.filePath;
  }

  async append(event: StoredEvent): Promise<void> {
    await mkdir(dirname(this.filePath), { recursive: true });
    await appendFile(this.filePath, JSON.stringify(event) + '\n', 'utf-8');
  }

  async query(q: EventStoreQuery): Promise<StoredEvent[]> {
    const all = await this.readAll();
    let results = all;

    if (q.userId) results = results.filter(e => e.userId === q.userId);
    if (q.type) results = results.filter(e => e.type === q.type);
    if (q.after) results = results.filter(e => e.timestamp > q.after!);
    if (q.before) results = results.filter(e => e.timestamp < q.before!);

    if (q.limit && q.limit > 0) {
      results = results.slice(-q.limit);
    }

    return results;
  }

  async recent(limit = 50): Promise<StoredEvent[]> {
    const all = await this.readAll();
    return all.slice(-limit);
  }

  async count(): Promise<number> {
    const all = await this.readAll();
    return all.length;
  }

  async clear(): Promise<void> {
    await writeFile(this.filePath, '', 'utf-8');
  }

  private async readAll(): Promise<StoredEvent[]> {
    try {
      const content = await readFile(this.filePath, 'utf-8');
      return content
        .split('\n')
        .filter(line => line.trim())
        .map(line => JSON.parse(line) as StoredEvent);
    } catch {
      return [];
    }
  }
}
