<?php

if (!defined('ABSPATH')) {
    exit;
}

/*----------------------------------------
メールフォーム：共通保存チェック
----------------------------------------*/
function immf_can_save($post_id) {

    if (
        defined('DOING_AUTOSAVE') &&
        DOING_AUTOSAVE
    ) {
        return false;
    }

    if (
        get_post_type($post_id) !== 'im_mail_form'
    ) {
        return false;
    }

    if (
        !current_user_can('edit_post', $post_id)
    ) {
        return false;
    }

    return true;
}


/*----------------------------------------
メールフォーム：複数メールアドレスの整形
----------------------------------------*/
function immf_sanitize_email_list($value) {

    $addresses = explode(
        ',',
        wp_unslash($value)
    );

    $addresses = array_map(
        static function ($address) {
            return sanitize_email(
                trim($address)
            );
        },
        $addresses
    );

    $addresses = array_filter($addresses);

    return implode(', ', $addresses);
}

/*----------------------------------------
複数メールアドレスの入力内容を検証
----------------------------------------*/
function immf_has_invalid_email_list($value) {

    $addresses = explode(
        ',',
        wp_unslash($value)
    );

    foreach ($addresses as $address) {

        $address = trim($address);

        if ($address === '') {
            continue;
        }

        if (!is_email($address)) {
            return true;
        }
    }

    return false;
}


/*----------------------------------------
フォームIDの重複を確認
----------------------------------------*/
function immf_id_exists(
    $form_id,
    $post_id
) {

    if ($form_id === '') {
        return false;
    }

    $form_ids = get_posts([
        'post_type'      => 'im_mail_form',
        'post_status'    => 'any',
        'posts_per_page' => 1,
        'post__not_in'   => [$post_id],
        'fields'         => 'ids',
        'meta_key'       => 'immf_id',
        'meta_value'     => $form_id,
        'no_found_rows'  => true,
    ]);

    return !empty($form_ids);

}


/*----------------------------------------
メールフォーム：基本設定保存
----------------------------------------*/
function immf_save_contact_form_settings($post_id) {

    if (!immf_can_save($post_id)) {
        return;
    }

    if (
        !isset($_POST['im_mail_form_settings_nonce']) ||
        !wp_verify_nonce(
            sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_settings_nonce']
                )
            ),
            'immf_save_contact_form_settings'
        )
    ) {
        return;
    }

    $form_id_raw = isset(
        $_POST['im_mail_form_id']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_id']
            )
        )
        : '';

    $form_id = sanitize_key(
        $form_id_raw
    );

    if ($form_id === '') {

        set_transient(
            'immf_settings_error_'
                . get_current_user_id()
                . '_'
                . $post_id,
            __(
                'Please enter a Form ID.',
                'im-mail-form'
            ),
            60
        );

        return;
    }

    if (
        preg_match(
            '/^[a-z0-9_-]+$/',
            $form_id_raw
        ) !== 1
    ) {

        set_transient(
            'immf_settings_error_'
                . get_current_user_id()
                . '_'
                . $post_id,
            __(
                'The Form ID may contain only lowercase letters, numbers, hyphens, and underscores.',
                'im-mail-form'
            ),
            60
        );

        return;
    }

    if (
        immf_id_exists(
            $form_id,
            $post_id
        )
    ) {

        set_transient(
            'immf_settings_error_'
                . get_current_user_id()
                . '_'
                . $post_id,
            __(
                'This Form ID is already in use.',
                'im-mail-form'
            ),
            60
        );

        return;
    }

    update_post_meta(
        $post_id,
        'immf_id',
        $form_id
    );

    $use_confirm = isset(
        $_POST['im_mail_form_use_confirm']
    ) ? '1' : '0';

    update_post_meta(
        $post_id,
        'immf_use_confirm',
        $use_confirm
    );

    $confirm_button_label = isset(
        $_POST['im_mail_form_confirm_button_label']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_confirm_button_label']
            )
        )
        : get_post_meta(
            $post_id,
            'immf_confirm_button_label',
            true
        );

    if ($confirm_button_label === '') {
        $confirm_button_label = __(
            'Confirm',
            'im-mail-form'
        );
    }

    update_post_meta(
        $post_id,
        'immf_confirm_button_label',
        $confirm_button_label
    );

    $back_button_label = isset(
        $_POST['im_mail_form_back_button_label']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_back_button_label']
            )
        )
        : get_post_meta(
            $post_id,
            'immf_back_button_label',
            true
        );

    if ($back_button_label === '') {
        $back_button_label = __(
            'Edit',
            'im-mail-form'
        );
    }

    update_post_meta(
        $post_id,
        'immf_back_button_label',
        $back_button_label
    );

    $submit_button_label = isset(
        $_POST['im_mail_form_submit_button_label']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_submit_button_label']
            )
        )
        : '';

    if ($submit_button_label === '') {
        $submit_button_label = __(
            'Submit',
            'im-mail-form'
        );
    }

    update_post_meta(
        $post_id,
        'immf_submit_button_label',
        $submit_button_label
    );

    $required_label = isset(
        $_POST['im_mail_form_required_label']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_required_label']
            )
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_required_label',
        $required_label
    );
}

add_action(
    'save_post_im_mail_form',
    'immf_save_contact_form_settings'
);


