// src/controllers/withdrawController.js

const withdrawModel = require('../models/withdrawModel');
const db = require('../database/db'); // ALTERADO: Caminho do import do db para '../database/db'


/**
 * GET /withdraws
 */
const getAllWithdraws = (req, res) => {
  withdrawModel.getAllWithdraws((err, rows) => {
    if (err) {
      console.error('Erro ao buscar retiradas (Controller):', err);
      return res.status(500).json({ error: 'Erro ao buscar retiradas.' });
    }
    return res.json(rows);
  });
};

/**
 * GET /withdraws/:id
 */
const getWithdrawById = (req, res) => {
  // ALTERADO: w_id para withdraws_id (para corresponder ao schema e evitar confusão)
  const withdraws_id = parseInt(req.params.id, 10);

  if (!withdraws_id) {
    return res.status(400).json({ error: 'ID inválido.' });
  }

  // ALTERADO: w_id para withdraws_id
  withdrawModel.getWithdrawById(withdraws_id, (err, row) => {
    if (err) {
      console.error('Erro ao buscar retirada por ID (Controller):', err);
      return res.status(500).json({ error: 'Erro ao buscar retirada.' });
    }
    if (!row) {
      return res.status(404).json({ error: 'Retirada não encontrada.' });
    }
    return res.json(row);
  });
};

/**
 * GET /withdraws/investment/:id
 */
const getWithdrawByInvestmentId = (req, res) => {
  // ALTERADO: w_investment_id para withdraws_investment_id
  const withdraws_investment_id = parseInt(req.params.id, 10);

  if (!withdraws_investment_id) {
    return res.status(400).json({ error: 'ID inválido.' });
  }

  // ALTERADO: w_investment_id para withdraws_investment_id
  withdrawModel.getWithdrawByInvestmentId(withdraws_investment_id, (err, rows) => { // NOTE: getWithdrawByInvestmentId retorna ROWS (db.all)
    if (err) {
      console.error('Erro ao buscar retirada por ID de investimento (Controller):', err);
      return res.status(500).json({ error: 'Erro ao buscar retirada.' });
    }
    // ALTERADO: Se getWithdrawByInvestmentId retornar um array vazio, ainda é um 200 OK, mas sem dados.
    // A verificação de !rows ou 404 seria mais adequada se esperasse APENAS UMA linha.
    // Para db.all, null é menos provável, será um array vazio.
    if (!rows || rows.length === 0) {
      return res.status(200).json([]); // Retorna array vazio em vez de 404 se nenhum for encontrado.
    }
    return res.json(rows);
  });
};

/**
 * POST /withdraws
 * Body: { withdraws_tp, withdraws_amt, withdraws_investment_id, withdraws_fee_id, withdraws_fee_amt, withdraws_date }
 */
