import { assertNever } from '@shared/kernel/fp';
import { Registration, RegistrationStatus, StatusTag } from './registration';

/**
 * Domain logic for a registration — pure functions, NO Angular. This is where
 * "what the business rules say" lives, separate from "how it looks" (UI) and
 * "where the data comes from" (infrastructure). Keeping it framework-free means
 * it is trivial to read and unit-test.
 */

/** Human-readable label for a status. */
export function statusLabel(tag: StatusTag): string {
  return tag; // the tag already reads as Dutch; kept as a function so labels can diverge later
}

/** Brand colour token for a status. assertNever forces a colour for every new
    status variant at compile time. */
export function statusColor(tag: StatusTag): string {
  switch (tag) {
    case 'Geregistreerd':
      return 'var(--rhc-color-groen-500)';
    case 'Doorgehaald':
      return 'var(--rhc-color-rood-500)';
    case 'Geschorst':
      return 'var(--rhc-color-oranje-500)';
    default:
      return assertNever(tag);
  }
}

/** The herregistratie deadline, if the status has one (only the active state does). */
export function herregistratieDeadline(reg: Registration): Date | null {
  return reg.status.tag === 'Geregistreerd' ? new Date(reg.status.herregistratieDatum) : null;
}

/** A registration may apply for herregistratie only while active and within the
    window before its deadline. A struck-off or suspended registration may not.
    SERVER-OWNED RULE: this now runs on the backend (BFF), which ships the result
    as `decisions.eligibleForHerregistratie` in the dashboard view. Kept here as
    the reference implementation + unit test; the frontend no longer calls it. */
export function isHerregistratieEligible(
  reg: Registration,
  today: Date,
  windowMonths = 12,
): boolean {
  const deadline = herregistratieDeadline(reg);
  if (!deadline) return false;
  const windowStart = new Date(deadline);
  windowStart.setMonth(windowStart.getMonth() - windowMonths);
  return today >= windowStart;
}

/** Invariant check used in tests/demos: a non-active status must not carry a
    herregistratie date. The union already enforces this structurally; this is
    the runtime statement of the same rule. */
export function isStatusConsistent(status: RegistrationStatus): boolean {
  return status.tag === 'Geregistreerd' ? typeof status.herregistratieDatum === 'string' : true;
}