/*----------------------------------------
フォーム項目の設定内容を検証
----------------------------------------*/
function immf_validate_contact_form_fields_settings(
    $submitted_fields,
    &$invalid_fields = []
) {

    $errors = [];
    $invalid_fields = [];
    $used_names = [];
    $field_number = 0;

    if (!is_array($submitted_fields)) {
        return $errors;
    }

    foreach (
        $submitted_fields
        as $field_index => $field
    ) {

        $field_number++;

        if (!is_array($field)) {
            $errors[] = sprintf(
                /* translators: %d: Form field number. */
                __(
                    'The settings for form field %d are invalid.',
                    'im-mail-form'
                ),
                $field_number
            );

            continue;
        }

        $label = sanitize_text_field(
            $field['label'] ?? ''
        );

        $field_label = $label !== ''
            ? sprintf(
                /* translators: %s: Form field label. */
                __('“%s”', 'im-mail-form'),
                $label
            )
            : sprintf(
                /* translators: %d: Form field number. */
                __('Form field %d', 'im-mail-form'),
                $field_number
            );

        $name_raw = trim(
            $field['name'] ?? ''
        );

        $type = sanitize_key(
            $field['type'] ?? ''
        );

        /*----------------------------------------
        HTMLブロックはlabel・nameを要求せず、
        HTML入力欄のみ検証する
        ----------------------------------------*/
        if ($type === 'html') {

            $html_content = trim(
                $field['html_content'] ?? ''
            );

            if ($html_content === '') {

                $invalid_fields[$field_index][] =
                    'html_content';

                $errors[] = sprintf(
                    /* translators: %d: Form field number. */
                    __(
                        'Please enter HTML content for form field %d.',
                        'im-mail-form'
                    ),
                    $field_number
                );
            }

            continue;
        }

        $min_length = isset(
            $field['min_length']
        ) && $field['min_length'] !== ''
            ? absint($field['min_length'])
            : null;

        $max_length = isset(
            $field['max_length']
        ) && $field['max_length'] !== ''
            ? absint($field['max_length'])
            : null;

        if (
            $min_length !== null &&
            $max_length !== null &&
            $min_length > $max_length
        ) {
            $invalid_fields[$field_index][] =
                'max_length';

            $errors[] = sprintf(
                /* translators: %s: Form field label or field number. */
                __(
                    'The maximum length for %s must be greater than or equal to the minimum length.',
                    'im-mail-form'
                ),
                $field_label
            );
        }

        if ($label === '') {

            $invalid_fields[$field_index][] =
                'label';

            $errors[] = sprintf(
                /* translators: %d: Form field number. */
                __(
                    'Please enter a label for form field %d.',
                    'im-mail-form'
                ),
                $field_number
            );
        }

        if ($name_raw === '') {

            $invalid_fields[$field_index][] =
                'name';

            $errors[] = sprintf(
                /* translators: %s: Form field label or field number. */
                __(
                    'Please enter a field name for %s.',
                    'im-mail-form'
                ),
                $field_label
            );

        } elseif (
            preg_match(
                '/^[a-z0-9_-]+$/',
                $name_raw
            ) !== 1
        ) {

            $invalid_fields[$field_index][] =
                'name';

            $errors[] = sprintf(
                /* translators: %s: Form field label or field number. */
                __(
                    'The field name for %s may contain only lowercase letters, numbers, hyphens, and underscores.',
                    'im-mail-form'
                ),
                $field_label
            );

        } elseif (
            in_array(
                $name_raw,
                immf_reserved_field_names(),
                true
            )
        ) {

            $invalid_fields[$field_index][] =
                'name';

            $errors[] = sprintf(
                /* translators: %s: Reserved field name. */
                __(
                    'The field name “%s” is reserved by the system and cannot be used.',
                    'im-mail-form'
                ),
                $name_raw
            );

        } elseif (
            isset(
                $used_names[$name_raw]
            )
        ) {

            $invalid_fields[$field_index][] =
                'name';

            $invalid_fields[
                $used_names[$name_raw]
            ][] = 'name';

            $errors[] = sprintf(
                /* translators: %s: Duplicated field name. */
                __(
                    'The field name “%s” is duplicated.',
                    'im-mail-form'
                ),
                $name_raw
            );

        } else {

            $used_names[$name_raw] =
                $field_index;
        }

        if (
            in_array(
                $type,
                [
                    'select',
                    'radio',
                    'checkbox',
                ],
                true
            )
        ) {

            $options = preg_split(
                '/\r\n|\r|\n/',
                sanitize_textarea_field(
                    $field['options'] ?? ''
                )
            );

            $options = array_filter(
                array_map(
                    'trim',
                    $options
                )
            );

            if (empty($options)) {
                $invalid_fields[$field_index][] =
                    'options';

                $errors[] = sprintf(
                    /* translators: %s: Form field label or field number. */
                    __(
                        'Please enter at least one option for %s.',
                        'im-mail-form'
                    ),
                    $field_label
                );
            }
        }
    }

    return $errors;

}