const createWithdraw = (req, res) => {
  const { withdraws_tp, withdraws_amt, withdraws_investment_id, withdraws_fee_id, withdraws_date } = req.body;

  // Verificação de campos obrigatórios
  if (!withdraws_tp || !withdraws_amt || !withdraws_investment_id || !withdraws_fee_id || !withdraws_date) {
    return res.status(400).json({
      error: 'Campos obrigatórios: withdraws_tp, withdraws_amt, withdraws_investment_id, withdraws_fee_id, withdraws_date.'
    });
  }

  // Validação de tipos e formato
  if (isNaN(withdraws_amt)) {
    return res.status(400).json({
      error: 'withdraws_amt deve ser um valor numérico.'
    });
  }

  // Validação de data
  const date = new Date(withdraws_date);
  if (isNaN(date.getTime())) {
    return res.status(400).json({
      error: 'Data inválida no formato withdraws_date.'
    });
  }

  // Verificar se o investimento existe e validar o intervalo de datas
  // ALTERADO: ? para $1
  const checkInvestmentSql = 'SELECT investment_start, investment_end FROM investment WHERE investment_id = $1';
  db.get(checkInvestmentSql, [withdraws_investment_id], (err, investment) => {
    if (err) {
      console.error('Erro ao verificar investimento (Controller):', err); // ADICIONADO: log do erro detalhado
      return res.status(500).json({ error: 'Erro ao verificar investimento.' });
    }
    if (!investment) {
      return res.status(404).json({ error: 'Investimento não encontrado.' });
    }

    const start = new Date(investment.investment_start);
    const end = new Date(investment.investment_end);

    if (date < start || date > end) {
      return res.status(400).json({
        error: 'A data da retirada deve estar entre o início e o final do investimento.'
      });
    }

    // Verificar se a taxa existe
    // ALTERADO: ? para $1
    const checkFeeSql = 'SELECT fee_op, fee_prorata FROM fee WHERE fee_id = $1';
    db.get(checkFeeSql, [withdraws_fee_id], (err, fee) => {
      if (err) {
        console.error('Erro ao buscar taxas (Controller):', err); // ADICIONADO: log do erro detalhado
        return res.status(500).json({ error: 'Erro ao buscar taxas.' });
      }
      if (!fee) {
        return res.status(404).json({ error: 'Taxa não encontrada.' });
      }

      let feeTotal;

      // Lógica de cálculo baseada no tipo de retirada
      if (withdraws_tp === 'Saque' || withdraws_tp === 'Cancelamento') {
        feeTotal = parseFloat(fee.fee_op) + parseFloat(fee.fee_prorata);
      } else if (withdraws_tp === 'Saque de rentabilidade' || withdraws_tp === 'Fechamento') {
        feeTotal = parseFloat(fee.fee_op);
      } else {
        return res.status(400).json({
          error: `Tipo de retirada '${withdraws_tp}' não encontrado. Tipos válidos: 'Saque', 'Cancelamento', 'Saque de rentabilidade', 'Fechamento'.`
        });
      }

      // Certifique-se de que o valor de withdraws_fee_amt esteja sendo calculado e passado corretamente
      // A variável withdraws_fee_amt do req.body não é usada, o valor é calculado.
      const calculated_withdraws_fee_amt = (parseFloat(withdraws_amt) * feeTotal).toFixed(2);


      // Criar retirada
      withdrawModel.createWithdraw(
        {
          withdraws_tp,
          withdraws_amt,
          withdraws_investment_id,
          withdraws_fee_id,
          withdraws_fee_amt: calculated_withdraws_fee_amt, // Passando o valor calculado
          withdraws_date
        },
        (err, newId) => {
          if (err) {
            console.error('Erro ao criar retirada (Controller):', err); // ADICIONADO: log do erro detalhado
            return res.status(400).json({ error: err.message });
          }
          return res.status(201).json({
            message: 'Retirada criada com sucesso!',
            withdraws_id: newId
          });
        }
      );
    });
  });
};


/**
 * PUT /withdraws/:id
 * Body: { withdraws_tp, withdraws_amt, withdraws_investment_id, withdraws_fee_id, withdraws_fee_amt, withdraws_date }
 */
