console.log("load validate.js");

$.validator.setDefaults({ ignore: ".js-ignore-validate" });

const RULE_METHODS = {
    formatedTel: function (value, element, params) {
        const $tels = $(params);

        let tel_length = 0;
        $tels.each(function () {
            tel_length += $(this).val().length;
        });

        if (10 <= tel_length && tel_length <= 11) {
            return true;
        } else {
            return false;
        }
    },
    required_1to4_images: function (value, element, params) {
        const image_count = $(element).val();

        if (_.isBoolean(params) && params == true) {
            if (image_count >= 1 && image_count <= 4) {
                return true;
            } else {
                return false;
            }
        } else if (_.isFunction(params)) {
            return params(element);
        } else {
            return false;
        }
    },
};
$.each(RULE_METHODS, function (key) {
    $.validator.addMethod(key, this);
});

$.validator.addMethod(
    // ルールの名前を指定
    "regex",
    // ルールのメソッド
    function (value, element, regexp) {
        return this.optional(element) || regexp.test(value);
    },
    // ルールに反した時のメッセージ
    "無効な文字があります。"
);

$.validator.addMethod(
    // ルールの名前を指定
    "validateStartAndEndDate", // 勤務開始と勤務終了の前後関係のチェック
    // ルールのメソッド
    function (value, element, index) {
        if (this.optional(element)) {
            return true;
        }
        let startDateYear = $(
            `select[name="user[user_resumes_attributes][${index}][work_start_date_year]"]`
        ).val();
        let startDateMonth = $(
            `select[name="user[user_resumes_attributes][${index}][work_start_date_month]"]`
        ).val();
        let endDateYear = $(
            `select[name="user[user_resumes_attributes][${index}][work_end_date_year]"]`
        ).val();
        let endDateMonth = $(
            `select[name="user[user_resumes_attributes][${index}][work_end_date_month]"]`
        ).val();
        if (
            !startDateYear ||
            !startDateMonth ||
            !endDateYear ||
            !endDateMonth
        ) {
            return true;
        }
        let startYearMonth = parseInt(
            startDateYear + ("00" + startDateMonth).slice(-2),
            10
        );
        let endYearMonth = parseInt(
            endDateYear + ("00" + endDateMonth).slice(-2),
            10
        );

        return startYearMonth <= endYearMonth;
    },
    // ルールに反した時のメッセージ
    "勤務終了は勤務開始より未来の日付を選択してください。"
);

$.validator.addMethod(
    // ルールの名前を指定
    "validateStartDate", // 勤務開始と次の経歴の勤務終了の前後関係のチェック
    // ルールのメソッド
    function (value, element, index) {
        if (this.optional(element)) {
            return true;
        }
        if (index === 2) {
            return true;
        }
        let nextIndex = index + 1;
        let startDateYear = $(
            `select[name="user[user_resumes_attributes][${index}][work_start_date_year]"]`
        ).val();
        let startDateMonth = $(
            `select[name="user[user_resumes_attributes][${index}][work_start_date_month]"]`
        ).val();
        let nextEndDateYear = $(
            `select[name="user[user_resumes_attributes][${nextIndex}][work_end_date_year]"]`
        ).val();
        let nextEndDateMonth = $(
            `select[name="user[user_resumes_attributes][${nextIndex}][work_end_date_month]"]`
        ).val();
        if (
            !startDateYear ||
            !startDateMonth ||
            !nextEndDateYear ||
            !nextEndDateMonth
        ) {
            return true;
        }

        let startYearMonth = parseInt(
            startDateYear + ("00" + startDateMonth).slice(-2),
            10
        );
        let nextEndYearMonth = parseInt(
            nextEndDateYear + ("00" + nextEndDateMonth).slice(-2),
            10
        );

        return nextEndYearMonth <= startYearMonth;
    },
    // ルールに反した時のメッセージ
    "勤務開始は次の経歴の勤務終了より未来の日付を選択してください。"
);

$.validator.addMethod(
    // ルールの名前を指定
    "validateEndDate", // 勤務終了と前の経歴の勤務開始の前後関係のチェック
    // ルールのメソッド
    function (value, element, index) {
        if (this.optional(element)) {
            return true;
        }
        if (index === 0) {
            return true;
        }
        let prevIndex = index - 1;
        let prevStartDateYear = $(
            `select[name="user[user_resumes_attributes][${prevIndex}][work_start_date_year]"]`
        ).val();
        let prevStartDateMonth = $(
            `select[name="user[user_resumes_attributes][${prevIndex}][work_start_date_month]"]`
        ).val();
        let endDateYear = $(
            `select[name="user[user_resumes_attributes][${index}][work_end_date_year]"]`
        ).val();
        let endDateMonth = $(
            `select[name="user[user_resumes_attributes][${index}][work_end_date_month]"]`
        ).val();
        if (
            !prevStartDateYear ||
            !prevStartDateMonth ||
            !endDateYear ||
            !endDateMonth
        ) {
            return true;
        }

        let prevStartYearMonth = parseInt(
            prevStartDateYear + ("00" + prevStartDateMonth).slice(-2),
            10
        );
        let endYearMonth = parseInt(
            endDateYear + ("00" + endDateMonth).slice(-2),
            10
        );

        return endYearMonth <= prevStartYearMonth;
    },
    // ルールに反した時のメッセージ
    "勤務終了は前の経歴の勤務開始より過去の日付を選択してください。"
);

