/**
 * Client mirror of the backend's contiguous-range rules for priority configs
 * (see PriorityConfigsService.assertNoRangeCollision): ranges per type — per
 * currency for CURRENCY — run from 1 with no gaps and no overlaps, so the next
 * range always starts at the lowest uncovered wagon count. There is no upper
 * ceiling. The backend re-validates on submit AND on approval; this only
 * drives the form prefill.
 */

export type PriorityRuleType = "WAGON" | "CURRENCY" | "CUSTOMS";

export interface PriorityRangeRule {
  id?: unknown;
  type?: unknown;
  currency?: unknown;
  minWagonCount?: unknown;
  maxWagonCount?: unknown;
}

const PRIORITY_RULE_TYPES: PriorityRuleType[] = ["WAGON", "CURRENCY", "CUSTOMS"];

/**
 * Where the next range for `type` (+`currency`) must start, excluding
 * `excludeId` (the rule being edited). Null only when `type` is not yet a
 * known priority rule type — the chain itself is unbounded, so a next start
 * always exists.
 */
export function nextPriorityRangeStart(
  rules: PriorityRangeRule[],
  type: string,
  currency: string | null | undefined,
  excludeId?: string,
): number | null {
  if (!PRIORITY_RULE_TYPES.includes(type as PriorityRuleType)) return null;

  const scoped = rules
    .filter(
      (r) =>
        String(r.type ?? "") === type &&
        (excludeId === undefined || String(r.id ?? "") !== excludeId) &&
        (type !== "CURRENCY" ||
          String(r.currency ?? "") === String(currency ?? "")),
    )
    .map((r) => ({
      min: Number(r.minWagonCount ?? 0),
      max: Number(r.maxWagonCount ?? 0),
    }))
    .sort((a, b) => a.min - b.min);

  let next = 1;
  for (const r of scoped) {
    if (r.min > next) break; // gap before this rule — fill it first
    next = Math.max(next, r.max + 1);
  }
  return next;
}