const updateWithdraw = (req, res) => {
  // ALTERADO: w_id para withdraws_id
  const withdraws_id = parseInt(req.params.id, 10);
  const { withdraws_tp, withdraws_amt, withdraws_investment_id, withdraws_fee_id, withdraws_date } = req.body;

  if (!withdraws_id) {
    return res.status(400).json({ error: 'ID inválido na URL.' });
  }

  // Verificação de campos obrigatórios
  if (!withdraws_tp || !withdraws_amt || !withdraws_investment_id || !withdraws_fee_id || !withdraws_date) {
    return res.status(400).json({
      error: 'Campos obrigatórios: withdraws_tp, withdraws_amt, withdraws_investment_id, withdraws_fee_id, withdraws_date.'
    });
  }

  // Validação de tipo numérico
  if (isNaN(withdraws_amt)) {
    return res.status(400).json({ error: 'withdraws_amt deve ser um valor numérico.' });
  }

  // Validação da data
  const date = new Date(withdraws_date);
  if (isNaN(date.getTime())) {
    return res.status(400).json({ error: 'Data inválida no formato withdraws_date.' });
  }

  // Verifica se o investimento existe e se a data está no intervalo válido
  // ALTERADO: ? para $1
  const investmentSql = 'SELECT investment_start, investment_end FROM investment WHERE investment_id = $1';
  db.get(investmentSql, [withdraws_investment_id], (err, investment) => {
    if (err) {
      console.error('Erro ao buscar investimento (Update Withdraw Controller):', err); // ADICIONADO: log do erro detalhado
      return res.status(500).json({ error: 'Erro ao buscar investimento.' });
    }
    if (!investment) {
      return res.status(404).json({ error: 'Investimento não encontrado.' });
    }

    const start = new Date(investment.investment_start);
    const end = new Date(investment.investment_end);

    if (date < start || date > end) {
      return res.status(400).json({
        error: 'A data da retirada deve estar entre o início e o final do investimento.'
      });
    }

    // Verificar se a taxa existe
    // ALTERADO: ? para $1
    const feeSql = 'SELECT fee_op, fee_prorata FROM fee WHERE fee_id = $1';
    db.get(feeSql, [withdraws_fee_id], (err, fee) => {
      if (err) {
        console.error('Erro ao buscar taxas (Update Withdraw Controller):', err); // ADICIONADO: log do erro detalhado
        return res.status(500).json({ error: 'Erro ao buscar taxas.' });
      }
      if (!fee) {
        return res.status(404).json({ error: 'Taxa não encontrada.' });
      }

      let feeTotal;

      // Lógica de cálculo baseada no tipo de retirada
      if (withdraws_tp === 'Saque' || withdraws_tp === 'Cancelamento') {
        feeTotal = parseFloat(fee.fee_op) + parseFloat(fee.fee_prorata);
      } else if (withdraws_tp === 'Saque de rentabilidade' || withdraws_tp === 'Fechamento') {
        feeTotal = parseFloat(fee.fee_op);
      } else {
        return res.status(400).json({
          error: `Tipo de retirada '${withdraws_tp}' não encontrado. Tipos válidos: 'Saque', 'Cancelamento', 'Saque de rentabilidade', 'Fechamento'.`
        });
      }

      const calculatedFeeAmt = (parseFloat(withdraws_amt) * feeTotal).toFixed(2);

      // Atualizar retirada
      // ALTERADO: w_id para withdraws_id
      withdrawModel.updateWithdraw(
        withdraws_id,
        {
          withdraws_tp,
          withdraws_amt,
          withdraws_investment_id,
          withdraws_fee_id,
          withdraws_fee_amt: calculatedFeeAmt,
          withdraws_date
        },
        (err, changes) => {
          if (err) {
            console.error('Erro ao atualizar retirada (Controller):', err); // ADICIONADO: log do erro detalhado
            return res.status(400).json({ error: err.message });
          }
          if (changes === 0) {
            return res.status(404).json({ error: 'Retirada não encontrada ou sem alterações.' });
          }
          return res.json({ message: 'Retirada atualizada com sucesso!' });
        }
      );
    });
  });
};


/**
 * DELETE /withdraws/:id
 */
const deleteWithdraw = (req, res) => {
  // ALTERADO: w_id para withdraws_id
  const withdraws_id = parseInt(req.params.id, 10);

  if (!withdraws_id) {
    return res.status(400).json({ error: 'ID inválido na URL.' });
  }

  // ALTERADO: w_id para withdraws_id
  withdrawModel.deleteWithdraw(withdraws_id, (err, changes) => {
    if (err) {
      console.error('Erro ao remover retirada (Controller):', err); // ADICIONADO: log do erro detalhado
      return res.status(500).json({ error: 'Erro ao remover retirada.' });
    }
    if (changes === 0) {
      return res.status(404).json({ error: 'Retirada não encontrada.' });
    }
    return res.json({ message: 'Retirada removida com sucesso!' });
  });
};

module.exports = {
  getAllWithdraws,
  getWithdrawById,
  getWithdrawByInvestmentId,
  createWithdraw,
  updateWithdraw,
  deleteWithdraw
};