$.validator.addMethod(
    // ルールの名前を指定
    "validateLatestWorkDate", // 現在日付と1社目の経歴の勤務開始・勤務終了の前後関係のチェック
    // ルールのメソッド
    function (value, element, index) {
        if (this.optional(element)) {
            return true;
        }
        if (index !== 0) {
            return true;
        }
        let startDateYear = $(
            `select[name="user[user_resumes_attributes][${index}][work_start_date_year]"]`
        ).val();
        let startDateMonth = $(
            `select[name="user[user_resumes_attributes][${index}][work_start_date_month]"]`
        ).val();
        if (!startDateYear || !startDateMonth) {
            return true;
        }
        let date = new Date();
        let currentYear = date.getFullYear().toString();
        let currentMonth = ("00" + (date.getMonth() + 1).toString()).slice(-2);
        let currentYearMonth = parseInt(currentYear + currentMonth, 10);

        let startYearMonth = parseInt(
            startDateYear + ("00" + startDateMonth).slice(-2),
            10
        );
        if (currentYearMonth < startYearMonth) {
            return false;
        }

        let endDateYear = $(
            `select[name="user[user_resumes_attributes][${index}][work_end_date_year]"]`
        ).val();
        let endDateMonth = $(
            `select[name="user[user_resumes_attributes][${index}][work_end_date_month]"]`
        ).val();
        if (!endDateYear || !endDateMonth) {
            return true;
        }

        let endYearMonth = parseInt(
            endDateYear + ("00" + endDateMonth).slice(-2),
            10
        );
        return endYearMonth <= currentYearMonth;
    },
    // ルールに反した時のメッセージ
    "1社目の勤務開始・終了は現在より過去の日付を選択してください。"
);

$.validator.addMethod(
    "validateMyPageStartAndEndDate",
    function (value, element, index) {
        if (this.optional(element)) {
            return true;
        }
        if (index === 0) {
            return true;
        }

        let startDateYear = $(
            `[name="user_resume[work_start_date_year]"]`
        ).val();
        let startDateMonth = $(
            `[name="user_resume[work_start_date_month]"]`
        ).val();
        if (!startDateYear || !startDateMonth) {
            return true;
        }

        let endDateYear = $(`[name="user_resume[work_end_date_year]"]`).val();
        let endDateMonth = $(`[name="user_resume[work_end_date_month]"]`).val();
        if (!endDateYear || !endDateMonth) {
            return true;
        }

        let startYearMonth = parseInt(
            startDateYear + ("00" + startDateMonth).slice(-2),
            10
        );
        let endYearMonth = parseInt(
            endDateYear + ("00" + endDateMonth).slice(-2),
            10
        );

        return startYearMonth <= endYearMonth;
    },
    // ルールに反した時のメッセージ
    "勤務終了は勤務開始より未来の日付を選択してください。"
);

$.validator.addMethod(
    "validateMyPageStartDate",
    function (value, element, index) {
        if (this.optional(element)) {
            return true;
        }
        if (index === 0) {
            return true;
        }

        let startDateYear = $(
            `[name="user_resume[work_start_date_year]"]`
        ).val();
        let startDateMonth = $(
            `[name="user_resume[work_start_date_month]"]`
        ).val();
        if (!startDateYear || !startDateMonth) {
            return true;
        }

        let startYearMonth = parseInt(
            startDateYear + ("00" + startDateMonth).slice(-2),
            10
        );

        let mindate = $(`[name="user_resume[work_start_date_year]"]`).data(
            "mindate"
        );
        if (!mindate) {
            return true;
        }

        let prevEndDate = new Date(Date.parse(mindate));
        let prevEndYear = prevEndDate.getFullYear().toString();
        let prevEndMonth = (
            "00" + (prevEndDate.getMonth() + 1).toString()
        ).slice(-2);
        let prevEndYearMonth = parseInt(prevEndYear + prevEndMonth, 10);

        return prevEndYearMonth <= startYearMonth;
    },
    // ルールに反した時のメッセージ
    "勤務開始は前の経歴の勤務終了より未来の日付を選択してください。"
);

$.validator.addMethod(
    "validateMyPageEndDate",
    function (value, element, index) {
        if (this.optional(element)) {
            return true;
        }
        if (index === 0) {
            return true;
        }

        let endDateYear = $(`[name="user_resume[work_end_date_year]"]`).val();
        let endDateMonth = $(`[name="user_resume[work_end_date_month]"]`).val();
        if (!endDateYear || !endDateMonth) {
            return true;
        }

        let endYearMonth = parseInt(
            endDateYear + ("00" + endDateMonth).slice(-2),
            10
        );

        let maxdate = $(`[name="user_resume[work_end_date_year]"]`).data(
            "maxdate"
        );
        if (!maxdate) {
            return true;
        }

        let nextStartDate = new Date(Date.parse(maxdate));
        let nextStartYear = nextStartDate.getFullYear().toString();
        let nextStartMonth = (
            "00" + (nextStartDate.getMonth() + 1).toString()
        ).slice(-2);
        let nextStartYearMonth = parseInt(nextStartYear + nextStartMonth, 10);

        return endYearMonth <= nextStartYearMonth;
    },
    // ルールに反した時のメッセージ
    "勤務終了は次の経歴の勤務開始より過去の日付を選択してください。"
);

$.validator.addMethod(
    "valueNotEquals",
    function (value, element, arg) {
        console.log(arg, value);
        return arg !== value;
    },
    "Value must not equal arg."
);

const REGEX_HIRAGANA = /^[ぁ-んー]+$/;
const REGEX_KATAKANA = /^[ア-ン゛゜ァ-ォャ-ョーヴ]+$/;
const REGEX_NUMBER = /^[0-9]+$/;
const REGEX_YAER = /^(18|19|20)[0-9]{2}$/;
const REGEX_MONTH = /^([1-9]|1[0-2])$/;
const REGEX_TEL = /^0\d{9,10}$/;
const REGEX_PASSWORD = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,32}$/;
const ERROR_REGEX_PASSWORD =
    "大小英数字を含む8文字以上32文字以下で入力してください";

