import axios from 'axios';
import * as Yup from "yup";
import { API_URL, reportAxiosError } from '../utils/RequestUtils';

/**
 * String enum for type of registration validation request to send to server
 */
type RegisterCredsValidationType = 'usernamevalidation' | 'emailvalidation';

export interface RegisterCredsValues {
    email: string;
    username: string;
}

const uniqueValidation = async (validationEndpoint: RegisterCredsValidationType, valueToValidate: string): Promise<boolean> => {
  try {
    const data = new FormData()
    data.append('input', valueToValidate)
    const response = await axios({
      method: 'POST',
      url: API_URL + '/api/' + validationEndpoint + '/',
      data: data,
    });
    if (response.data.valid) {
      return true;
    }
    else {
      return false;
    }
  } catch (error) {
    reportAxiosError('Username validation request failed.', error);
    return false;
  }
}

export const credsSchema = Yup.object({
  username: Yup
    .string()
    .trim()
    .required("You must enter a username.")
    .min(5, "Your username must be atleast 5 characters long.")
    .test("unique-username", "This username is already in use", async (value) => await uniqueValidation("usernamevalidation", value)),
  email: Yup
    .string()
    .trim()
    .required("You must enter an email.")
    .email("You must enter a valid email.")
    .test("unique-email", "This email is already in use", async (value) => await uniqueValidation("emailvalidation", value)),
})

export const profileCredsSchema = Yup.object({
  username: Yup
    .string()
    .trim()
    .required("You must enter a username.")
    .min(5, "Your username must be atleast 5 characters long."),
  email: Yup
    .string()
    .trim()
    .required("You must enter an email.")
    .email("You must enter a valid email.")
})

export const passwordSchema = Yup.object({
  password: Yup.string().trim().required("You must enter a password.").matches(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[\w~@#$%^&*+=`|{}:;!.?\"()\[\]-]{8,}$/, "Your password must be a minimum of 8 characters and contain 1 special character and 1 number."),
  confirmPassword: Yup.string().trim().required("You must confirm your password.").oneOf([Yup.ref('password'), null], "Your passwords must match.")
})