/**
 * Simple PostgreSQL client for testing
 */
export class SimplePostgresClient {
  private tables = new Map<string, any[]>();
  private connected = false;

  constructor(private config: any) {}

  async query(sql: string, params?: any[]): Promise<{ rows: any[]; rowCount: number }> {
    // Simple mock implementation
    return { rows: [], rowCount: 0 };
  }

  async findOne(table: string, where: any): Promise<any | null> {
    const rows = this.tables.get(table) || [];
    for (const row of rows) {
      let match = true;
      for (const [key, value] of Object.entries(where)) {
        if (row[key] !== value) {
          match = false;
          break;
        }
      }
      if (match) {
        return row;
      }
    }
    return null;
  }

  async find(table: string, where: any): Promise<any[]> {
    const rows = this.tables.get(table) || [];
    if (Object.keys(where).length === 0) {
      return rows;
    }

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

  async insert(table: string, data: any): Promise<any> {
    const rows = this.tables.get(table) || [];
    const newRow = { ...data, id: rows.length + 1 };
    rows.push(newRow);
    this.tables.set(table, rows);
    return newRow;
  }

  async update(table: string, where: any, data: any): Promise<number> {
    const rows = this.tables.get(table) || [];
    let updated = 0;

    for (const row of rows) {
      let match = true;
      for (const [key, value] of Object.entries(where)) {
        if (row[key] !== value) {
          match = false;
          break;
        }
      }
      if (match) {
        Object.assign(row, data);
        updated++;
      }
    }

    return updated;
  }

  async delete(table: string, where: any): Promise<number> {
    const rows = this.tables.get(table) || [];
    const remaining = rows.filter(row => {
      for (const [key, value] of Object.entries(where)) {
        if (row[key] !== value) {
          return true;
        }
      }
      return false;
    });

    const deleted = rows.length - remaining.length;
    this.tables.set(table, remaining);
    return deleted;
  }

  async healthCheck(): Promise<{ status: string; isConnected: boolean; error?: string }> {
    return {
      status: 'healthy',
      isConnected: true,
    };
  }

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

export class SimpleQueryBuilder {
  private parts: string[] = [];
  private params: any[] = [];

  select(columns: string[] | string = '*'): SimpleQueryBuilder {
    const cols = Array.isArray(columns) ? columns.join(', ') : columns;
    this.parts.push(`SELECT ${cols}`);
    return this;
  }

  from(table: string): SimpleQueryBuilder {
    this.parts.push(`FROM ${table}`);
    return this;
  }

  where(conditions: any): SimpleQueryBuilder {
    const whereClause = Object.entries(conditions)
      .map(([key], i) => {
        this.params.push(conditions[key]);
        return `${key} = $${this.params.length}`;
      })
      .join(' AND ');

    this.parts.push(`WHERE ${whereClause}`);
    return this;
  }

  orderBy(column: string, direction = 'ASC'): SimpleQueryBuilder {
    this.parts.push(`ORDER BY ${column} ${direction}`);
    return this;
  }

  limit(count: number): SimpleQueryBuilder {
    this.parts.push(`LIMIT ${count}`);
    return this;
  }

  insert(table: string, data: any): SimpleQueryBuilder {
    const columns = Object.keys(data);
    const values = Object.values(data);
    this.params.push(...values);

    const placeholders = columns.map((_, i) => `$${i + 1}`);
    this.parts.push(
      `INSERT INTO ${table} (${columns.join(', ')}) VALUES (${placeholders.join(', ')})`
    );
    return this;
  }

  update(table: string): SimpleQueryBuilder {
    this.parts.push(`UPDATE ${table}`);
    return this;
  }

  set(data: any): SimpleQueryBuilder {
    const setClause = Object.entries(data)
      .map(([key, value]) => {
        this.params.push(value);
        return `${key} = $${this.params.length}`;
      })
      .join(', ');

    this.parts.push(`SET ${setClause}`);
    return this;
  }

  delete(table: string): SimpleQueryBuilder {
    this.parts.push(`DELETE FROM ${table}`);
    return this;
  }

  returning(columns: string): SimpleQueryBuilder {
    this.parts.push(`RETURNING ${columns}`);
    return this;
  }

  join(table: string, condition: string): SimpleQueryBuilder {
    this.parts.push(`JOIN ${table} ON ${condition}`);
    return this;
  }

  build(): { text: string; values: any[] } {
    return {
      text: this.parts.join(' '),
      values: this.params,
    };
  }
}

export class SimpleTransactionManager {
  constructor(private pool: any) {}

  async transaction<T>(fn: (client: any) => Promise<T>): Promise<T> {
    const mockClient = {
      query: async (sql?: string) => ({ rows: [], rowCount: 0 }),
      release: () => {},
    };

    await mockClient.query('BEGIN');
    try {
      const result = await fn(mockClient);
      await mockClient.query('COMMIT');
      return result;
    } catch (error) {
      await mockClient.query('ROLLBACK');
      throw error;
    } finally {
      mockClient.release();
    }
  }
}
