import { z } from "zod" import { phoneValidator } from "@scandic-hotels/common/utils/zod/phoneValidator" import { specialRequestSchema } from "@/components/HotelReservation/EnterDetails/Details/SpecialRequests/schema" // stringMatcher regex is copied from current web as specified by requirements. const stringMatcher = /^[A-Za-z¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ0-9-\s]*$/ const isValidString = (key: string) => stringMatcher.test(key) export const multiroomErrors = { COUNTRY_REQUIRED: "COUNTRY_REQUIRED", FIRST_NAME_REQUIRED: "FIRST_NAME_REQUIRED", FIRST_NAME_SPECIAL_CHARACTERS: "FIRST_NAME_SPECIAL_CHARACTERS", FIRST_AND_LAST_NAME_UNIQUE: "FIRST_AND_LAST_NAME_UNIQUE", LAST_NAME_REQUIRED: "LAST_NAME_REQUIRED", LAST_NAME_SPECIAL_CHARACTERS: "LAST_NAME_SPECIAL_CHARACTERS", PHONE_REQUIRED: "PHONE_REQUIRED", PHONE_REQUESTED: "PHONE_REQUESTED", EMAIL_REQUIRED: "EMAIL_REQUIRED", MEMBERSHIP_NO_ONLY_DIGITS: "MEMBERSHIP_NO_ONLY_DIGITS", MEMBERSHIP_NO_INVALID: "MEMBERSHIP_NO_INVALID", MEMBERSHIP_NO_UNIQUE: "MEMBERSHIP_NO_UNIQUE", } as const export type CrossValidationData = { firstName: string lastName: string membershipNo: string | undefined } export function getMultiroomDetailsSchema( crossValidationData: CrossValidationData[] | undefined = [] ) { return z .object({ countryCode: z.string().min(1, multiroomErrors.COUNTRY_REQUIRED), email: z.string().email(multiroomErrors.EMAIL_REQUIRED), firstName: z .string() .min(1, multiroomErrors.FIRST_NAME_REQUIRED) .refine(isValidString, multiroomErrors.FIRST_NAME_SPECIAL_CHARACTERS), join: z.boolean().default(false), lastName: z .string() .min(1, multiroomErrors.LAST_NAME_REQUIRED) .refine(isValidString, multiroomErrors.LAST_NAME_SPECIAL_CHARACTERS), phoneNumber: phoneValidator( multiroomErrors.PHONE_REQUIRED, multiroomErrors.PHONE_REQUESTED ), phoneNumberCC: z.string(), membershipNo: z .string() .optional() .refine((val) => { if (val) { return !val.match(/[^0-9]/g) } return true }, multiroomErrors.MEMBERSHIP_NO_ONLY_DIGITS) .refine((num) => { if (num) { return num.match(/^30812(?!(0|1|2))[0-9]{9}$/) } return true }, multiroomErrors.MEMBERSHIP_NO_INVALID), specialRequest: specialRequestSchema, }) .refine( (data) => !crossValidationData.some( (room) => room.firstName.toLowerCase() === data.firstName.toLowerCase() && room.lastName.toLowerCase() === data.lastName.toLowerCase() ), { message: multiroomErrors.FIRST_AND_LAST_NAME_UNIQUE, path: ["firstName"], } ) .refine( (data) => !crossValidationData.some( (room) => room.firstName.toLowerCase() === data.firstName.toLowerCase() && room.lastName.toLowerCase() === data.lastName.toLowerCase() ), { message: multiroomErrors.FIRST_AND_LAST_NAME_UNIQUE, path: ["lastName"], } ) .refine( (data) => !crossValidationData.some( (room) => room.membershipNo && room.membershipNo === data.membershipNo ), { message: multiroomErrors.MEMBERSHIP_NO_UNIQUE, path: ["membershipNo"], } ) }