import db from "../models/index.js";

/**
 * Adjusts a customer's balance for a specific system service (e.g. usd_virtual_account_service).
 * Automatically creates the balance record if it does not already exist (lazy init).
 *
 * @param {string} customerId - The customer UUID
 * @param {string} serviceCode - The system service code (e.g. 'usd_virtual_account_service')
 * @param {number} delta - Positive to credit, negative to debit
 * @param {object} [transaction] - Optional Sequelize transaction object for atomicity
 * @returns {Promise<object>} The updated CustomerServiceBalance record
 */
export async function adjustCustomerServiceBalance(customerId, serviceCode, delta, transaction = null) {
  const service = await db.SystemService.findOne({
    where: { code: serviceCode },
    ...(transaction && { transaction }),
  });

  if (!service) throw new Error(`System service '${serviceCode}' not found.`);

  const [balanceRecord] = await db.CustomerServiceBalance.findOrCreate({
    where: { customerId, serviceId: service.id },
    defaults: { balance: 0.00, prev_balance: 0.00 },
    ...(transaction && { transaction }),
  });

  const newBalance = parseFloat(balanceRecord.balance) + parseFloat(delta);

  if (newBalance < 0) {
    throw new Error(`Insufficient balance on '${service.name}'. Available: ${balanceRecord.balance}`);
  }

  await balanceRecord.update(
    { prev_balance: balanceRecord.balance, balance: newBalance },
    transaction ? { transaction } : {},
  );

  return balanceRecord;
}

/**
 * Fetch a customer's current balance for a specific service.
 * Returns { balance, prev_balance } or { balance: 0, prev_balance: 0 } if no record yet.
 *
 * @param {string} customerId
 * @param {string} serviceCode
 * @returns {Promise<{ balance: number, prev_balance: number }>}
 */
export async function getCustomerServiceBalance(customerId, serviceCode) {
  const service = await db.SystemService.findOne({ where: { code: serviceCode } });
  if (!service) throw new Error(`System service '${serviceCode}' not found.`);

  const record = await db.CustomerServiceBalance.findOne({
    where: { customerId, serviceId: service.id },
  });

  return {
    balance: record ? parseFloat(record.balance) : 0.00,
    prev_balance: record ? parseFloat(record.prev_balance) : 0.00,
    service: { id: service.id, name: service.name, code: service.code, currency: service.currency },
  };
}