/*----------------------------------------
メールフォーム：入力保持用にフォーム項目をサニタイズ
----------------------------------------*/
function immf_sanitize_fields_for_display($fields) {

    if (!is_array($fields)) {
        return [];
    }

    $sanitized_fields = [];

    foreach ($fields as $field) {

        if (!is_array($field)) {
            continue;
        }

        $type = sanitize_key(
            $field['type'] ?? ''
        );

        $sanitized_fields[] = [
            'label' => sanitize_text_field(
                $field['label'] ?? ''
            ),

            'description' => sanitize_textarea_field(
                $field['description'] ?? ''
            ),

            /*
            * 書式エラーをユーザーが確認・修正できるよう、
            * ここではsanitize_key()を使わず入力文字を保持する。
            */
            'name' => sanitize_text_field(
                $field['name'] ?? ''
            ),

            'placeholder' => sanitize_text_field(
                $field['placeholder'] ?? ''
            ),

            'type' => $type,

            'validation' => sanitize_key(
                $field['validation'] ?? ''
            ),

            'required' => isset(
                $field['required']
            ) ? '1' : '0',

            'min_length' => isset(
                $field['min_length']
            ) && $field['min_length'] !== ''
                ? absint($field['min_length'])
                : '',

            'max_length' => isset(
                $field['max_length']
            ) && $field['max_length'] !== ''
                ? absint($field['max_length'])
                : '',

            'hidden_value' => sanitize_text_field(
                $field['hidden_value'] ?? ''
            ),

            'options' => sanitize_textarea_field(
                $field['options'] ?? ''
            ),

            'max_file_size' => isset(
                $field['max_file_size']
            ) && $field['max_file_size'] !== ''
                ? absint($field['max_file_size'])
                : '',

            'allowed_file_types' => isset(
                $field['allowed_file_types']
            ) && is_array(
                $field['allowed_file_types']
            )
                ? array_map(
                    'sanitize_key',
                    $field['allowed_file_types']
                )
                : [],

            'html_content' => $type === 'html'
                ? wp_kses_post(
                    $field['html_content'] ?? ''
                )
                : '',
        ];

    }

    return $sanitized_fields;

}


/*----------------------------------------
メールフォーム：フォーム項目保存
----------------------------------------*/
function immf_save_contact_form_fields($post_id) {

    if (!immf_can_save($post_id)) {
        return;
    }

    if (
        !isset($_POST['im_mail_form_fields_nonce']) ||
        !wp_verify_nonce(
            sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_fields_nonce']
                )
            ),
            'immf_save_contact_form_fields'
        )
    ) {
        return;
    }

    $submitted_fields = isset(
        $_POST['im_mail_form_fields']
    )
        ? wp_unslash(
            // Field settings are validated and sanitized individually below.
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $_POST['im_mail_form_fields']
        )
        : [];

    $invalid_fields = [];

    $field_errors =
        immf_validate_contact_form_fields_settings(
            $submitted_fields,
            $invalid_fields
        );

    if (!empty($field_errors)) {

        set_transient(
            'immf_fields_errors_'
                . get_current_user_id()
                . '_'
                . $post_id,
            $field_errors,
            60
        );

        set_transient(
            'immf_invalid_fields_'
                . get_current_user_id()
                . '_'
                . $post_id,
            $invalid_fields,
            60
        );

        set_transient(
            'immf_save_error_'
                . get_current_user_id()
                . '_'
                . $post_id,
            true,
            60
        );

        set_transient(
            'immf_fields_input_'
                . get_current_user_id()
                . '_'
                . $post_id,
            immf_sanitize_fields_for_display(
                $submitted_fields
            ),
            60
        );

        return;
    }

    $fields = [];
    $used_names = [];

    if (is_array($submitted_fields)) {

        foreach ($submitted_fields as $field) {

            if (!is_array($field)) {
                continue;
            }

            /*----------------------------------------
            フォーム種類を取得
            ----------------------------------------*/
            $type = sanitize_key(
                $field['type'] ?? 'text'
            );

            /*----------------------------------------
            HTMLブロックはlabel・nameを持たず、
            HTML入力欄のみ保存する
            ----------------------------------------*/
            if ($type === 'html') {

                $html_content = wp_kses_post(
                    $field['html_content'] ?? ''
                );

                if ($html_content === '') {
                    continue;
                }

                $fields[] = [
                    'label'              => '',
                    'description'        => '',
                    'placeholder'        => '',
                    'name'               => '',
                    'type'               => 'html',
                    'validation'         => '',
                    'required'           => '0',
                    'min_length'         => '',
                    'max_length'         => '',
                    'hidden_value'       => '',
                    'options'            => '',
                    'max_file_size'      => '',
                    'allowed_file_types' => [],
                    'html_content'       => $html_content,
                ];

                continue;
            }

            $label = sanitize_text_field(
                $field['label'] ?? ''
            );

            $name = sanitize_key(
                $field['name'] ?? ''
            );

            if (
                $label === '' ||
                $name === ''
            ) {
                continue;
            }

            if (
                in_array(
                    $name,
                    $used_names,
                    true
                )
            ) {
                continue;
            }

            $used_names[] = $name;

            $allowed_types = [
                'text',
                'email',
                'tel',
                'textarea',
                'select',
                'radio',
                'checkbox',
                'date',
                'file',
                'hidden',
            ];

            if (
                !in_array(
                    $type,
                    $allowed_types,
                    true
                )
            ) {
                continue;
            }

            /*----------------------------------------
            フォーム種類に応じたバリデーションを取得
            ----------------------------------------*/
            $validation_by_type = [
                'email' => 'email',
                'tel' => 'tel',
                'date' => 'date',
                'file' => 'file',
                'select' => '',
                'radio' => '',
                'checkbox' => '',
                'hidden' => '',
            ];

            $validation = $validation_by_type[$type]
                ?? sanitize_key(
                    $field['validation'] ?? ''
                );

            /*----------------------------------------
            選択可能なバリデーションを制限
            ----------------------------------------*/
            $allowed_validations = [
                'text' => [
                    '',
                    'number',
                    'alphanumeric',
                ],
                'textarea' => [
                    '',
                ],
            ];

            if (
                isset($allowed_validations[$type]) &&
                !in_array(
                    $validation,
                    $allowed_validations[$type],
                    true
                )
            ) {
                $validation = '';
            }

            /*----------------------------------------
            許可するファイル形式を取得
            ----------------------------------------*/
            $allowed_file_type_keys = [
                'jpeg',
                'png',
                'webp',
                'pdf',
            ];

            $allowed_file_types = isset(
                $field['allowed_file_types']
            ) && is_array(
                $field['allowed_file_types']
            )
                ? array_values(
                    array_intersect(
                        $allowed_file_type_keys,
                        array_map(
                            'sanitize_key',
                            $field['allowed_file_types']
                        )
                    )
                )
                : [];

            /*----------------------------------------
            最大ファイルサイズを取得
            ----------------------------------------*/
            $wordpress_max_file_size = max(
                1,
                (int) floor(
                    wp_max_upload_size() / MB_IN_BYTES
                )
            );

            $max_file_size = isset(
                $field['max_file_size']
            ) && $field['max_file_size'] !== ''
                ? max(
                    1,
                    min(
                        absint($field['max_file_size']),
                        $wordpress_max_file_size
                    )
                )
                : '';


            /*----------------------------------------
            最小・最大文字数を取得
            ----------------------------------------*/
            $min_length = isset(
                $field['min_length']
            ) && $field['min_length'] !== ''
                ? absint($field['min_length'])
                : '';

            $max_length = isset(
                $field['max_length']
            ) && $field['max_length'] !== ''
                ? absint($field['max_length'])
                : '';

            if (
                $min_length !== '' &&
                $max_length !== '' &&
                $min_length > $max_length
            ) {
                [
                    $min_length,
                    $max_length,
                ] = [
                    $max_length,
                    $min_length,
                ];
            }

            /*----------------------------------------
            保存するフォーム項目
            ----------------------------------------*/
            $fields[] = [
                'label' => $label,

                'description' => sanitize_textarea_field(
                    $field['description'] ?? ''
                ),

                'placeholder' => sanitize_text_field(
                    $field['placeholder'] ?? ''
                ),

                'name' => $name,

                'type' => $type,

                'validation' => $validation,

                'required' => isset(
                    $field['required']
                ) ? '1' : '0',

                'min_length' => $min_length,

                'max_length' => $max_length,

                'hidden_value' => sanitize_text_field(
                    $field['hidden_value'] ?? ''
                ),

                'options' => sanitize_textarea_field(
                    $field['options'] ?? ''
                ),

                'max_file_size' => $max_file_size,

                'allowed_file_types' => $allowed_file_types,

                'html_content' => '',
            ];
        }
    }

    update_post_meta(
        $post_id,
        'immf_fields',
        $fields
    );
}

