const Pool = require('../../models/Pool');

class PoolRepository {
  constructor(uow) {
    this.uow = uow;
  }

  async create({ pool_name, description = null, price = 0.00, subscription_coffee_id = null, pool_type = 'other', is_active = true, created_by = null }) {
    const conn = this.uow.connection;
    try {
      console.info('PoolRepository.create:start', { pool_name, pool_type, is_active, price, subscription_coffee_id, created_by });
      const sql = `INSERT INTO pools (pool_name, description, price, subscription_coffee_id, pool_type, is_active, created_by)
       VALUES (?, ?, ?, ?, ?, ?, ?)`;
      const params = [pool_name, description, price, subscription_coffee_id, pool_type, is_active, created_by];
      const [res] = await conn.execute(sql, params);
      console.info('PoolRepository.create:success', { insertId: res?.insertId });
      return new Pool({ id: res.insertId, pool_name, description, price, subscription_coffee_id, pool_type, is_active, created_by });
    } catch (err) {
      console.error('PoolRepository.create:error', { code: err?.code, errno: err?.errno, sqlMessage: err?.sqlMessage, message: err?.message });
      const e = new Error('Failed to create pool');
      e.status = 500;
      e.cause = err;
      throw e;
    }
  }

  async findAll() {
    const conn = this.uow.connection; // switched to connection
    try {
      console.info('PoolRepository.findAll:start');
      const sql = `SELECT 
          p.id, p.pool_name, p.description, p.price, p.subscription_coffee_id, c.title AS subscription_title, p.pool_type, p.is_active,
          p.created_by, p.updated_by, p.created_at, p.updated_at,
          COUNT(pm.user_id) AS members_count
        FROM pools p
        LEFT JOIN coffee_table c ON c.id = p.subscription_coffee_id
        LEFT JOIN pool_members pm ON pm.pool_id = p.id
        WHERE p.pool_name IN ('ABO 60', 'ABO 120', 'Business', 'Gigantea', 'Core')
        GROUP BY p.id
        ORDER BY FIELD(p.pool_name, 'ABO 60', 'ABO 120', 'Business', 'Gigantea', 'Core')`;
      const [rows] = await conn.execute(sql);
      console.info('PoolRepository.findAll:success', { count: rows.length });
      return rows.map(r => new Pool(r));
    } catch (err) {
      console.error('PoolRepository.findAll:error', { code: err?.code, errno: err?.errno, sqlMessage: err?.sqlMessage, message: err?.message });
      // Surface a consistent error up the stack
      const e = new Error('Failed to fetch pools');
      e.status = 500;
      e.cause = err;
      throw e;
    }
  }

  // Update is_active flag (replaces old state transitions)
  async updateActive(id, is_active, updated_by = null) {
    const conn = this.uow.connection;
    try {
      console.info('PoolRepository.updateActive:start', { id, is_active, updated_by });
      const [rows] = await conn.execute(`SELECT id FROM pools WHERE id = ?`, [id]);
      if (!rows || rows.length === 0) {
        console.warn('PoolRepository.updateActive:not_found', { id });
        const err = new Error('Pool not found');
        err.status = 404;
        throw err;
      }
      await conn.execute(
        `UPDATE pools SET is_active = ?, updated_by = ?, updated_at = NOW() WHERE id = ?`,
        [is_active, updated_by, id]
      );
      const [updated] = await conn.execute(
        `SELECT p.id, p.pool_name, p.description, p.price, p.subscription_coffee_id, c.title AS subscription_title, p.pool_type, p.is_active, p.created_by, p.updated_by, p.created_at, p.updated_at
         FROM pools p
         LEFT JOIN coffee_table c ON c.id = p.subscription_coffee_id
         WHERE p.id = ?`,
        [id]
      );
      console.info('PoolRepository.updateActive:success', { id, is_active });
      return new Pool(updated[0]);
    } catch (err) {
      console.error('PoolRepository.updateActive:error', { id, is_active, code: err?.code, errno: err?.errno, sqlMessage: err?.sqlMessage, message: err?.message });
      if (!err.status) {
        const e = new Error('Failed to update pool active state');
        e.status = 500;
        e.cause = err;
        throw e;
      }
      throw err;
    }
  }

  async updateSubscriptionLink(id, subscription_coffee_id = null, updated_by = null) {
    const conn = this.uow.connection;
    try {
      console.info('PoolRepository.updateSubscriptionLink:start', { id, subscription_coffee_id, updated_by });
      const [rows] = await conn.execute(`SELECT id FROM pools WHERE id = ?`, [id]);
      if (!rows || rows.length === 0) {
        const err = new Error('Pool not found');
        err.status = 404;
        throw err;
      }

      await conn.execute(
        `UPDATE pools SET subscription_coffee_id = ?, updated_by = ?, updated_at = NOW() WHERE id = ?`,
        [subscription_coffee_id, updated_by, id]
      );

      const [updated] = await conn.execute(
        `SELECT p.id, p.pool_name, p.description, p.price, p.subscription_coffee_id, c.title AS subscription_title, p.pool_type, p.is_active, p.created_by, p.updated_by, p.created_at, p.updated_at
         FROM pools p
         LEFT JOIN coffee_table c ON c.id = p.subscription_coffee_id
         WHERE p.id = ?`,
        [id]
      );

      return new Pool(updated[0]);
    } catch (err) {
      console.error('PoolRepository.updateSubscriptionLink:error', { id, subscription_coffee_id, code: err?.code, message: err?.message });
      if (!err.status) {
        const e = new Error('Failed to update pool subscription link');
        e.status = 500;
        e.cause = err;
        throw e;
      }
      throw err;
    }
  }
}

module.exports = PoolRepository;