const ERROR_MESSAGE__REQUIRED_INPUT = "入力してください";
const ERROR_MESSAGE__REQUIRED_SELECT = "選択してください";
const ERROR_MESSAGE__REQUIRED_FILE = "ファイルを選択してください";
const ERROR_MESSAGE__REQUIRED_NUMBER = "整数で入力してください";
const ERROR_MESSAGE__MAXLENGTH_1 = "1文字使用できます";
const ERROR_MESSAGE__MAXLENGTH_50 = "最大50文字まで使用できます";
const ERROR_MESSAGE__MAXLENGTH_100 = "最大100文字まで使用できます";
const ERROR_MESSAGE__MAXLENGTH_200 = "最大200文字まで使用できます";
const ERROR_MESSAGE__MAXLENGTH_250 = "最大250文字まで使用できます";
const ERROR_MESSAGE__MAXLENGTH_60000 = "最大60000文字まで使用できます";
const ERROR_MESSAGE__MAXLENGTH_65535 = "最大65535文字まで使用できます";
const ERROR_MESSAGE__NUMBER = "数字で入力してください";
const ERROR_MESSAGE__EMAIL = "正しいメールアドレスの形式で入力してください";
const ERROR_MESSAGE__TEL = "電話番号は10桁か11桁で入力してください";
const ERROR_MESSAGE__UPPER_ALPHABETIC =
    "半角英字（大文字のみ）で入力してください";
const ERROR_MESSAGE__FILESIZE_OVERFLOW_3M =
    "ファイルサイズは3MB以下にしてください";
const ERROR_MESSAGE__FILESIZE_OVERFLOW_10M =
    "ファイルサイズは10MB以下にしてください";
const ERROR_MESSAGE__INVALID_DATE = "有効な日付を選択してください";
const ERROR_MESSAGE__EXTENSION_PDF = "PDFファイルを選択してください";

const invalidHandler = function (form, validator) {
    if (!validator.numberOfInvalids()) return;
    if (!$(".js-user-registrations-resume-form").hasClass("is-hide")) {
        return;
    }
    if ($(validator.errorList[0].element).attr("type") == "hidden") {
        $("html, body").animate(
            {
                scrollTop:
                    $(validator.errorList[0].element).parent().offset().top -
                    $("header").height() -
                    150,
            },
            10
        );
    } else {
        $("html, body").animate(
            {
                scrollTop:
                    $(validator.errorList[0].element).offset().top -
                    $("header").height() -
                    150,
            },
            10
        );
    }
};

const resume_rules = {
    //STEP1
    "user_resume[company_name]": {
        required: true,
    },
    "user_resume[work_start_date_year]": {
        required: true,
        regex: REGEX_YAER,
        validateMyPageStartDate: true,
    },
    "user_resume[work_start_date_month]": {
        required: true,
        regex: REGEX_MONTH,
        validateMyPageStartDate: true,
    },
    "user_resume[work_end_date_year]": {
        required: true,
        regex: REGEX_YAER,
        validateMyPageEndDate: true,
        validateMyPageStartAndEndDate: true,
    },
    "user_resume[work_end_date_month]": {
        required: true,
        regex: REGEX_MONTH,
        validateMyPageEndDate: true,
        validateMyPageStartAndEndDate: true,
    },
    "user_resume[employment_id]": {
        required: true,
    },
    "user_resume[genre_id]": {
        required: true,
    },
    "user_resume[user_occupation_resumes_attributes][0][occupation_id]": {
        required: true,
    },
    "user_resume[job_description]": {
        required: true,
        minlength: 10,
        maxlength: 5000,
    },
};

const resume_messages = {
    "user_resume[company_name]": {
        required: "会社名または店舗名を入力してください",
    },
    "user_resume[work_start_date_year]": {
        required: "勤務開始日を入力してください",
        regex: "勤務開始日を入力してください",
    },
    "user_resume[work_start_date_month]": {
        required: "勤務開始日を入力してください",
        regex: "勤務開始日を入力してください",
    },
    "user_resume[work_end_date_year]": {
        required: "勤務終了日を入力してください",
        regex: "終了日を入力してください",
    },
    "user_resume[work_end_date_month]": {
        required: "勤務終了日を入力してください",
        regex: "終了日を入力してください",
    },
    "user_resume[employment_id]": {
        required: "雇用形態を選択してください",
    },
    "user_resume[genre_id]": {
        required: "料理ジャンルを選択してください",
    },
    "user_resume[user_occupation_resumes_attributes][0][occupation_id]": {
        required: "仕事内容を選択してください",
    },
    "user_resume[job_description]": {
        required: "仕事内容を入力してください",
        minlength: "10文字以上入力してください",
        maxlength: "5000文字以下で入力してください",
    },
};

const resume_groups = {
    user_resume_start_date:
        "user_resume[work_start_date_year] user_resume[work_start_date_month]",
    user_resume_end_date:
        "user_resume[work_end_date_year] user_resume[work_end_date_month]",
};

$(function () {
    $(".js-validate-resume-form form").each(function () {
        $(this).validate({
            rules: resume_rules,
            messages: resume_messages,
            groups: resume_groups,
            errorElement: "div",
            maxErrorsPerField: 1,
            highlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.addClass("is-error");
            },
            unhighlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.removeClass("is-error");
            },
            errorPlacement: function (error, element) {
                const DEBUG = false;
                if (DEBUG) {
                    const errorMessage = error[0].innerText;
                    console.log(errorMessage);
                    console.log(error);
                    console.log(element);
                }
                const $input = $(element);
                error.appendTo(
                    $input
                        .parents(".js-input-area")
                        .find(".js-input-area__error")
                );
                $input.addClass("is-error");
            },
            invalidHandler,
        });
    });
});

const user_registration_rules = {
    "user[situation]": {
        required: true,
    },
    "user[prefecture_id]": {
        required: true,
    },
    "user[city_id]": {
        required: true,
    },
    "user[first_name]": {
        required: true,
    },
    "user[last_name]": {
        required: true,
    },
    "user[first_name_kana]": {
        required: true,
        regex: REGEX_KATAKANA,
    },
    "user[last_name_kana]": {
        required: true,
        regex: REGEX_KATAKANA,
    },
    "user[birthday_year]": {
        required: true,
        regex: REGEX_YAER,
    },
    "user[birthday_month]": {
        required: true,
        regex: REGEX_MONTH,
    },
    "user[sex]": {
        required: true,
    },
    "user[tel]": {
        required: true,
        regex: REGEX_TEL,
        minlength: 10,
        maxlength: 11,
    },
    "user[line_id]": {
        regex: /^[a-zA-Z0-9-_]*$/,
    },
    "user[email]": {
        required: true,
        email: true,
        remote: {
            url: "/api/v1/users/check_if_registered",
            type: "POST",
            dataType: "json",
            data: {
                email: $(".js-user-registration-email").val(),
            },
        },
    },
    "user[password]": {
        required: true,
        minlength: 8,
        regex: REGEX_PASSWORD,
    },
    "user[agree_terms]": {
        required: true,
    },
    "user[agree_privacy]": {
        required: true,
    },
};

