```typescript
// Importing necessary types for the solution
import { Record } from "typescript-collections";

export function applyCharges(
  caps: Record<string, [number, number]>,
  charges: [string, string, number][]): { left: Record<string, number>; refused: [string, string][] } {
  const result: { left: Record<string, number>, refused: [string, string][] } = { left: {}, refused: [] };

  charges.forEach(([chargeId, bucketName, amount]) => {
    // Ensure the charge amount is a positive whole number
    if (!Number.isInteger(amount) || amount <= 0) {
      throw new Error("Amount must be a positive whole number.");
    }

    const [allowance, singleCharge] = caps.get(bucketName);
    if (!allowance) {
      result.refused.push([chargeId, "unknown"]);
      return;
    }

    if (amount > singleCharge) {
      result.refused.push([chargeId, "single"]);
      return;
    }

    if (amount > allowance) {
      result.refused.push([chargeId, "cap"]);
      return;
    }

    // Accept the charge and update the bucket's allowance
    caps.set(bucketName, [allowance - amount, singleCharge]);
  });

  // Collect the remaining allowances
  Object.keys(caps).forEach(bucket => {
    result.left[bucket] = caps.getValue(bucket)[0];
  });

  return result;
}
```