```ts
export function invoiceTotal(lines: { qty: number; unit: number; discount: number }[], rate: number): { subtotal: number; tax: number; total: number } {
  if (lines.length === 0) {
    throw new Error("Empty line list");
  }

  const round = (value: number): number => Math.round(value);

  const calculateLineNet = ({ qty, unit, discount }: { qty: number; unit: number; discount: number }): number => {
    if (!Number.isInteger(qty) || qty <= 0) {
      throw new Error("Invalid quantity");
    }
    if (!Number.isInteger(unit) || unit < 0) {
      throw new Error("Invalid unit price");
    }
    if (!Number.isInteger(discount) || discount < 0 || discount > 10000) {
      throw new Error("Invalid discount rate");
    }

    const gross = qty * unit;
    const rebate = round((gross * discount) / 10000);
    return gross - rebate;
  };

  if (!Number.isInteger(rate) || rate < 0 || rate > 10000) {
    throw new Error("Invalid tax rate");
  }

  const subtotal = lines.reduce((acc, line) => acc + calculateLineNet(line), 0);
  const tax = round((subtotal * rate) / 10000);
  const total = subtotal + tax;

  return { subtotal, tax, total };
}
```