import { z } from "zod";

export const zValidate = (name: string | null) => {
  return {
    required_error: `${name ? name : "این فیلد"} الزامی است!`,
    invalid_type_error: "لطفا فیلد را به درستی پر کنید!",
  };
};

export const zValidateNumber = (name: string | null) => {
  return z.coerce
    .number(zValidate(name || null))
    .min(1, `${name || "فیلد"} نمیتواند خالی باشد!`);
};

export const zValidateNumberOptional = (name: string | null) => {
  return z.coerce.number(zValidate(name || null)).optional();
};

export const zValidateString = (name: string | null) => {
  return z.coerce
    .string(zValidate(name || null))
    .min(1, `${name || "فیلد"} نمیتواند خالی باشد!`);
};
export const zValidateStringOptional = (name: string | null) => {
  return z.coerce.string(zValidate(name || null)).optional();
};

export const zValidateBigNumber = (name: string | null) => {
  return z.coerce
    .string(zValidate(name || null))
    .min(1, `${name || "فیلد"} نمیتواند خالی باشد!`)
    .regex(/^\d+$/, `فقط اعداد مجاز است!`);
};

export const zValidateEnglishString = (name: string | null) => {
  return z.coerce
    .string(zValidate(name || null))
    .min(1, `${name || "فیلد"} نمیتواند خالی باشد!`)
    .regex(
      /^[A-Za-z0-9\s!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]*$/,
      `صرفا حروف انگلیسی وارد کنید!`
    );
};
export const zValidateAutoComplete = (name: string | null) => {
  return z
    .array(z.union([z.string(), z.number()]))
    .min(1, { message: `لطفاً ${name} را انتخاب کنید.` });
};

export const zValidateAutoCompleteOptional = () => {
  return z.array(z.union([z.string(), z.number()])).optional();
};

export const zValidateMobile = (name: string | null = "شماره موبایل") => {
  return z.coerce
    .string(zValidate(name))
    .min(1, `${name || "فیلد"} نمیتواند خالی باشد!`)
    .regex(/^09\d{9}$/, `موبایل باید با 09 شروع شود و 11 رقم باشد!`);
};

export const zValidateBase64 = (name: string | null) => {
  return z.coerce
    .string()
    .min(1, `${name || "فیلد"} نمیتواند خالی باشد!`)
    .regex(
      /^data:\w+\/\w+;base64,([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/,
      name ? `${name} معتبر نیست!` : "یک فرمت معتبر وارد کنید!"
    );
};

export const zValidateBase64Optional = (name: string | null) => {
  return z
    .union([
      z.literal(""),
      z.literal(null),
      z.coerce
        .string()
        .regex(
          /^data:\w+\/\w+;base64,([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/,
          name ? `${name} معتبر نیست!` : "یک فرمت معتبر وارد کنید!"
        ),
    ])
    .optional()
    .transform((value) => (value === "" ? null : value));
};

export const zValidateNationalCode = (name: string | null = "کد ملی") => {
  return z.coerce
    .string(zValidate(name))
    .min(1, `${name || "فیلد"} نمیتواند خالی باشد!`)
    .length(10, "کد ملی باید 10 رقمی باشد!")
    .regex(/^\d{10}$/, "کد ملی باید فقط شامل اعداد باشد!")
    .refine((code) => {
      if (/^(\d)\1{9}$/.test(code)) {
        return false;
      }

      const check = parseInt(code[9], 10);
      let sum = 0;

      for (let i = 0; i < 9; i++) {
        sum += parseInt(code[i], 10) * (10 - i);
      }

      const remainder = sum % 11;

      return (
        (remainder < 2 && check === remainder) ||
        (remainder >= 2 && check === 11 - remainder)
      );
    }, "کد ملی وارد شده معتبر نیست!");
};

export const zValidateNationalCodeOptional = (
  name: string | null = "کد ملی"
) => {
  return z
    .union([
      z.literal(""),
      z.literal(null),
      z.coerce
        .string(zValidate(name))
        .length(10, "کد ملی باید 10 رقمی باشد!")
        .regex(/^\d{10}$/, "کد ملی باید فقط شامل اعداد باشد!")
        .refine((code) => {
          if (/^(\d)\1{9}$/.test(code)) {
            return false;
          }

          const check = parseInt(code[9], 10);
          let sum = 0;

          for (let i = 0; i < 9; i++) {
            sum += parseInt(code[i], 10) * (10 - i);
          }

          const remainder = sum % 11;

          return (
            (remainder < 2 && check === remainder) ||
            (remainder >= 2 && check === 11 - remainder)
          );
        }, "کد ملی وارد شده معتبر نیست!"),
    ])
    .optional()
    .transform((value) => (value === "" ? null : value));
};