add_action(
    'save_post_im_mail_form',
    'immf_save_contact_form_fields'
);


/*----------------------------------------
メールフォーム：自動返信メール設定保存
----------------------------------------*/
function immf_save_contact_form_reply_mail($post_id) {

    // 保存可能な投稿か確認
    if (!immf_can_save($post_id)) {
        return;
    }

    // nonce確認
    if (
        !isset($_POST['im_mail_form_settings_nonce']) ||
        !wp_verify_nonce(
            sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_settings_nonce']
                )
            ),
            'immf_save_contact_form_settings'
        )
    ) {
        return;
    }


    /*----------------------------------------
    自動返信メールの使用設定
    ----------------------------------------*/
    $use_reply = isset(
        $_POST['im_mail_form_use_reply']
    ) ? '1' : '0';

    $submitted_fields = isset(
        $_POST['im_mail_form_fields']
    ) && is_array(
        $_POST['im_mail_form_fields']
    )
        ? wp_unslash(
            // Only field types and validation settings are sanitized and inspected below.
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $_POST['im_mail_form_fields']
        )
        : [];

    $has_email_field = false;
    $email_field_names = [];

    foreach ($submitted_fields as $field) {

        if (!is_array($field)) {
            continue;
        }

        $field_type = sanitize_key(
            $field['type'] ?? ''
        );

        $field_validation = sanitize_key(
            $field['validation'] ?? ''
        );

        if (
            $field_type === 'email' ||
            $field_validation === 'email'
        ) {
            $has_email_field = true;

            $field_name = sanitize_key(
                $field['name'] ?? ''
            );

            if ($field_name !== '') {
                $email_field_names[] = $field_name;
            }
        }
    }

    if (
        $use_reply === '1' &&
        !$has_email_field
    ) {
        $use_reply = '0';

        set_transient(
            'immf_reply_error_'
                . get_current_user_id(),
            __(
                'To use the auto-reply email, add at least one email address field.',
                'im-mail-form'
            ),
            60
        );
    }

    update_post_meta(
        $post_id,
        'immf_use_reply',
        $use_reply
    );

    if (
        !isset(
            $_POST['im_mail_form_use_reply']
        )
    ) {
        return;
    }

    /*----------------------------------------
    自動返信先フィールド
    ----------------------------------------*/
    $reply_to_field = isset(
        $_POST['im_mail_form_reply_to_field']
    )
        ? sanitize_key(
            wp_unslash(
                $_POST['im_mail_form_reply_to_field']
            )
        )
        : '';

    // 実在するメール形式のフィールド名か確認
    if (
        $reply_to_field !== '' &&
        !in_array(
            $reply_to_field,
            $email_field_names,
            true
        )
    ) {
        $reply_to_field = '';
    }

    update_post_meta(
        $post_id,
        'immf_reply_to_field',
        $reply_to_field
    );

    /*----------------------------------------
    送信元名
    ----------------------------------------*/
    $reply_from_name = isset(
        $_POST['im_mail_form_reply_from_name']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_reply_from_name']
            )
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_reply_from_name',
        $reply_from_name
    );


    /*----------------------------------------
    送信元アドレス
    ----------------------------------------*/
    $reply_from_raw = isset(
        $_POST['im_mail_form_reply_from']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_reply_from']
            )
        )
        : '';

    $reply_from = sanitize_email(
        $reply_from_raw
    );

    update_post_meta(
        $post_id,
        'immf_reply_from',
        $reply_from
    );


    /*----------------------------------------
    BCC
    ----------------------------------------*/
    $reply_bcc = isset(
        $_POST['im_mail_form_reply_bcc']
    )
        ? immf_sanitize_email_list(
            // Unslashed and sanitized by immf_sanitize_email_list().
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $_POST['im_mail_form_reply_bcc']
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_reply_bcc',
        $reply_bcc
    );


    /*----------------------------------------
    件名
    ----------------------------------------*/
    $reply_subject = isset(
        $_POST['im_mail_form_reply_subject']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_reply_subject']
            )
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_reply_subject',
        $reply_subject
    );


    /*----------------------------------------
    メール本文
    ----------------------------------------*/
    $reply_body = isset(
        $_POST['im_mail_form_reply_body']
    )
        ? sanitize_textarea_field(
            wp_unslash(
                $_POST['im_mail_form_reply_body']
            )
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_reply_body',
        $reply_body
    );
}

