/**
 * consent-manager-helpers.ts
 *
 * Pure helper functions used by ConsentManager that have no dependency on
 * class instance state.  Extracted to keep ConsentManager.ts under the
 * 350 LOC soft target.
 */

import type {
  ConsentState,
  ConsentCategories,
  ConsentInput,
  ConsentConfig,
} from '../types';
import { DEFAULT_CONSENT } from './consent-manager-config';

/** All categories accepted (used by acceptAll). */
export const ALL_CATEGORIES: ConsentCategories = {
  essential: true,
  functional: true,
  analytics: true,
  marketing: true,
  social: true,
};

/** Only essential consent (used by rejectAll). */
export const MINIMAL_CATEGORIES: ConsentCategories = {
  essential: true,
  functional: false,
  analytics: false,
  marketing: false,
  social: false,
};

/**
 * Normalise a ConsentInput into a full ConsentCategories map.
 * Always returns a shallow copy — never mutates the input.
 */
export function normalizeConsentInput(input: ConsentInput): ConsentCategories {
  if ('categories' in input && input.categories) {
    return { ...DEFAULT_CONSENT, ...input.categories };
  }
  return { ...DEFAULT_CONSENT, ...(input as Partial<ConsentCategories>) };
}

/**
 * Return true when the stored consent record has passed its expiry date.
 * Falls back to `rememberDays` from config when `expiresAt` is absent.
 */
export function isConsentExpired(
  consent: ConsentState | null,
  config: ConsentConfig
): boolean {
  if (!consent) return false;

  if (!consent.expiresAt) {
    if (consent.timestamp && config.consent?.rememberDays) {
      const consentDate = new Date(consent.timestamp);
      const expiryDate = new Date(consentDate);
      expiryDate.setDate(expiryDate.getDate() + config.consent.rememberDays);
      return new Date() > expiryDate;
    }
    return false;
  }

  return new Date() > new Date(consent.expiresAt);
}

/**
 * Return true when the user needs to be shown the consent banner.
 */
export function needsConsent(
  consent: ConsentState | null,
  config: ConsentConfig
): boolean {
  if (!consent) return true;

  if (isConsentExpired(consent, config)) return true;

  if (config.consent?.recheckAfterDays) {
    const consentDate = new Date(consent.timestamp);
    const recheckDate = new Date(consentDate);
    recheckDate.setDate(recheckDate.getDate() + config.consent.recheckAfterDays);
    if (new Date() > recheckDate) return true;
  }

  return false;
}