for (let i = 0; i < 3; i++) {
    let rules = {
        [`user[user_resumes_attributes][${i}][company_name]`]: {
            required: true,
        },
        [`user[user_resumes_attributes][${i}][work_start_date_year]`]: {
            required: true,
            validateStartAndEndDate: i,
            validateStartDate: i,
            validateLatestWorkDate: i,
        },
        [`user[user_resumes_attributes][${i}][work_start_date_month]`]: {
            required: true,
            validateStartAndEndDate: i,
            validateStartDate: i,
            validateLatestWorkDate: i,
        },
        [`user[user_resumes_attributes][${i}][work_end_date_year]`]: {
            required: {
                depends: function () {
                    return (
                        0 < i ||
                        $('input[name="user[situation]"]:checked').val() ===
                            "resignation"
                    );
                },
            },
            validateStartAndEndDate: i,
            validateEndDate: i,
            validateLatestWorkDate: i,
        },
        [`user[user_resumes_attributes][${i}][work_end_date_month]`]: {
            required: {
                depends: function () {
                    return (
                        0 < i ||
                        $('input[name="user[situation]"]:checked').val() ===
                            "resignation"
                    );
                },
            },
            validateStartAndEndDate: i,
            validateEndDate: i,
            validateLatestWorkDate: i,
        },
        [`user[user_resumes_attributes][${i}][employment_id]`]: {
            required: true,
        },
        [`user[user_resumes_attributes][${i}][genre_id]`]: {
            required: true,
        },
        [`user[user_resumes_attributes][${i}][user_occupation_resumes_attributes][0][occupation_id]`]:
            {
                required: true,
            },
        [`user[user_resumes_attributes][${i}][job_description]`]: {
            required: true,
            minlength: 10,
            maxlength: 5000,
        },
    };
    Object.assign(user_registration_rules, rules);
}

const user_registration_messages = {
    "user[situation]": {
        required: "選択してください",
    },
    "user[prefecture_id]": {
        required: "選択してください",
    },
    "user[city_id]": {
        required: "選択してください",
    },
    "user[first_name]": {
        required: "入力してください",
    },
    "user[last_name]": {
        required: "入力してください",
    },
    "user[last_name_kana]": {
        required: "入力してください",
        regex: "カタカナで入力してください",
    },
    "user[first_name_kana]": {
        required: "入力してください",
        regex: "カタカナで入力してください",
    },
    "user[birthday_year]": {
        required: "選択してください",
    },
    "user[birthday_month]": {
        required: "選択してください",
    },
    "user[sex]": {
        required: "選択してください",
    },
    "user[tel]": {
        required: "入力してください",
        regex: "電話番号を入力してください",
        minlength: "10桁以上で入力してください",
        maxlength: "11桁以下で入力してください",
    },
    "user[line_id]": {
        regex: "半角英数字で入力してください",
    },
    "user[email]": {
        required: "入力してください",
        email: "メールアドレスを入力してください",
        remote: "このメールアドレスはすでに登録されています",
    },
    "user[password]": {
        required: "入力してください",
        minlength: "8文字以上で入力してください",
        regex: ERROR_REGEX_PASSWORD,
    },
    "user[agree_terms]": {
        required: "選択してください",
    },
    "user[agree_privacy]": {
        required: "選択してください",
    },
};

for (let i = 0; i < 3; i++) {
    let messages = {
        [`user[user_resumes_attributes][${i}][company_name]`]: {
            required: "入力してください",
        },
        [`user[user_resumes_attributes][${i}][work_start_date_year]`]: {
            required: "勤務開始年月を選択してください",
        },
        [`user[user_resumes_attributes][${i}][work_start_date_month]`]: {
            required: "勤務開始年月を選択してください",
        },
        [`user[user_resumes_attributes][${i}][work_end_date_year]`]: {
            required: "勤務終了年月を選択してください",
        },
        [`user[user_resumes_attributes][${i}][work_end_date_month]`]: {
            required: "勤務終了年月を選択してください",
        },
        [`user[user_resumes_attributes][${i}][employment_id]`]: {
            required: "雇用形態を選択してください",
        },
        [`user[user_resumes_attributes][${i}][genre_id]`]: {
            required: "料理ジャンルを選択してください",
        },
        [`user[user_resumes_attributes][${i}][user_occupation_resumes_attributes][0][occupation_id]`]:
            {
                required: "仕事内容を選択してください",
            },
        [`user[user_resumes_attributes][${i}][job_description]`]: {
            required: "詳しい仕事内容を記入してください",
            minlength: "10文字以上入力してください",
            maxlength: "5000文字以下で入力してください",
        },
    };
    Object.assign(user_registration_messages, messages);
}

const user_registration_groups = {
    birthday: "user[birthday_year] user[birthday_month]",
};

for (let i = 0; i < 3; i++) {
    let groups = {
        [`work_date_${i}`]: `user[user_resumes_attributes][${i}][work_start_date_year] user[user_resumes_attributes][${i}][work_start_date_month] user[user_resumes_attributes][${i}][work_end_date_year] user[user_resumes_attributes][${i}][work_end_date_month]`,
    };
    Object.assign(user_registration_groups, groups);
}

