const db = require('../database/db'); 

function getUserIdByApiKey(user_api_key, callback) {

  const sql = `SELECT user_id FROM "user" WHERE user_api_key = $1`;
  db.get(sql, [user_api_key], (err, row) => {
    if (err) return callback(err);
    if (!row) return callback(null, null);
    return callback(null, row.user_id);
  });
}

/**
 * Helper: busca o investment_type_id com base no investment_type_name.
 * Retorna `null` se não encontrar.
 */
function getInvestmentTypeIdByName(investment_type_name, callback) {
  
  const sql = `SELECT investment_type_id FROM investment_type WHERE investment_type_name = $1`;
  db.get(sql, [investment_type_name], (err, row) => {
    if (err) return callback(err);
    if (!row) return callback(null, null);
    return callback(null, row.investment_type_id);
  });
}

/**
 * SELECT com JOIN para listar todos os investments,
 * retornando também o nome do user (ou user id?), e o nome do investment type.
 *
 * Você pode buscar mais campos se quiser, por exemplo `user_name` do usuário.
 */
function getAllInvestments(callback) {
  const sql = `
    SELECT
      i.investment_id,
      i.investment_start,
      i.investment_end,
      i.investment_amt, -- ADICIONADO: investment_amt
      u.user_name        AS user_name,
      u.user_api_key     AS user_api_key,
      it.investment_type_name      AS investment_type
    FROM investment i
    JOIN "user" u            ON i.investment_user_id = u.user_id
    JOIN investment_type it  ON i.investment_type_id = it.investment_type_id
  `;
  db.all(sql, [], (err, rows) => {
    if (err) {
      console.error('Erro ao listar investments:', err.message);
      return callback(err);
    }
    callback(null, rows);
  });
}

/**
 * SELECT por ID, com JOIN, para retornar 1 registro
 */
function getInvestmentById(investment_id, callback) {
  // ALTERADO: ? para $1
  const sql = `
    SELECT
      i.investment_id,
      i.investment_start,
      i.investment_end,
      i.investment_amt, -- ADICIONADO: investment_amt
      u.user_name        AS user_name,
      u.user_api_key     AS user_api_key,
      it.investment_type_name      AS investment_type_name
    FROM investment i
    JOIN "user" u            ON i.investment_user_id = u.user_id
    JOIN investment_type it  ON i.investment_type_id = it.investment_type_id
    WHERE i.investment_id = $1
  `;
  db.get(sql, [investment_id], (err, row) => {
    if (err) {
      console.error('Erro ao buscar investment por ID:', err.message);
      return callback(err);
    }
    callback(null, row);
  });
}


function getRentabilityByInvestmentId(investment_id, callback) {
  const sql = `
    SELECT
      ir.investment_rentability_api_rent,
      bs.btc_value_date AS btcv_start_date,
      be.btc_value_date AS btcv_end_date
    FROM investment AS i
    JOIN investment_rentability AS ir ON i.investment_type_id = ir.investment_rentability_investment_type_id
    JOIN btc_value bs ON ir.investment_rentability_btcv_start = bs.btc_value_id
    JOIN btc_value be ON ir.investment_rentability_btcv_end = be.btc_value_id
    WHERE i.investment_id = $1
  `;

  db.all(sql, [investment_id], (err, rows) => {
    if (err) {
      console.error('Erro ao executar a query:', err.message);
      return callback(err);
    }
    if (!rows || rows.length === 0) return callback(null, null);
    return callback(null, rows);
  });
}


/**
 * Busca um tipo de investimento pelo nome
 * @param {string} investment_type_name
 * @param {function} callback (err, row)
 */
function getInvestmentTypeByName(investment_type_name, callback) {

  const sql = `SELECT * FROM investment_type WHERE investment_type_name = $1`;
  db.get(sql, [investment_type_name], (err, row) => {
    if (err) {
      console.error('Erro ao buscar investment_type por nome:', err.message);
      return callback(err);
    }
    callback(null, row); 
  });
}



/**
 * Cria um novo investment, convertendo:
 * - user_api_key -> investment_user_id
 * - investment_type_name   -> investment_type_id
 */
