const DATE_ONLY_RE = /^(\d{4})-(\d{1,2})-(\d{1,2})$/;

export function resolveAutoFillValue(item, form = {}) {
  const rule = item && item.autoFill;
  if (!rule || !rule.sourceField || !rule.type) return undefined;

  const sourceValue = form ? form[rule.sourceField] : '';
  if (!sourceValue) return '';

  if (rule.type === 'addDays') {
    const days = Number(rule.days);
    if (!Number.isFinite(days)) return '';
    return addDays(sourceValue, days);
  }

  return undefined;
}

export function collectAutoFillChanges(items = [], form = {}) {
  if (!Array.isArray(items)) return [];

  return items.reduce((changes, item) => {
    if (!item || !item.title) return changes;

    const nextValue = resolveAutoFillValue(item, form);
    if (nextValue === undefined) return changes;

    const currentValue = form && form[item.title] !== undefined && form[item.title] !== null
      ? String(form[item.title])
      : '';
    if (currentValue !== nextValue) {
      changes.push({ title: item.title, value: nextValue });
    }
    return changes;
  }, []);
}

function addDays(value, days) {
  const date = parseDateOnly(value);
  if (!date) return '';
  date.setUTCDate(date.getUTCDate() + days);
  return formatDateOnly(date);
}

function parseDateOnly(value) {
  const match = String(value || '').trim().match(DATE_ONLY_RE);
  if (!match) return null;

  const year = Number(match[1]);
  const month = Number(match[2]);
  const day = Number(match[3]);
  const date = new Date(Date.UTC(year, month - 1, day));

  if (
    date.getUTCFullYear() !== year ||
    date.getUTCMonth() !== month - 1 ||
    date.getUTCDate() !== day
  ) {
    return null;
  }
  return date;
}

function formatDateOnly(date) {
  const year = date.getUTCFullYear();
  const month = String(date.getUTCMonth() + 1).padStart(2, '0');
  const day = String(date.getUTCDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}