$(function () {
    $(".js-validate-user-registrations-form form").each(function () {
        const $form = $(this);

        $form.validate({
            rules: user_registration_rules,
            messages: user_registration_messages,
            groups: user_registration_groups,
            errorElement: "div",
            maxErrorsPerField: 1,
            highlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.addClass("is-error");
            },
            unhighlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.removeClass("is-error");
            },
            errorPlacement: function (error, element) {
                const DEBUG = false;
                if (DEBUG) {
                    const errorMessage = error[0].innerText;
                    console.log(errorMessage);
                    console.log(error);
                    console.log(element);
                }
                const $input = $(element);
                error.appendTo(
                    $input
                        .parents(".js-input-area")
                        .find(".js-input-area__error")
                );
                $input.addClass("is-error");
            },
        });

        // step1
        const $situation = $form.find('input[name="user[situation]"]');
        if ($situation.length > 0) {
            $form.on("change", 'input[name="user[situation]"]', function () {
                if ($form.valid()) {
                    $form.find('button[type="submit"]').removeAttr("disabled");
                } else {
                    $form
                        .find('button[type="submit"]')
                        .attr("disabled", "disabled");
                }
            });
        }

        // step2
        $form.on("change", 'select[name="user[prefecture_id]"]', function () {
            const $this = $(this);
            console.log($this);
            $form.find('button[type="submit"]').attr("disabled", "disabled");
        });

        $form.on("change", 'select[name="user[city_id]"]', function () {
            const $this = $(this);
            console.log($this);
            if ($form.valid()) {
                $form.find('button[type="submit"]').removeAttr("disabled");
            } else {
                $form
                    .find('button[type="submit"]')
                    .attr("disabled", "disabled");
            }
        });

        //step3
        (function () {
            const validateStatus = {};
            const inputElements = [
                'input[name="user[first_name]"]',
                'input[name="user[last_name]"]',
                'input[name="user[first_name_kana]"]',
                'input[name="user[last_name_kana]"]',
                'select[name="user[birthday_year]"]',
                'select[name="user[birthday_month]"]',
                'select[name="user[sex]"]',
            ];
            inputElements.forEach(function (name) {
                validateStatus[name] = false;
                // console.log(validateStatus)
                $form.on("change", name, function () {
                    const $this = $(this);

                    // １つのinput要素が変更されたら、そのinput要素のバリデーション結果を取得
                    if ($this.valid()) {
                        validateStatus[name] = true;
                    }

                    const keys = Object.keys(validateStatus);
                    const statuses = keys.map(function (v) {
                        return validateStatus[v];
                    });

                    if ($this[0].className.includes("not-disable-submit-btn"))
                        return;

                    // 1つでもバリデーションをしていない or バリデーションエラーがある場合はボタンを無効化
                    if (
                        statuses.some(function (v) {
                            return v == false;
                        })
                    ) {
                        $form
                            .find('button[type="submit"]')
                            .attr("disabled", "disabled");
                        return;
                    }

                    // 全体のバリデーションチェックをして、エラーがなければボタンを有効化
                    if ($form.valid()) {
                        $form
                            .find('button[type="submit"]')
                            .removeAttr("disabled");
                    } else {
                        $form
                            .find('button[type="submit"]')
                            .attr("disabled", "disabled");
                    }
                });
            });
        })();

        //step4
        $form.on("input", 'input[name="user[tel]"]', function () {
            const $this = $(this);
            console.log($this);
            if ($form.valid()) {
                $form.find('button[type="submit"]').removeAttr("disabled");
            } else {
                $form
                    .find('button[type="submit"]')
                    .attr("disabled", "disabled");
            }
        });
        $form.on("input", 'input[name="user[line_id]"]', function () {
            const $this = $(this);
            console.log($this);
            if ($form.valid()) {
                $form.find('button[type="submit"]').removeAttr("disabled");
            } else {
                $form
                    .find('button[type="submit"]')
                    .attr("disabled", "disabled");
            }
        });

        //step5
        (function () {
            const validateStatus = {};
            const inputElements = [
                'input[name="user[email]"]',
                'input[name="user[password]"]',
            ];
            inputElements.forEach(function (name) {
                validateStatus[name] = false;
                $form.on("change input", name, function () {
                    const $this = $(this);
                    console.log($this);

                    // １つのinput要素が変更されたら、そのinput要素のバリデーション結果を取得
                    if ($this.valid()) {
                        validateStatus[name] = true;
                    }

                    const keys = Object.keys(validateStatus);
                    const statuses = keys.map(function (v) {
                        return validateStatus[v];
                    });

                    // 1つでもバリデーションをしていない or バリデーションエラーがある場合はボタンを無効化
                    if (
                        statuses.some(function (v) {
                            return v == false;
                        })
                    ) {
                        $(".js-stepform--step5-submit").attr(
                            "disabled",
                            "disabled"
                        );
                        return;
                    }

                    // 全体のバリデーションチェックをして、エラーがなければボタンを有効化
                    if ($form.valid()) {
                        $(".js-stepform--step5-submit").removeAttr("disabled");
                    } else {
                        $(".js-stepform--step5-submit").attr(
                            "disabled",
                            "disabled"
                        );
                    }
                });
            });
        })();

        //step6
        (function () {
            const validateStatus = { 0: {}, 1: {}, 2: {} };
            const inputElements0 = [
                'input[name="user[user_resumes_attributes][0][company_name]"]',
                'select[name="user[user_resumes_attributes][0][work_start_date_year]"]',
                'select[name="user[user_resumes_attributes][0][work_start_date_month]"]',
                'select[name="user[user_resumes_attributes][0][work_end_date_year]"]',
                'select[name="user[user_resumes_attributes][0][work_end_date_month]"]',
                'select[name="user[user_resumes_attributes][0][employment_id]"]',
                'select[name="user[user_resumes_attributes][0][genre_id]"]',
                'select[name="user[user_resumes_attributes][0][user_occupation_resumes_attributes][0][occupation_id]"]',
                'textarea[name="user[user_resumes_attributes][0][job_description]"]',
            ];
            const inputElements1 = [
                'input[name="user[user_resumes_attributes][1][company_name]"]',
                'select[name="user[user_resumes_attributes][1][work_start_date_year]"]',
                'select[name="user[user_resumes_attributes][1][work_start_date_month]"]',
                'select[name="user[user_resumes_attributes][1][work_end_date_year]"]',
                'select[name="user[user_resumes_attributes][1][work_end_date_month]"]',
                'select[name="user[user_resumes_attributes][1][employment_id]"]',
                'select[name="user[user_resumes_attributes][1][genre_id]"]',
                'select[name="user[user_resumes_attributes][1][user_occupation_resumes_attributes][0][occupation_id]"]',
                'textarea[name="user[user_resumes_attributes][1][job_description]"]',
            ];
            const inputElements2 = [
                'input[name="user[user_resumes_attributes][2][company_name]"]',
                'select[name="user[user_resumes_attributes][2][work_start_date_year]"]',
                'select[name="user[user_resumes_attributes][2][work_start_date_month]"]',
                'select[name="user[user_resumes_attributes][2][work_end_date_year]"]',
                'select[name="user[user_resumes_attributes][2][work_end_date_month]"]',
                'select[name="user[user_resumes_attributes][2][employment_id]"]',
                'select[name="user[user_resumes_attributes][2][genre_id]"]',
                'select[name="user[user_resumes_attributes][2][user_occupation_resumes_attributes][0][occupation_id]"]',
                'textarea[name="user[user_resumes_attributes][2][job_description]"]',
            ];

            const inputElements = inputElements0
                .concat(inputElements1)
                .concat(inputElements2);

            inputElements.forEach(function (name) {
                let index = 0;
                if (inputElements1.includes(name)) {
                    index = 1;
                } else if (inputElements2.includes(name)) {
                    index = 2;
                }

                if (
                    name ===
                        'select[name="user[user_resumes_attributes][0][work_end_date_year]"]' ||
                    name ===
                        'select[name="user[user_resumes_attributes][0][work_end_date_month]"]'
                ) {
                    // disabledの場合を考慮して事前にtrueを入れておく
                    validateStatus[index][name] = true;
                } else {
                    validateStatus[index][name] = false;
                }
                $form.on("change input", name, function () {
                    const $this = $(this);
                    console.log($this);

                    // １つのinput要素が変更されたら、そのinput要素のバリデーション結果を取得
                    if (
                        name.includes("work_start_date_year") ||
                        name.includes("work_start_date_month") ||
                        name.includes("work_end_date_year") ||
                        name.includes("work_end_date_month")
                    ) {
                        // 個別のvalidationではtrueを入れておく
                        validateStatus[index][name] = true;
                    } else {
                        validateStatus[index][name] = !!$this.valid();
                    }

                    const keys = Object.keys(validateStatus[index]);
                    const statuses = keys.map(function (v) {
                        return validateStatus[index][v];
                    });

                    console.log(statuses);

                    // 1つでもバリデーションをしていない or バリデーションエラーがある場合はボタンを無効化
                    if (
                        statuses.some(function (v) {
                            return v == false;
                        })
                    ) {
                        $(".js-stepform--step6-submit").attr(
                            "disabled",
                            "disabled"
                        );
                        return;
                    }

                    // 全体のバリデーションチェックをして、エラーがなければボタンを有効化
                    if ($form.valid()) {
                        $(".js-stepform--step6-submit").removeAttr("disabled");
                    } else {
                        $(".js-stepform--step6-submit").attr(
                            "disabled",
                            "disabled"
                        );
                    }
                });
            });
        })();

        //step7
        (function () {
            const validateStatus = {};
            const inputElements = [
                'input[name="user[agree_terms]"]',
                'input[name="user[agree_privacy]"]',
            ];
            inputElements.forEach(function (name) {
                validateStatus[name] = false;
                $form.on("change", name, function () {
                    const $this = $(this);
                    console.log($this);

                    // １つのinput要素が変更されたら、そのinput要素のバリデーション結果を取得
                    if ($this.is(":checked")) {
                        validateStatus[name] = true;
                    } else {
                        validateStatus[name] = false;
                    }

                    const keys = Object.keys(validateStatus);
                    const statuses = keys.map(function (v) {
                        return validateStatus[v];
                    });

                    console.log(statuses);

                    // 1つでもバリデーションをしていない or バリデーションエラーがある場合はボタンを無効化
                    if (
                        statuses.some(function (v) {
                            return v == false;
                        })
                    ) {
                        $(".js-stepform--step7-submit").attr(
                            "disabled",
                            "disabled"
                        );
                        return;
                    }

                    // 全体のバリデーションチェックをして、エラーがなければボタンを有効化
                    if ($form.valid()) {
                        $(".js-stepform--step7-submit").removeAttr("disabled");
                    } else {
                        $(".js-stepform--step7-submit").attr(
                            "disabled",
                            "disabled"
                        );
                    }
                });
            });
        })();
    });
});

