import { z } from 'zod'
import { sanitizeAndFormat, getMaxLength } from './inputValidation'
import type { FieldType } from './inputValidation'

// ─── Regex constants ───────────────────────────────────────────

const GLOBAL_ALLOWED = /^[a-zA-Z0-9@\-/\s]*$/

const EMAIL_REGEX = /^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$/

/** Morocco phone: (+212|00212|0) + 5/6/7 + 8 digits (optional spaces) */
const MA_PHONE_REGEX = /^(?:(?:\+|00)212|0)\s?[5-7](?:\s?\d){8}$/

// ─── Phone sanitization ───────────────────────────────────────

function sanitizePhone(raw: string): string {
  let out = ''
  for (const ch of raw) {
    if (/[\d\s+]/.test(ch)) out += ch
  }
  return out.trim()
}

// ─── Required fields ───────────────────────────────────────────

function applyFieldRules(fieldType: FieldType) {
  const maxLength = getMaxLength(fieldType)
  return z
    .string()
    .min(1, { message: 'This field is required' })
    .trim()
    .transform((val: string) => sanitizeAndFormat(val, fieldType))
    .pipe(
      z.string().refine(
        (val: string) => val.length <= maxLength,
        { message: 'Maximum ' + maxLength + ' characters allowed' }
      )
    )
}

// ─── Optional fields ───────────────────────────────────────────

function applyOptionalFieldRules(fieldType: FieldType) {
  const maxLength = getMaxLength(fieldType)
  return z
    .string()
    .optional()
    .transform((val) => {
      if (val === undefined || val === null || val.trim() === '') return undefined
      return sanitizeAndFormat(val, fieldType)
    })
    .pipe(
      z.string().optional().refine(
        (val) => val === undefined || val.length <= maxLength,
        { message: 'Maximum ' + maxLength + ' characters allowed' }
      )
    )
}

// ─── Exported helpers ──────────────────────────────────────────

export function textField(fieldType: FieldType) {
  return applyFieldRules(fieldType)
}
export function optionalTextField(fieldType: FieldType) {
  return applyOptionalFieldRules(fieldType)
}
export function titleCaseAllField(fieldType: FieldType) {
  return applyFieldRules(fieldType)
}
export function optionalTitleCaseAllField(fieldType: FieldType) {
  return applyOptionalFieldRules(fieldType)
}
export function upperField(fieldType: FieldType) {
  return applyFieldRules(fieldType)
}
export function optionalUpperField(fieldType: FieldType) {
  return applyOptionalFieldRules(fieldType)
}
export function carTextField(fieldType: FieldType) {
  return applyFieldRules(fieldType)
}
export function optionalCarTextField(fieldType: FieldType) {
  return applyOptionalFieldRules(fieldType)
}
export function zipField() {
  return applyFieldRules('zipCode')
}
export function optionalZipField() {
  return applyOptionalFieldRules('zipCode')
}

// ─── Email fields ──────────────────────────────────────────────

export function emailField() {
  return z
    .string()
    .min(1, { message: 'Email is required' })
    .trim()
    .transform((val: string) => sanitizeAndFormat(val, 'email'))
    .pipe(
      z.string().refine(
        (val: string) => EMAIL_REGEX.test(val),
        { message: 'Please enter a valid email address' }
      )
    )
}

export function optionalEmailField() {
  return z
    .string()
    .optional()
    .transform((val) => {
      if (val === undefined || val === null || val.trim() === '') return undefined
      return sanitizeAndFormat(val, 'email')
    })
    .pipe(
      z.string().optional().refine(
        (val) => val === undefined || EMAIL_REGEX.test(val),
        { message: 'Please enter a valid email address' }
      )
    )
}

// ─── Phone fields ──────────────────────────────────────────────

export function phoneField() {
  return z
    .string()
    .min(1, { message: 'Phone number is required' })
    .trim()
    .transform((val: string) => sanitizePhone(val))
    .pipe(
      z.string().refine(
        (val: string) => MA_PHONE_REGEX.test(val),
        { message: 'Please enter a valid Morocco phone number' }
      )
    )
}

export function optionalPhoneField() {
  return z
    .string()
    .optional()
    .transform((val) => {
      if (val === undefined || val === null || val.trim() === '') return undefined
      return sanitizePhone(val)
    })
    .pipe(
      z.string().optional().refine(
        (val) => val === undefined || MA_PHONE_REGEX.test(val),
        { message: 'Please enter a valid Morocco phone number' }
      )
    )
}
