import { defineRule } from 'vee-validate';
import errorMessages from '@/constants/error-messages';
import globalRules from '@/constants/global-rules';
import { required, regex } from '@/helpers/validation-rules';

/**
 * @summary Define global rules related to names
 */
function defineGlobalNameRules() {
    defineRule(globalRules.FIRST_NAME_REQUIRED, required(errorMessages.FIRST_NAME_REQUIRED));
    defineRule(globalRules.LAST_NAME_REQUIRED, required(errorMessages.LAST_NAME_REQUIRED));
    defineRule(
        globalRules.POLICYHOLDER_FIRST_NAME_REQUIRED,
        required(errorMessages.POLICYHOLDER_FIRST_NAME_REQUIRED)
    );
    defineRule(
        globalRules.POLICYHOLDER_LAST_NAME_REQUIRED,
        required(errorMessages.POLICYHOLDER_LAST_NAME_REQUIRED)
    );
}

/**
 * @summary Define global rules related to email addresses
 */
function defineGlobalEmailRules() {
    defineRule(globalRules.EMAIL_ADDRESS_REQUIRED, required(errorMessages.EMAIL_ADDRESS_REQUIRED));
    defineRule(
        globalRules.EMAIL_ADDRESS_FORMAT,
        regex(
            /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/,
            errorMessages.EMAIL_ADDRESS_FORMAT
        )
    );
}

/**
 * @summary Define global rules related to date/location of loss information
 */
function defineGlobalDateOfLossRules() {
    defineRule(globalRules.DATE_OF_LOSS_REQUIRED, required(errorMessages.LOSS_DATE_REQUIRED));
    defineRule(globalRules.DATE_OF_LOSS_NOT_TEN_YEARS_PAST, (value) => {
        const lossDate = new Date(Date.parse(`${value}T00:00:00`));
        const today = new Date();
        const tenYearsAgo = new Date(today.getFullYear() - 10, today.getMonth(), today.getDate(), 0, 0, 0, 0);
        if (lossDate < tenYearsAgo) {
            return errorMessages.DAMAGE_DATE_REQUIREMENT;
        }

        return true;
    });
    defineRule(globalRules.DATE_OF_LOSS_NOT_FUTURE, (value) => {
        const lossDate = new Date(Date.parse(`${value}T00:00:00`));
        const today = new Date();
        const tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1, 0, 0, 0, 0);
        if (lossDate >= tomorrow) {
            return errorMessages.DAMAGE_DATE_NO_FUTURE_DATE;
        }

        return true;
    });
    defineRule(globalRules.DATE_OF_LOSS_CITY_REQUIRED, required(errorMessages.LOSS_CITY_REQUIRED));
    defineRule(
        globalRules.DATE_OF_LOSS_CITY_FORMAT,
        regex(/^[a-zA-Z .'-]+$/, errorMessages.LOSS_CITY_FORMAT)
    );
    defineRule(globalRules.DATE_OF_LOSS_STATE_REQUIRED, required(errorMessages.LOSS_STATE_REQUIRED));
}

/**
 * @summary Define global rules related to phone numbers
 */
function defineGlobalPhoneNumberRules() {
    defineRule(globalRules.PHONE_NUMBER_REQUIRED, required(errorMessages.PHONE_NUMBER_REQUIRED));
    defineRule(
        globalRules.PHONE_NUMBER_FORMAT,
        regex(
            /^(\([0-9]{3}\)|[0-9]{3}) *[-.]? *[0-9]{3} *[-.]? *[0-9]{4}$/,
            errorMessages.PHONE_NUMBER_REQUIRED
        )
    );
}

/**
 * @summary Define global rules related to extensions
 */
function defineGlobalExtensionRules() {
    defineRule(
        globalRules.EXTENSION_FORMAT,
        regex(/^[0-9]{1,5}$/, errorMessages.EXTENSION_FORMAT)
    );
}

/**
 * @summary Define global rules related to policy numbers
 */
function defineGlobalPolicyNumberRules() {
    defineRule(globalRules.POLICY_NUMBER_REQUIRED, required(errorMessages.POLICY_NUMBER_REQUIRED));
    defineRule(
        globalRules.POLICY_NUMBER_FORMAT,
        regex(
            /^~?[a-zA-Z0-9]+$/,
            errorMessages.POLICY_NUMBER_FORMAT
        )
    );
}

/**
 * @summary Define global rules related to policy zip codes
 */
function defineGlobalPolicyZipCodeRules() {
    defineRule(globalRules.POLICY_ZIP_REQUIRED, required(errorMessages.POLICY_ZIP_REQUIRED));
    defineRule(
        globalRules.POLICY_ZIP_FORMAT,
        regex(/^\d{5}$/, errorMessages.POLICY_ZIP_FORMAT)
    );
}

/**
 * @summary Define global rules related to zip codes
 */
function defineGlobalZipCodeRules() {
    defineRule(globalRules.ZIP_CODE_REQUIRED, required(errorMessages.ZIP_REQUIRED));
    defineRule(globalRules.ZIP_CODE_SEARCH_FORMAT, regex(/^\d{5}$/, errorMessages.ZIP_FORMAT));
}

/**
 * @function defineGlobalRules
 * @summary Define all global rules
 */
export default function defineGlobalRules() {
    defineGlobalNameRules();
    defineGlobalDateOfLossRules();
    defineGlobalEmailRules();
    defineGlobalPhoneNumberRules();
    defineGlobalExtensionRules();
    defineGlobalPolicyNumberRules();
    defineGlobalPolicyZipCodeRules();
    defineGlobalZipCodeRules();

    defineRule(globalRules.OPTION_REQUIRED, required(errorMessages.OPTION_REQUIRED));
}