const user_profile_rules = {
    "user[situation]": {
        required: true,
    },
    "user[prefecture_id]": {
        required: true,
    },
    "user[city_id]": {
        required: true,
    },
    "user[first_name]": {
        required: true,
    },
    "user[last_name]": {
        required: true,
    },
    "user[first_name_kana]": {
        required: true,
        regex: REGEX_KATAKANA,
    },
    "user[last_name_kana]": {
        required: true,
        regex: REGEX_KATAKANA,
    },
    "user[birthday_year]": {
        required: true,
        regex: REGEX_YAER,
    },
    "user[birthday_month]": {
        required: true,
        regex: REGEX_MONTH,
    },
    "user[sex]": {
        required: true,
    },
    "user[tel]": {
        required: true,
        regex: REGEX_TEL,
        minlength: 10,
        maxlength: 11,
    },
    "user[possible_to_relocation]": {
        required: true,
    },
    "user[english_work_experience]": {
        required: true,
    },
};

const user_profile_groups = {
    birthday: "user[birthday_year] user[birthday_month]",
    name: "user[last_name] user[first_name]",
    name_kana: "user[last_name_kana] user[first_name_kana]",
    area: "user[prefecture_id] user[city_id]",
};

const user_profile_messages = {
    "user[last_name]": {
        required: "氏名を入力してください",
    },
    "user[first_name]": {
        required: "氏名を入力してください",
    },
    "user[last_name_kana]": {
        required: "フリガナを入力してください",
        regex: "カタカナで入力してください",
    },
    "user[first_name_kana]": {
        required: "フリガナを入力してください",
        regex: "カタカナで入力してください",
    },
    "user[birthday_year]": {
        required: "選択してください",
    },
    "user[birthday_month]": {
        required: "選択してください",
    },
    "user[sex]": {
        required: "選択してください",
    },
    "user[prefecture_id]": {
        required: "選択してください",
    },
    "user[city_id]": {
        required: "選択してください",
    },
    "user[tel]": {
        required: "電話番号を入力してください",
        regex: "正しい電話番号を入力してください",
        minlength: "10桁以上で入力してください",
        maxlength: "11桁以下で入力してください",
    },
    "user[situation]": {
        required: "選択してください",
    },
    "user[possible_to_relocation]": {
        required: "選択してください",
    },
    "user[english_work_experience]": {
        required: "選択してください",
    },
};