function createInvestment({ user_api_key, investment_type_name, investment_start, investment_end, investment_amt }, callback) {
  // 1) Verifica se as datas são válidas e se investment_start < investment_end
  const startDate = new Date(investment_start);
  const endDate = new Date(investment_end);

  if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) { // Melhorado: usar .getTime() para validação de data
    return callback(new Error('Datas inválidas. Use o formato YYYY-MM-DD.'));
  }

  if (startDate >= endDate) {
    return callback(new Error('A data de início deve ser anterior à data de término.'));
  }

  // 2) Busca o user_id pelo api_key
  getUserIdByApiKey(user_api_key, (err, user_id) => {
    if (err) return callback(err);
    if (!user_id) {
      return callback(new Error('Usuário não encontrado para essa API Key.'));
    }

    // 3) Busca o investment_type_id pelo investment_type_name
    getInvestmentTypeIdByName(investment_type_name, (err2, investment_type_id) => {
      if (err2) return callback(err2);
      if (!investment_type_id) {
        return callback(new Error(`Tipo de investimento não encontrado: ${investment_type_name}`));
      }

      // 4) Inserir
      const sql = `
        INSERT INTO investment (investment_user_id, investment_type_id, investment_start, investment_end, investment_amt)
        VALUES ($1, $2, $3, $4, $5)
        RETURNING investment_id
      `;

      const params = [user_id, investment_type_id, investment_start, investment_end, investment_amt];

      db.run(sql, params, function (err3, result) { // 'result' contém os dados retornados pelo RETURNING
        if (err3) {
          console.error('Erro ao inserir investment:', err3.message);
          return callback(err3);
        }
        // ALTERADO: O ID vem de result.rows[0].investment_id em vez de this.lastID
        callback(null, result.rows[0].investment_id);
      });
    });
  });
}


/**
 * Atualiza um investment existente.
 * Também faz a mesma lógica de lookup de user e investment_type,
 * pois o usuário pode querer alterar o tipo de investimento, ou user, ou datas.
 */
function updateInvestment(investment_id, { user_api_key, investment_type_name, investment_start, investment_end, investment_amt }, callback) {
  const startDate = new Date(investment_start);
  const endDate = new Date(investment_end);

  if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) { // Melhorado: usar .getTime() para validação de data
    return callback(new Error('Datas inválidas. Use o formato YYYY-MM-DD.'));
  }

  if (startDate >= endDate) {
    return callback(new Error('A data de início deve ser anterior à data de término.'));
  }

  getUserIdByApiKey(user_api_key, (err, user_id) => {
    if (err) return callback(err);
    if (!user_id) {
      return callback(new Error('Usuário não encontrado para essa API Key.'));
    }

    getInvestmentTypeIdByName(investment_type_name, (err2, investment_type_id) => {
      if (err2) return callback(err2);
      if (!investment_type_id) {
        return callback(new Error(`Tipo de investimento não encontrado: ${investment_type_name}`));
      }

      const sql = `
        UPDATE investment
        SET investment_user_id = $1, investment_type_id = $2, investment_start = $3, investment_end = $4, investment_amt = $5
        WHERE investment_id = $6
      `;
      const params = [user_id, investment_type_id, investment_start, investment_end, investment_amt, investment_id];

      db.run(sql, params, function (err3, result) { // 'result' é o segundo argumento
        if (err3) {
          console.error('Erro ao atualizar investment:', err3.message);
          return callback(err3);
        }
        // ALTERADO: this.changes para result.rowCount
        callback(null, result.rowCount);
      });
    });
  });
}


/**
 * Remove um investment por investment_id
 */
function deleteInvestment(investment_id, callback) {

  const sql = `
    DELETE FROM investment
    WHERE investment_id = $1
  `;
  db.run(sql, [investment_id], function (err, result) { // 'result' é o segundo argumento
    if (err) {
      console.error('Erro ao remover investment:', err.message);
      return callback(err);
    }
    // ALTERADO: this.changes para result.rowCount
    callback(null, result.rowCount);
  });
}

module.exports = {
  getAllInvestments,
  getInvestmentById,
  getRentabilityByInvestmentId,
  createInvestment,
  updateInvestment,
  deleteInvestment,
  getInvestmentTypeByName
};