add_action(
    'save_post_im_mail_form',
    'immf_save_contact_form_reply_mail'
);


/*----------------------------------------
メールフォーム：管理者向けメール設定保存
----------------------------------------*/
function immf_save_contact_form_admin_mail($post_id) {

    // 保存可能な投稿か確認
    if (!immf_can_save($post_id)) {
        return;
    }

    // nonce確認
    if (
        !isset($_POST['im_mail_form_settings_nonce']) ||
        !wp_verify_nonce(
            sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_settings_nonce']
                )
            ),
            'immf_save_contact_form_settings'
        )
    ) {
        return;
    }


    /*----------------------------------------
    送信先アドレス
    ----------------------------------------*/
    $admin_to_raw = isset(
        $_POST['im_mail_form_admin_to']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_admin_to']
            )
        )
        : '';

    $admin_to = sanitize_email(
        $admin_to_raw
    );

    update_post_meta(
        $post_id,
        'immf_admin_to',
        $admin_to
    );


    /*----------------------------------------
    送信元名
    ----------------------------------------*/
    $admin_from_name = isset(
        $_POST['im_mail_form_admin_from_name']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_admin_from_name']
            )
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_admin_from_name',
        $admin_from_name
    );


    /*----------------------------------------
    送信元アドレス
    ----------------------------------------*/
    $admin_from = isset(
        $_POST['im_mail_form_admin_from']
    )
        ? sanitize_email(
            wp_unslash(
                $_POST['im_mail_form_admin_from']
            )
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_admin_from',
        $admin_from
    );


    /*----------------------------------------
    CC
    ----------------------------------------*/
    $admin_cc = isset(
        $_POST['im_mail_form_admin_cc']
    )
        ? immf_sanitize_email_list(
            // Unslashed and sanitized by immf_sanitize_email_list().
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $_POST['im_mail_form_admin_cc']
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_admin_cc',
        $admin_cc
    );


    /*----------------------------------------
    BCC
    ----------------------------------------*/
    $admin_bcc = isset(
        $_POST['im_mail_form_admin_bcc']
    )
        ? immf_sanitize_email_list(
            // Unslashed and sanitized by immf_sanitize_email_list().
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $_POST['im_mail_form_admin_bcc']
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_admin_bcc',
        $admin_bcc
    );


    /*----------------------------------------
    件名
    ----------------------------------------*/
    $admin_subject = isset(
        $_POST['im_mail_form_admin_subject']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_admin_subject']
            )
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_admin_subject',
        $admin_subject
    );


    /*----------------------------------------
    メール本文
    ----------------------------------------*/
    $admin_body = isset(
        $_POST['im_mail_form_admin_body']
    )
        ? sanitize_textarea_field(
            wp_unslash(
                $_POST['im_mail_form_admin_body']
            )
        )
        : '';

    update_post_meta(
        $post_id,
        'immf_admin_body',
        $admin_body
    );

    /*----------------------------------------
    完了画面設定
    ----------------------------------------*/
    $redirect_enabled = isset(
        $_POST['im_mail_form_redirect_enabled']
    ) ? '1' : '0';

    update_post_meta(
        $post_id,
        'immf_redirect_enabled',
        $redirect_enabled
    );

    if (
        isset(
            $_POST['im_mail_form_redirect_url']
        )
    ) {

        $redirect_url = esc_url_raw(
            wp_unslash(
                $_POST['im_mail_form_redirect_url']
            )
        );

        update_post_meta(
            $post_id,
            'immf_redirect_url',
            $redirect_url
        );
    }

    if (
        isset(
            $_POST['im_mail_form_complete_message']
        )
    ) {

        $complete_message = wp_kses_post(
            wp_unslash(
                $_POST['im_mail_form_complete_message']
            )
        );

        update_post_meta(
            $post_id,
            'immf_complete_message',
            $complete_message
        );
    }
}

add_action(
    'save_post_im_mail_form',
    'immf_save_contact_form_admin_mail'
);


/*----------------------------------------
メール設定の入力内容を検証
----------------------------------------*/

