import { FormikErrors } from "formik";
import { isEmpty, set } from "lodash";
import { TravelersFormValues } from "../../types";
import { CHILD_MAX_AGE } from "./travelers-form-slice";
import { format } from "../../../shared/utils/localization-util";

function isValidEmail(email: string) {
  return !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,24}$/i.test(email);
}

function getAge(birthDateText: string, startDateText: string) {
  var birthDate = new Date(birthDateText);
  var startDate = new Date(startDateText);

  var age = startDate.getFullYear() - birthDate.getFullYear();
  var m = startDate.getMonth() - birthDate.getMonth();
  if (m < 0 || (m === 0 && startDate.getDate() < birthDate.getDate())) {
    age--;
  }
  return age;
}

const validateForm = (
  values: TravelersFormValues,
  agentRequired?: boolean,
  bookingType?: string,
  translations?: any,
) => {
  const errors: FormikErrors<TravelersFormValues> = {};

  values.rooms.forEach((r, rIndex) =>
    r.adults.forEach((adult, index) => {
      if (isEmpty(adult.gender)) {
        set(
          errors,
          `rooms[${rIndex}].adults[${index}].gender`,
          format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
            rIndex + 1,
            index + 1,
            translations.TRAVELERS_FORM.GENDER,
          ])
        );
      }

      if (isEmpty(adult.firstName)) {
        set(
          errors,
          `rooms[${rIndex}].adults[${index}].firstName`,
          format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
            rIndex + 1,
            index + 1,
            translations.TRAVELERS_FORM.FIRST_NAME,
          ])
        );
      }

      if (isEmpty(adult.lastName)) {
        set(
          errors,
          `rooms[${rIndex}].adults[${index}].lastName`,
          format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
            rIndex + 1,
            index + 1,
            translations.TRAVELERS_FORM.LAST_NAME,
          ])
        );
      }

      if (isEmpty(adult.birthDate)) {
        set(
          errors,
          `rooms[${rIndex}].adults[${index}].birthDate`,
          format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
            rIndex + 1,
            index + 1,
            translations.TRAVELERS_FORM.BIRTHDATE,
          ])
        );
      } else if (values.startDate) {
        const age = getAge(adult.birthDate, values.startDate);

        if (age <= CHILD_MAX_AGE) {
          set(
            errors,
            `rooms[${rIndex}].adults[${index}].birthDate`,
            format(
              translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_ADULT,
              [rIndex + 1, index + 1]
            )
          );
        }
      }
    })
  );

  values.rooms.forEach((r, rIndex) =>
    r.children.forEach((child, index) => {
      if (isEmpty(child.gender)) {
        set(
          errors,
          `rooms[${rIndex}].children[${index}].gender`,
          format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
            rIndex + 1,
            r.adults.length + index + 1,
            translations.TRAVELERS_FORM.GENDER,
          ])
        );
      }

      if (isEmpty(child.firstName)) {
        set(
          errors,
          `children[${index}].firstName`,
          format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
            rIndex + 1,
            r.adults.length + index + 1,
            translations.TRAVELERS_FORM.FIRST_NAME,
          ])
        );
      }

      if (isEmpty(child.lastName)) {
        set(
          errors,
          `rooms[${rIndex}].children[${index}].lastName`,
          format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
            rIndex + 1,
            r.adults.length + index + 1,
            translations.TRAVELERS_FORM.LAST_NAME,
          ])
        );
      }

      if (isEmpty(child.birthDate)) {
        set(
          errors,
          `rooms[${rIndex}].children[${index}].birthDate`,
          format(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD, [
            rIndex + 1,
            r.adults.length + index + 1,
            translations.TRAVELERS_FORM.BIRTHDATE,
          ])
        );
      } else if (values.startDate) {
        const age = getAge(child.birthDate, values.startDate);

        if (age > CHILD_MAX_AGE) {
          set(
            errors,
            `rooms[${rIndex}].children[${index}].birthDate`,
            format(
              translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_CHILD,
              [rIndex + 1, r.adults.length + index + 1]
            )
          );
        }
      }
    })
  );

  if (values.mainBookerId < 0) {
    errors.mainBookerId =
      translations.TRAVELERS_FORM.VALIDATION.NO_MAIN_BOOKER_SELECTED;
  }

  if (bookingType != "b2b") {
    if (isEmpty(values.street)) {
      errors.street = format(
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
        [translations.TRAVELERS_FORM.STREET]
      );
    }

    if (isEmpty(values.houseNumber)) {
      errors.houseNumber = format(
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
        [translations.TRAVELERS_FORM.HOUSE_NUMBER]
      );
    }

    if (isEmpty(values.zipCode)) {
      errors.zipCode = format(
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
        [translations.TRAVELERS_FORM.ZIPCODE]
      );
    }

    if (isEmpty(values.place)) {
      errors.place = format(
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
        [translations.TRAVELERS_FORM.CITY]
      );
    }

    if (isEmpty(values.email)) {
      errors.email = format(
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
        [translations.TRAVELERS_FORM.EMAIL]
      );
    } else if (isValidEmail(values.email)) {
      errors.email =
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_EMAIL_IS_INVALID;
    }

    if (isEmpty(values.emailConfirmation)) {
      errors.emailConfirmation = format(
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
        [translations.TRAVELERS_FORM.REPEAT_EMAIL]
      );
    } else if (values.emailConfirmation !== values.email) {
      errors.emailConfirmation =
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_EMAIL_DOES_NOT_MATCH;
    }

    if (isEmpty(values.country)) {
      errors.country = format(
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
        [translations.TRAVELERS_FORM.COUNTRY]
      );
    }

    if (isEmpty(values.phone)) {
      errors.phone = format(
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
        [translations.TRAVELERS_FORM.PHONE]
      );
    }
  } else {
    if (isEmpty(values.phone)) {
      errors.phone = format(
        translations.TRAVELERS_FORM.VALIDATION.MAIN_BOOKER_FIELD,
        [translations.TRAVELERS_FORM.PHONE]
      );
    }
  }

  if (agentRequired && !values.travelAgentId) {
    errors.travelAgentId =
      translations.TRAVELERS_FORM.VALIDATION.AGENT_IS_REQUIRED;
  }

  return errors;
};

export default validateForm;