$(function () {
    $(".js-validate-user-profile-form form").each(function () {
        $(this).validate({
            rules: user_profile_rules,
            messages: user_profile_messages,
            groups: user_profile_groups,
            errorElement: "div",
            maxErrorsPerField: 1,
            highlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.addClass("is-error");
            },
            unhighlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.removeClass("is-error");
            },
            errorPlacement: function (error, element) {
                const DEBUG = false;
                if (DEBUG) {
                    const errorMessage = error[0].innerText;
                    console.log(errorMessage);
                    console.log(error);
                    console.log(element);
                }
                const $input = $(element);
                error.appendTo(
                    $input
                        .parents(".js-input-area")
                        .find(".js-input-area__error")
                );
                $input.addClass("is-error");
            },
            invalidHandler,
        });
    });
});

const new_password_rules = {
    "account[email]": {
        required: true,
        email: true,
    },
};

const new_password_messages = {
    "account[email]": {
        required: "入力してください",
        email: "メールアドレスを入力してください",
    },
};

const new_password_registration_groups = {};

$(function () {
    $(".js-validate-password-form form").each(function () {
        $(this).validate({
            rules: new_password_rules,
            messages: new_password_messages,
            groups: new_password_registration_groups,
            errorElement: "div",
            maxErrorsPerField: 1,
            highlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.addClass("is-error");
            },
            unhighlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.removeClass("is-error");
            },
            errorPlacement: function (error, element) {
                const DEBUG = false;
                if (DEBUG) {
                    const errorMessage = error[0].innerText;
                    console.log(errorMessage);
                    console.log(error);
                    console.log(element);
                }
                const $input = $(element);
                error.appendTo(
                    $input
                        .parents(".js-input-area")
                        .find(".js-input-area__error")
                );
                $input.addClass("is-error");
            },
            invalidHandler,
        });
    });
});

const edit_password_rules = {
    "account[password]": {
        required: true,
        minlength: 8,
        maxlength: 32,
        regex: REGEX_PASSWORD,
    },
    "account[password_confirmation]": {
        required: true,
        minlength: 8,
        maxlength: 32,
        regex: REGEX_PASSWORD,
    },
};

const edit_password_messages = {
    "account[password]": {
        required: "入力してください",
        minlength: "8文字以上で入力してください",
        maxlength: "32文字以下で入力してください",
        regex: ERROR_REGEX_PASSWORD,
    },
    "account[password_confirmation]": {
        required: "入力してください",
        minlength: "8文字以上で入力してください",
        maxlength: "32文字以下で入力してください",
        regex: ERROR_REGEX_PASSWORD,
    },
};

const edit_password_registration_groups = {
    password: "account[password] account[password_confirmation]",
};

$(function () {
    $(".js-validate-edit-password-form form").each(function () {
        $(this).validate({
            rules: edit_password_rules,
            messages: edit_password_messages,
            groups: edit_password_registration_groups,
            errorElement: "div",
            maxErrorsPerField: 1,
            highlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.addClass("is-error");
            },
            unhighlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.removeClass("is-error");
            },
            errorPlacement: function (error, element) {
                const DEBUG = false;
                if (DEBUG) {
                    const errorMessage = error[0].innerText;
                    console.log(errorMessage);
                    console.log(error);
                    console.log(element);
                }
                const $input = $(element);
                error.appendTo(
                    $input
                        .parents(".js-input-area")
                        .find(".js-input-area__error")
                );
                $input.addClass("is-error");
            },
            invalidHandler,
        });
    });
});

const MAX_FILE_SIZE_5MB = 1024 * 1024 * 5; // 5MB

/* メッセージの入力のバリデーション */
$(function () {
    const $form = $("form.js-chat-form");
    $form.each(function () {
        $(this).validate({
            rules: chat_rules,
            messages: chat_messages,
            groups: chat_groups,
            errorElement: "div",
            maxErrorsPerField: 1,
            highlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.addClass("is-error");
            },
            unhighlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.removeClass("is-error");
            },
            errorPlacement: function (error, element) {
                const DEBUG = false;
                if (DEBUG) {
                    const errorMessage = error[0].innerText;
                    console.log(errorMessage);
                    console.log(error);
                    console.log(element);
                }
                const $input = $(element);
                error.appendTo($form.find(".js-input-area__error"));
                $input.addClass("is-error");
            },
        });
    });
});

$.validator.addMethod(
    "includeMailAddress",
    function (value, element) {
        const emailReg =
            /[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}/;
        return this.optional(element) || !emailReg.test(value);
    },
    "メールアドレスは入力できません。"
);
$.validator.addMethod(
    "includePhoneNumber",
    function (value, element) {
        const telRegWithoutHyphen = /0\d{9,10}/;
        const telRegWithHyphen = /0\d{1,3}-\d{2,4}-\d{3,4}/;
        return (
            this.optional(element) ||
            !(telRegWithoutHyphen.test(value) || telRegWithHyphen.test(value))
        );
    },
    "電話番号は入力できません。"
);

$.validator.addMethod(
    "maxFileSize",
    function (value, element, fileSize) {
        return (
            this.optional(element) ||
            !element.files[0] ||
            element.files[0].size <= fileSize
        );
    },
    "ファイルサイズが大きすぎます。"
);