// Nonce verification is performed by immf_validate_contact_form_mail_settings_on_save().
// phpcs:disable WordPress.Security.NonceVerification.Missing
function immf_validate_contact_form_mail_settings(
    $post_id,
    &$invalid_fields = []
) {

    $errors = [];
    $invalid_fields = [];

    /*----------------------------------------
    自動返信メール
    ----------------------------------------*/
    $use_reply = isset(
        $_POST['im_mail_form_use_reply']
    );

    if ($use_reply) {

        $reply_from_name = isset(
            $_POST['im_mail_form_reply_from_name']
        )
            ? sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_reply_from_name']
                )
            )
            : '';

        $reply_from_raw = isset(
            $_POST['im_mail_form_reply_from']
        )
            ? sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_reply_from']
                )
            )
            : '';

        $reply_from = sanitize_email(
            $reply_from_raw
        );

        $reply_bcc_raw = isset(
            $_POST['im_mail_form_reply_bcc']
        )
            ? sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_reply_bcc']
                )
            )
            : '';

        $reply_subject = isset(
            $_POST['im_mail_form_reply_subject']
        )
            ? sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_reply_subject']
                )
            )
            : '';

        $reply_body = isset(
            $_POST['im_mail_form_reply_body']
        )
            ? sanitize_textarea_field(
                wp_unslash(
                    $_POST['im_mail_form_reply_body']
                )
            )
            : '';

        if ($reply_from_name === '') {

            $invalid_fields[] =
                'im_mail_form_reply_from_name';

            $errors[] = __(
                'Please enter the sender name for the auto-reply email.',
                'im-mail-form'
            );
        }

        if ($reply_from_raw === '') {

            $invalid_fields[] =
                'im_mail_form_reply_from';

            $errors[] = __(
                'Please enter the sender email address for the auto-reply email.',
                'im-mail-form'
            );

        } elseif (
            $reply_from === '' ||
            !is_email($reply_from)
        ) {

            $invalid_fields[] =
                'im_mail_form_reply_from';

            $errors[] = __(
                'Please enter a valid sender email address for the auto-reply email.',
                'im-mail-form'
            );
        }

        if (
            immf_has_invalid_email_list(
                $reply_bcc_raw
            )
        ) {

            $invalid_fields[] =
                'im_mail_form_reply_bcc';

            $errors[] = __(
                'The auto-reply email Bcc field contains an invalid email address.',
                'im-mail-form'
            );
        }

        if ($reply_subject === '') {

            $invalid_fields[] =
                'im_mail_form_reply_subject';

            $errors[] = __(
                'Please enter a subject for the auto-reply email.',
                'im-mail-form'
            );
        }

        if ($reply_body === '') {

            $invalid_fields[] =
                'im_mail_form_reply_body';

            $errors[] = __(
                'Please enter a body for the auto-reply email.',
                'im-mail-form'
            );
        }
    }


    /*----------------------------------------
    管理者向けメール
    ----------------------------------------*/

    $admin_to_raw = isset(
        $_POST['im_mail_form_admin_to']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_admin_to']
            )
        )
        : '';

    $admin_to = sanitize_email(
        $admin_to_raw
    );

    $admin_from_name = isset(
        $_POST['im_mail_form_admin_from_name']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_admin_from_name']
            )
        )
        : '';

    $admin_from_raw = isset(
        $_POST['im_mail_form_admin_from']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_admin_from']
            )
        )
        : '';

    $admin_from = sanitize_email(
        $admin_from_raw
    );

    $admin_cc_raw = isset(
        $_POST['im_mail_form_admin_cc']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_admin_cc']
            )
        )
        : '';

    $admin_bcc_raw = isset(
        $_POST['im_mail_form_admin_bcc']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_admin_bcc']
            )
        )
        : '';

    $admin_subject = isset(
        $_POST['im_mail_form_admin_subject']
    )
        ? sanitize_text_field(
            wp_unslash(
                $_POST['im_mail_form_admin_subject']
            )
        )
        : '';

    $admin_body = isset(
        $_POST['im_mail_form_admin_body']
    )
        ? sanitize_textarea_field(
            wp_unslash(
                $_POST['im_mail_form_admin_body']
            )
        )
        : '';

        if ($admin_to_raw === '') {

            $invalid_fields[] =
                'im_mail_form_admin_to';

            $errors[] = __(
                'Please enter a recipient email address for the admin email.',
                'im-mail-form'
            );

        } elseif (
            $admin_to === '' ||
            !is_email($admin_to)
        ) {

            $invalid_fields[] =
                'im_mail_form_admin_to';

            $errors[] = __(
                'Please enter a valid recipient email address for the admin email.',
                'im-mail-form'
            );
        }

        if ($admin_from_name === '') {

            $invalid_fields[] =
                'im_mail_form_admin_from_name';

            $errors[] = __(
                'Please enter the sender name for the admin email.',
                'im-mail-form'
            );
        }

        if ($admin_from_raw === '') {

            $invalid_fields[] =
                'im_mail_form_admin_from';

            $errors[] = __(
                'Please enter the sender email address for the admin email.',
                'im-mail-form'
            );

        } elseif (
            $admin_from === '' ||
            !is_email($admin_from)
        ) {

            $invalid_fields[] =
                'im_mail_form_admin_from';

            $errors[] = __(
                'Please enter a valid sender email address for the admin email.',
                'im-mail-form'
            );
        }

        if (
            immf_has_invalid_email_list(
                $admin_cc_raw
            )
        ) {

            $invalid_fields[] =
                'im_mail_form_admin_cc';

            $errors[] = __(
                'The admin email Cc field contains an invalid email address.',
                'im-mail-form'
            );
        }

        if (
            immf_has_invalid_email_list(
                $admin_bcc_raw
            )
        ) {

            $invalid_fields[] =
                'im_mail_form_admin_bcc';

            $errors[] = __(
                'The admin email Bcc field contains an invalid email address.',
                'im-mail-form'
            );
        }

        /*----------------------------------------
        送信先メールアドレスの重複チェック
        ----------------------------------------*/
        $admin_recipient_groups = [
            'im_mail_form_admin_to'  => [
                $admin_to_raw,
            ],
            'im_mail_form_admin_cc'  => explode(
                ',',
                $admin_cc_raw
            ),
            'im_mail_form_admin_bcc' => explode(
                ',',
                $admin_bcc_raw
            ),
        ];

        $used_admin_recipients = [];
        $duplicate_recipient_fields = [];

        foreach (
            $admin_recipient_groups
            as $field_name => $addresses
        ) {

            foreach ($addresses as $address) {

                $address = strtolower(
                    trim($address)
                );

                if (
                    $address === '' ||
                    !is_email($address)
                ) {
                    continue;
                }

                if (
                    isset(
                        $used_admin_recipients[$address]
                    )
                ) {

                    $duplicate_recipient_fields[] =
                        $field_name;

                    $duplicate_recipient_fields[] =
                        $used_admin_recipients[$address];

                    continue;
                }

                $used_admin_recipients[$address] =
                    $field_name;
            }
        }

        $duplicate_recipient_fields = array_values(
            array_unique(
                $duplicate_recipient_fields
            )
        );

        if (!empty($duplicate_recipient_fields)) {

            $invalid_fields = array_values(
                array_unique(
                    array_merge(
                        $invalid_fields,
                        $duplicate_recipient_fields
                    )
                )
            );

            $errors[] = __(
                'The same email address cannot be used more than once across To, Cc, and Bcc.',
                'im-mail-form'
            );
        }

        if ($admin_subject === '') {

            $invalid_fields[] =
                'im_mail_form_admin_subject';

            $errors[] = __(
                'Please enter a subject for the admin email.',
                'im-mail-form'
            );
        }

        if ($admin_body === '') {

            $invalid_fields[] =
                'im_mail_form_admin_body';

            $errors[] = __(
                'Please enter a body for the admin email.',
                'im-mail-form'
            );
        }

    /*----------------------------------------
    リダイレクト先URL
    ----------------------------------------*/
    $redirect_enabled = isset(
        $_POST['im_mail_form_redirect_enabled']
    );

    if ($redirect_enabled) {

        $redirect_url_raw = isset(
            $_POST['im_mail_form_redirect_url']
        )
            ? sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_redirect_url']
                )
            )
            : '';

        $redirect_url = esc_url_raw(
            $redirect_url_raw,
            [
                'http',
                'https',
            ]
        );

        if ($redirect_url_raw === '') {

            $invalid_fields[] =
                'im_mail_form_redirect_url';

            $errors[] = __(
                'Please enter a redirect URL.',
                'im-mail-form'
            );

        } elseif (
            $redirect_url === '' ||
            !filter_var(
                $redirect_url,
                FILTER_VALIDATE_URL
            )
        ) {

            $invalid_fields[] =
                'im_mail_form_redirect_url';

            $errors[] = __(
                'Please enter a valid redirect URL.',
                'im-mail-form'
            );
        }
    }

    if (!$redirect_enabled) {

        $complete_message = isset(
            $_POST['im_mail_form_complete_message']
        )
            ? trim(
                wp_strip_all_tags(
                    wp_unslash(
                        $_POST[
                            'im_mail_form_complete_message'
                        ]
                    )
                )
            )
            : '';

        if ($complete_message === '') {

            $invalid_fields[] =
                'im_mail_form_complete_message';

            $errors[] = __(
                'Please enter a completion message.',
                'im-mail-form'
            );
        }
    }

    return $errors;
}
// phpcs:enable WordPress.Security.NonceVerification.Missing


