/**
 * Simple MongoDB client implementation for testing
 */
export class SimpleMongoDBClient {
  private collections = new Map<string, any[]>();
  private connected = false;

  constructor(private config: any) {}

  async connect(): Promise<void> {
    this.connected = true;
  }

  async disconnect(): Promise<void> {
    this.connected = false;
  }

  async find(collection: string, filter: any = {}): Promise<any[]> {
    if (!this.connected) {
      await this.connect();
    }
    const docs = this.collections.get(collection) || [];

    // Simple filter matching
    if (Object.keys(filter).length === 0) {
      return docs;
    }

    return docs.filter(doc => {
      for (const [key, value] of Object.entries(filter)) {
        if (doc[key] !== value) {
          return false;
        }
      }
      return true;
    });
  }

  async findOne(collection: string, filter: any = {}): Promise<any | null> {
    const results = await this.find(collection, filter);
    return results[0] || null;
  }

  async insert(collection: string, doc: any): Promise<void> {
    if (!this.connected) {
      await this.connect();
    }
    const docs = this.collections.get(collection) || [];
    docs.push({ ...doc, _id: Math.random().toString(36) });
    this.collections.set(collection, docs);
  }

  async insertMany(collection: string, documents: any[]): Promise<void> {
    for (const doc of documents) {
      await this.insert(collection, doc);
    }
  }

  async update(collection: string, filter: any, update: any): Promise<number> {
    if (!this.connected) {
      await this.connect();
    }
    const docs = await this.find(collection, filter);

    if (docs.length === 0) {
      return 0;
    }

    const doc = docs[0];
    if (update.$set) {
      Object.assign(doc, update.$set);
    }

    return 1;
  }

  async updateMany(collection: string, filter: any, update: any): Promise<number> {
    if (!this.connected) {
      await this.connect();
    }
    const docs = await this.find(collection, filter);

    for (const doc of docs) {
      if (update.$set) {
        Object.assign(doc, update.$set);
      }
    }

    return docs.length;
  }

  async delete(collection: string, filter: any): Promise<number> {
    if (!this.connected) {
      await this.connect();
    }
    const allDocs = this.collections.get(collection) || [];
    const toDelete = await this.find(collection, filter);

    if (toDelete.length === 0) {
      return 0;
    }

    const remaining = allDocs.filter(doc => !toDelete.includes(doc));
    this.collections.set(collection, remaining);

    return 1;
  }

  async deleteMany(collection: string, filter: any): Promise<number> {
    if (!this.connected) {
      await this.connect();
    }
    const allDocs = this.collections.get(collection) || [];
    const toDelete = await this.find(collection, filter);

    const remaining = allDocs.filter(doc => !toDelete.includes(doc));
    this.collections.set(collection, remaining);

    return toDelete.length;
  }

  async batchUpsert(collection: string, documents: any[], uniqueKeys: string[]): Promise<void> {
    if (!this.connected) {
      await this.connect();
    }

    for (const doc of documents) {
      const filter: any = {};
      for (const key of uniqueKeys) {
        filter[key] = doc[key];
      }

      const existing = await this.findOne(collection, filter);
      if (existing) {
        await this.update(collection, filter, { $set: doc });
      } else {
        await this.insert(collection, doc);
      }
    }
  }

  async count(collection: string, filter: any = {}): Promise<number> {
    const docs = await this.find(collection, filter);
    return docs.length;
  }

  async createIndex(collection: string, index: any, options?: any): Promise<void> {
    // No-op for simple implementation
  }

  async healthCheck(): Promise<{ status: string; isConnected: boolean; error?: string }> {
    try {
      return {
        status: this.connected ? 'healthy' : 'unhealthy',
        isConnected: this.connected,
      };
    } catch (error: any) {
      return {
        status: 'unhealthy',
        isConnected: false,
        error: error.message,
      };
    }
  }
}