const chat_rules = {
    "application_message[content]": {
        includePhoneNumber: true,
        includeMailAddress: true,
    },
    "application_message[file]": {
        maxFileSize: MAX_FILE_SIZE_5MB,
    },
};

const chat_messages = {
    "application_message[file]": {
        maxFileSize: `${MAX_FILE_SIZE_5MB / 1024 / 1024}MBより大きいファイルサイズはアップロードできません。`,
    },
};

const chat_groups = {
    "application_message[content]":
        "application_message[file] application_message[content]",
    "application_message[file]":
        "application_message[content] application_message[file]",
};

/* 設定画面のメールアドレスのvalidation */
$(function () {
    const $emailInput = $(".js-update-email");
    const ENDPOINT_URL = "/api/v1/users/check_if_registered";
    $emailInput.on("keyup change", function () {
        const newEmail = $(this).val();
        const param = {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ user: { email: newEmail } }),
        };
        fetch(ENDPOINT_URL, param)
            .then(res => res.json())
            .then(json => {
                if (!json) {
                    $(".js-email-update__error").text(
                        "このメールアドレスはすでに登録されています"
                    );
                    const $updateButton = $(".js-email-update-btn");
                    $updateButton.attr("disabled", "disabled");
                    $updateButton.addClass("c-btn-1__disabled");
                } else {
                    $(".js-email-update__error").text("");
                    const $updateButton = $(".js-email-update-btn");
                    $updateButton.removeAttr("disabled");
                    $updateButton.removeClass("c-btn-1__disabled");
                }
            })
            .catch(error => {
                console.log(error);
            });
    });
});

const user_reset_password_rules = {
    "account[current_password]": {
        required: true,
        minlength: 8,
        regex: REGEX_PASSWORD,
    },
    "account[password]": {
        required: true,
        minlength: 8,
        regex: REGEX_PASSWORD,
    },
    "account[password_confirmation]": {
        required: true,
        minlength: 8,
        regex: REGEX_PASSWORD,
    },
};

const user_reset_password_messages = {
    "account[current_password]": {
        required: "入力してください",
        minlength: "8文字以上で入力してください",
        maxlength: "32文字以下で入力してください",
        regex: ERROR_REGEX_PASSWORD,
    },
    "account[password]": {
        required: "入力してください",
        minlength: "8文字以上で入力してください",
        maxlength: "32文字以下で入力してください",
        regex: ERROR_REGEX_PASSWORD,
    },
    "account[password_confirmation]": {
        required: "入力してください",
        minlength: "8文字以上で入力してください",
        maxlength: "32文字以下で入力してください",
        regex: ERROR_REGEX_PASSWORD,
    },
};

const user_reset_password_groups = {};

/* 設定画面のパスワードのvalidation */
$(function () {
    $(".js-validate-user-reset-password-form form").each(function () {
        const $userResetPasswordForm = $(this);
        $userResetPasswordForm.validate({
            rules: user_reset_password_rules,
            messages: user_reset_password_messages,
            groups: user_reset_password_groups,
            errorElement: "div",
            maxErrorsPerField: 1,
            highlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.addClass("is-error");
            },
            unhighlight: function (element, errorClass, validClass) {
                const $input = $(element);
                $input.removeClass("is-error");
            },
            errorPlacement: function (error, element) {
                const DEBUG = false;
                if (DEBUG) {
                    const errorMessage = error[0].innerText;
                    console.log(errorMessage);
                    console.log(error);
                    console.log(element);
                }
                const $input = $(element);
                error.appendTo(
                    $input
                        .parents(".js-input-area")
                        .find(".js-input-area__error")
                );
                $input.addClass("is-error");
            },
            invalidHandler,
        });
        (function () {
            const validateStatus = {};
            const inputElements = [
                'input[name="account[current_password]"]',
                'input[name="account[password]"]',
                'input[name="account[password_confirmation]"]',
            ];
            inputElements.forEach(function (name) {
                validateStatus[name] = false;
                $userResetPasswordForm.on("change input", name, function () {
                    const $this = $(this);

                    // １つのinput要素が変更されたら、そのinput要素のバリデーション結果を取得
                    if ($this.valid()) {
                        validateStatus[name] = true;
                    }

                    const keys = Object.keys(validateStatus);
                    const statuses = keys.map(function (v) {
                        return validateStatus[v];
                    });

                    // 1つでもバリデーションをしていない or バリデーションエラーがある場合はボタンを無効化
                    if (
                        statuses.some(function (v) {
                            return v === false;
                        })
                    ) {
                        $(".js-user-reset-password-submit").attr(
                            "disabled",
                            "disabled"
                        );
                        return;
                    }

                    // 全体のバリデーションチェックをして、エラーがなければボタンを有効化
                    if ($userResetPasswordForm.valid()) {
                        const $updateButton = $(
                            ".js-user-reset-password-submit"
                        );
                        $updateButton.removeAttr("disabled");
                        $updateButton.removeClass("c-btn-1__disabled");
                    } else {
                        const $updateButton = $(
                            ".js-user-reset-password-submit"
                        );
                        $updateButton.attr("disabled", "disabled");
                        $updateButton.addClass("c-btn-1__disabled");
                    }
                });
            });
        })();
    });
});

/* メッセージの入力のバリデーション */
$(function () {
    const MAX_FILE_SIZE_5MB = 1024 * 1024 * 5; // 5MB

    $form = $(".js-agent-chat-form");
    $form.on("change", 'input[name="agent_application[file]"]', function (e) {
        const files = e.target.files;
        if (files.length && files[0].size > MAX_FILE_SIZE_5MB) {
            $form
                .find('input[type="submit"],button[type="submit"]')
                .attr("disabled", true)
                .addClass("is-disabled");
            $form
                .find(".js-input-area__error")
                .text(
                    `${MAX_FILE_SIZE_5MB / 1024 / 1024}MBより大きいファイルサイズはアップロードできません。`
                );
        } else {
            $form
                .find('input[type="submit"],button[type="submit"]')
                .removeAttr("disabled")
                .removeClass("is-disabled");
            $form.find(".js-input-area__error").text("");
        }
    });
});