/*----------------------------------------
メール設定：保存時バリデーション
----------------------------------------*/
function immf_validate_contact_form_mail_settings_on_save($post_id) {

    if (!immf_can_save($post_id)) {
        return;
    }

    if (
        !isset($_POST['im_mail_form_settings_nonce']) ||
        !wp_verify_nonce(
            sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_settings_nonce']
                )
            ),
            'immf_save_contact_form_settings'
        )
    ) {
        return;
    }

    $invalid_fields = [];

    $errors = immf_validate_contact_form_mail_settings(
        $post_id,
        $invalid_fields
    );

    // エラーがなければ、以前のエラー情報を削除
    if (empty($errors)) {

        delete_transient(
            'immf_errors_' . get_current_user_id()
        );

        delete_transient(
            'immf_invalid_mail_fields_'
                . get_current_user_id()
                . '_'
                . $post_id
        );

        delete_transient(
            'immf_error_tabs_'
                . get_current_user_id()
        );

        return;
    }

    set_transient(
        'immf_use_reply_input_'
            . get_current_user_id()
            . '_'
            . $post_id,
        isset(
            $_POST['im_mail_form_use_reply']
        ) ? '1' : '0',
        60
    );
    

    // 不完全な設定のままメール機能を有効化しない
    update_post_meta(
        $post_id,
        'immf_use_reply',
        '0'
    );

    update_post_meta(
        $post_id,
        'immf_use_admin_mail',
        '0'
    );

    //エラー時の完了画面設定を一時保存
    $complete_settings = [
        'redirect_enabled' => isset(
            $_POST['im_mail_form_redirect_enabled']
        ) ? '1' : '0',

        'redirect_url' => isset(
            $_POST['im_mail_form_redirect_url']
        )
            ? sanitize_text_field(
                wp_unslash(
                    $_POST['im_mail_form_redirect_url']
                )
            )
            : get_post_meta(
                $post_id,
                'immf_redirect_url',
                true
            ),

        'complete_message' => isset(
            $_POST['im_mail_form_complete_message']
        )
            ? wp_kses_post(
                wp_unslash(
                    $_POST['im_mail_form_complete_message']
                )
            )
            : get_post_meta(
                $post_id,
                'immf_complete_message',
                true
            ),
    ];

    set_transient(
        'immf_complete_settings_'
            . get_current_user_id()
            . '_'
            . $post_id,
        $complete_settings,
        60
    );

    set_transient(
        'immf_invalid_mail_fields_'
            . get_current_user_id()
            . '_'
            . $post_id,
        array_values(
            array_unique($invalid_fields)
        ),
        60
    );

    $error_tabs = [];

    foreach ($invalid_fields as $invalid_field) {

        if (
            $invalid_field ===
                'im_mail_form_redirect_url' ||
            $invalid_field ===
                'im_mail_form_complete_message'
        ) {
            $error_tabs[] = 'complete';

        } else {
            $error_tabs[] = 'mail';
        }
    }

    set_transient(
        'immf_error_tabs_'
            . get_current_user_id(),
        array_values(
            array_unique($error_tabs)
        ),
        60
    );

    // リロード後に表示するため、エラー内容を一時保存
    set_transient(
        'immf_errors_' . get_current_user_id(),
        $errors,
        60
    );
}

