import * as heldBillRepo from '../repositories/heldBillRepository.js';
import Counter from '../models/Counter.js';
import logAudit from '../utils/audit.js';

const generateHoldNumber = async () => {
  const seq = await Counter.getNextSequence('heldBill');
  return `HOLD-${String(seq).padStart(3, '0')}`;
};

const getAllHeldBills = async () => heldBillRepo.findAll();

const createHeldBill = async (data, req) => {
  const items = (data.items || []).map((item) => ({
    productId: item.productId,
    productName: item.productName || '',
    image: item.image || '',
    variantId: item.variantId || '',
    variantLabel: item.variantLabel || '',
    sellingUnit: item.sellingUnit || 'pcs',
    size: item.size || '',
    measurementValue: item.measurementValue ?? null,
    measurementUnit: item.measurementUnit || '',
    price: Number(item.price) || 0,
    quantity: Number(item.quantity) || 1,
  }));

  if (items.length === 0) {
    throw Object.assign(new Error('Cannot hold an empty bill'), { statusCode: 400 });
  }

  const heldBill = await heldBillRepo.create({
    holdNumber: await generateHoldNumber(),
    items,
    customerName: (data.customerName || '').trim().slice(0, 120),
    customerPhone: (data.customerPhone || '').trim().slice(0, 20),
    createdBy: req.user ? { id: req.user._id, name: req.user.name } : { id: null, name: '' },
  });

  logAudit(req, 'BILL_HELD', 'heldBill', heldBill._id, {
    holdNumber: heldBill.holdNumber,
    itemCount: items.length,
  });

  return heldBill;
};

const resumeHeldBill = async (id, req) => {
  const heldBill = await heldBillRepo.findById(id);
  if (!heldBill) throw Object.assign(new Error('Held bill not found'), { statusCode: 404 });
  if (heldBill.status !== 'HELD') {
    throw Object.assign(new Error('Held bill is no longer active'), { statusCode: 400 });
  }

  heldBill.status = 'RESUMED';
  await heldBillRepo.save(heldBill);

  logAudit(req, 'BILL_RESUMED', 'heldBill', heldBill._id, { holdNumber: heldBill.holdNumber });
  return heldBill;
};

const deleteHeldBill = async (id, req) => {
  const heldBill = await heldBillRepo.findById(id);
  if (!heldBill) throw Object.assign(new Error('Held bill not found'), { statusCode: 404 });

  heldBill.status = 'DELETED';
  await heldBillRepo.save(heldBill);

  logAudit(req, 'BILL_HOLD_DELETED', 'heldBill', heldBill._id, {
    holdNumber: heldBill.holdNumber,
  });
  return heldBill;
};

export default { getAllHeldBills, createHeldBill, resumeHeldBill, deleteHeldBill };
