import { setLocale } from 'yup'

import { fields } from '@/constants/fields'

const FA_DIGITS = '۰۱۲۳۴۵۶۷۸۹'

const toFaDigits = (value) => String(value ?? '').replace(/\d/g, (digit) => FA_DIGITS[digit])

const label = (path) => {
  const normalizedPath = String(path ?? '').replace(/\[\d+]/g, '')
  const fieldName = normalizedPath.split('.').pop()
  return fields[path] || fields[normalizedPath] || fields[fieldName] || path || 'مقدار'
}

const typeError = ({ path, type }) => {
  const field = label(path)
  const messages = {
    array: `فیلد ${field} باید به‌صورت فهرست باشد`,
    boolean: `فیلد ${field} باید مقدار بله یا خیر داشته باشد`,
    date: `فیلد ${field} باید یک تاریخ معتبر باشد`,
    number: `فیلد ${field} باید عدد باشد`,
    object: `ساختار فیلد ${field} معتبر نیست`,
    string: `فیلد ${field} باید متن باشد`,
  }
  return messages[type] || `نوع مقدار فیلد ${field} معتبر نیست`
}

setLocale({
  mixed: {
    default: ({ path }) => `مقدار فیلد ${label(path)} معتبر نیست`,
    required: ({ path }) => `فیلد ${label(path)} ضروری است`,
    defined: ({ path }) => `فیلد ${label(path)} باید مقدار داشته باشد`,
    notNull: ({ path }) => `فیلد ${label(path)} نمی‌تواند خالی باشد`,
    oneOf: ({ path }) => `مقدار انتخاب‌شده برای فیلد ${label(path)} معتبر نیست`,
    notOneOf: ({ path }) => `مقدار انتخاب‌شده برای فیلد ${label(path)} مجاز نیست`,
    notType: typeError,
  },
  string: {
    min: ({ path, min }) => `فیلد ${label(path)} باید حداقل ${toFaDigits(min)} کاراکتر باشد`,
    max: ({ path, max }) => `فیلد ${label(path)} باید حداکثر ${toFaDigits(max)} کاراکتر باشد`,
    email: ({ path }) => `فیلد ${label(path)} باید یک ایمیل معتبر باشد`,
    url: ({ path }) => `فیلد ${label(path)} باید یک نشانی اینترنتی معتبر باشد`,
    length: ({ path, length }) =>
      `فیلد ${label(path)} باید دقیقاً ${toFaDigits(length)} کاراکتر باشد`,
    matches: ({ path }) => `فرمت فیلد ${label(path)} صحیح نیست`,
    uuid: ({ path }) => `شناسه فیلد ${label(path)} معتبر نیست`,
    datetime: ({ path }) => `فیلد ${label(path)} باید یک تاریخ و زمان معتبر باشد`,
    datetime_precision: ({ path }) => `دقت زمانی فیلد ${label(path)} معتبر نیست`,
    datetime_offset: ({ path }) => `منطقه زمانی فیلد ${label(path)} معتبر نیست`,
    trim: ({ path }) => `ابتدا یا انتهای فیلد ${label(path)} نباید فاصله داشته باشد`,
    lowercase: ({ path }) => `فیلد ${label(path)} باید با حروف کوچک نوشته شود`,
    uppercase: ({ path }) => `فیلد ${label(path)} باید با حروف بزرگ نوشته شود`,
  },
  number: {
    min: ({ path, min }) => `فیلد ${label(path)} باید حداقل ${toFaDigits(min)} باشد`,
    max: ({ path, max }) => `فیلد ${label(path)} باید حداکثر ${toFaDigits(max)} باشد`,
    lessThan: ({ path, less }) => `فیلد ${label(path)} باید کمتر از ${toFaDigits(less)} باشد`,
    moreThan: ({ path, more }) => `فیلد ${label(path)} باید بیشتر از ${toFaDigits(more)} باشد`,
    positive: ({ path }) => `فیلد ${label(path)} باید عددی بزرگ‌تر از صفر باشد`,
    negative: ({ path }) => `فیلد ${label(path)} باید عددی کوچک‌تر از صفر باشد`,
    integer: ({ path }) => `فیلد ${label(path)} باید عدد صحیح باشد`,
  },
  date: {
    min: ({ path }) => `تاریخ فیلد ${label(path)} زودتر از محدوده مجاز است`,
    max: ({ path }) => `تاریخ فیلد ${label(path)} دیرتر از محدوده مجاز است`,
  },
  boolean: {
    isValue: ({ path }) => `مقدار فیلد ${label(path)} معتبر نیست`,
  },
  object: {
    noUnknown: ({ path }) => `فیلد ${label(path)} شامل مقادیر ناشناخته است`,
    exact: ({ path }) => `فیلد ${label(path)} شامل مقادیر اضافی است`,
  },
  array: {
    min: ({ path, min }) => `فیلد ${label(path)} باید حداقل ${toFaDigits(min)} مورد داشته باشد`,
    max: ({ path, max }) => `فیلد ${label(path)} باید حداکثر ${toFaDigits(max)} مورد داشته باشد`,
    length: ({ path, length }) =>
      `فیلد ${label(path)} باید دقیقاً ${toFaDigits(length)} مورد داشته باشد`,
  },
  tuple: {
    notType: typeError,
  },
})