add_action(
    'save_post_im_mail_form',
    'immf_validate_contact_form_mail_settings_on_save',
    20
);


/*----------------------------------------
フォーム項目設定エラーを表示
----------------------------------------*/
function immf_fields_error_notice() {

    global $post;

    if (
        !($post instanceof WP_Post) ||
        $post->post_type !== 'im_mail_form'
    ) {
        return;
    }

    $transient_key =
        'immf_fields_errors_'
        . get_current_user_id()
        . '_'
        . $post->ID;

    $errors = get_transient(
        $transient_key
    );

    if (
        !is_array($errors) ||
        empty($errors)
    ) {
        return;
    }

    delete_transient(
        $transient_key
    );

    ?>

    <div
        class="notice notice-error is-dismissible"
        data-contact-form-error-tab="fields"
        data-contact-form-save-error
    >
        <p>
            <strong>
                <?php
                esc_html_e(
                    'There are errors in the form field settings.',
                    'im-mail-form'
                );
                ?>
            </strong>
        </p>

        <ul>

            <?php foreach ($errors as $error) : ?>

                <li>
                    <?php echo esc_html($error); ?>
                </li>

            <?php endforeach; ?>

        </ul>
    </div>

    <?php
}

add_action(
    'admin_notices',
    'immf_fields_error_notice'
);


/*----------------------------------------
フォーム基本設定エラーを表示
----------------------------------------*/
function immf_settings_error_notice() {

    global $post;

    if (
        !($post instanceof WP_Post) ||
        $post->post_type !== 'im_mail_form'
    ) {
        return;
    }

    $transient_key =
        'immf_settings_error_'
        . get_current_user_id()
        . '_'
        . $post->ID;

    $message = get_transient(
        $transient_key
    );

    if ($message === false) {
        return;
    }

    delete_transient(
        $transient_key
    );

    ?>

    <div
        class="notice notice-error is-dismissible"
        data-contact-form-save-error
    >
        <p>
            <?php echo esc_html($message); ?>
        </p>
    </div>

    <?php
}

add_action(
    'admin_notices',
    'immf_settings_error_notice'
);


/*----------------------------------------
自動返信メール設定エラーを表示
----------------------------------------*/
function immf_reply_error_notice() {

    $message = get_transient(
        'immf_reply_error_'
        . get_current_user_id()
    );

    if ($message === false) {
        return;
    }

    delete_transient(
        'immf_reply_error_'
        . get_current_user_id()
    );

    ?>

    <div
        class="notice notice-error is-dismissible"
        data-contact-form-save-error
    >
        <p>
            <?php echo esc_html($message); ?>
        </p>
    </div>

    <?php
}

add_action(
    'admin_notices',
    'immf_reply_error_notice'
);

/*----------------------------------------
メールフォーム：保存完了メッセージを変更
----------------------------------------*/
function immf_updated_messages($messages) {

    if (
        !isset($messages['post']) ||
        !is_array($messages['post'])
    ) {
        return $messages;
    }

    global $post;

    if (
        $post instanceof WP_Post &&
        (
            get_transient(
                'immf_settings_error_'
                    . get_current_user_id()
                    . '_'
                    . $post->ID
            ) !== false ||
            get_transient(
                'immf_fields_errors_'
                    . get_current_user_id()
                    . '_'
                    . $post->ID
            ) !== false ||
            get_transient(
                'immf_errors_'
                    . get_current_user_id()
            ) !== false ||
            get_transient(
                'immf_save_error_'
                    . get_current_user_id()
                    . '_'
                    . $post->ID
            ) !== false
        )
    ) {

        delete_transient(
            'immf_save_error_'
                . get_current_user_id()
                . '_'
                . $post->ID
        );

        $messages['im_mail_form'] =
            array_fill_keys(
                array_keys($messages['post']),
                ''
            );

        return $messages;
    }

    $messages['im_mail_form'] =
        $messages['post'];

    foreach (
        $messages['im_mail_form']
        as $message_key => $message
    ) {

        if ($message_key === 0) {
            continue;
        }

        $messages['im_mail_form'][$message_key] =
            __(
                'Settings saved.',
                'im-mail-form'
            );
    }

    return $messages;
}

add_filter(
    'post_updated_messages',
    'immf_updated_messages'
);