import type { DateUnit, Rule } from './types';

export const RELATIVE_FIELD_MAP = { release_date: 'released', added_date: 'added' } as const;
type RelField = keyof typeof RELATIVE_FIELD_MAP;

const OP_TO_SUFFIX = { inLast: 'inthelast', notInLast: 'notinthelast' } as const;
const SUFFIX_TO_OP = { inthelast: 'inLast', notinthelast: 'notInLast' } as const;
const CATALOG_FROM_PREFIX = { released: 'release_date', added: 'added_date' } as const;
const UNITS: DateUnit[] = ['day', 'week', 'month', 'year'];

export const RELATIVE_SYNTHETIC = /^(released|added)_(inthelast|notinthelast)$/;

function isValidN(value: string): boolean {
  const t = value.trim();
  return /^\d+$/.test(t) && Number(t) > 0;
}

export function compileRelative(rule: Rule): string | null {
  if (rule.operator !== 'inLast' && rule.operator !== 'notInLast') return null;
  const prefix = RELATIVE_FIELD_MAP[rule.field as RelField];
  if (!prefix) return null;
  if (!isValidN(rule.value) || !rule.unit || !UNITS.includes(rule.unit)) return null;
  return `${prefix}_${OP_TO_SUFFIX[rule.operator]}:"${rule.value} ${rule.unit}"`;
}

export function parseRelative(field: string, quoted: string): Rule | null {
  const m = RELATIVE_SYNTHETIC.exec(field);
  if (!m) return null;
  const [, prefix, suffix] = m;
  const vm = /^(\d+)\s+(day|week|month|year)$/.exec(quoted.trim());
  if (!vm) return null;
  const [, n, unit] = vm;
  if (!isValidN(n)) return null;
  return {
    field: CATALOG_FROM_PREFIX[prefix as 'released' | 'added'],
    operator: SUFFIX_TO_OP[suffix as 'inthelast' | 'notinthelast'],
    value: n,
    unit: unit as DateUnit
  };
}
