import type { ProfileField } from '@/services/profile-sections.service';

/**
 * Returns an error message if the given value fails validation for the field,
 * or null if it passes. Enforces:
 *   - required
 *   - TEXT/TEXTAREA: minLength, maxLength, pattern
 *   - NUMBER/RANGE: min, max
 *   - DATE: minDate, maxDate
 *   - CHECKBOX_GROUP / MULTI_SELECT / TAG_INPUT / RADIO / SELECT: required non-empty
 */
export function validateFieldValue(field: ProfileField, value: unknown): string | null {
  const v = field.validation ?? {};
  const fieldName = field.name || 'This field';

  const isEmpty =
    value === undefined ||
    value === null ||
    value === '' ||
    (Array.isArray(value) && value.length === 0);

  if (field.isRequired && isEmpty) {
    return `${fieldName} is required`;
  }
  if (isEmpty) return null; // optional + empty → OK

  switch (field.fieldType) {
    case 'TEXT':
    case 'TEXTAREA': {
      const str = String(value);
      if (typeof v.minLength === 'number' && str.length < v.minLength) {
        return `${fieldName} must be at least ${v.minLength} characters`;
      }
      if (typeof v.maxLength === 'number' && str.length > v.maxLength) {
        return `${fieldName} must be no more than ${v.maxLength} characters`;
      }
      if (v.pattern && typeof v.pattern === 'string') {
        try {
          if (!new RegExp(v.pattern).test(str)) {
            return `${fieldName} has an invalid format`;
          }
        } catch {
          // Invalid regex in admin config — silently skip
        }
      }
      return null;
    }

    case 'NUMBER':
    case 'RANGE': {
      const n = typeof value === 'number' ? value : parseFloat(String(value));
      if (!isFinite(n)) return `${fieldName} must be a number`;
      if (typeof v.min === 'number' && n < v.min) {
        return `${fieldName} must be at least ${v.min}`;
      }
      if (typeof v.max === 'number' && n > v.max) {
        return `${fieldName} must be no more than ${v.max}`;
      }
      return null;
    }

    case 'DATE': {
      const str = String(value).slice(0, 10); // YYYY-MM-DD
      if (!/^\d{4}-\d{2}-\d{2}$/.test(str)) {
        return `${fieldName} must be a valid date`;
      }
      if (v.minDate && str < v.minDate) {
        return `${fieldName} must be on or after ${v.minDate}`;
      }
      if (v.maxDate && str > v.maxDate) {
        return `${fieldName} must be on or before ${v.maxDate}`;
      }
      return null;
    }

    case 'TAG_INPUT': {
      // string items — apply maxLength per item if defined
      if (Array.isArray(value) && typeof v.maxLength === 'number') {
        const tooLong = (value as unknown[]).find(
          (item) => typeof item === 'string' && item.length > v.maxLength!,
        );
        if (tooLong) {
          return `Each ${fieldName.toLowerCase()} entry must be no more than ${v.maxLength} characters`;
        }
      }
      return null;
    }

    default:
      return null;
  }
}
