<?php

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

/*----------------------------------------
フォーム一覧：Duplicate行アクションを追加
----------------------------------------*/
function immf_add_duplicate_row_action(
    $actions,
    $post
) {

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

    // ゴミ箱内のフォームは複製対象にしない
    if ($post->post_status === 'trash') {
        return $actions;
    }

    if (
        !current_user_can(
            'edit_post',
            $post->ID
        )
    ) {
        return $actions;
    }

    $duplicate_url = wp_nonce_url(
        add_query_arg(
            [
                'action' => 'im_mail_form_duplicate',
                'post'   => $post->ID,
            ],
            admin_url('edit.php')
        ),
        'im_mail_form_duplicate_' . $post->ID
    );

    $duplicate_action =
        '<a href="'
        . esc_url($duplicate_url)
        . '">'
        . esc_html__(
            'Duplicate',
            'im-mail-form'
        )
        . '</a>';

    // Editの直後にDuplicateを挿入する
    if (isset($actions['edit'])) {

        $new_actions = [];

        foreach ($actions as $key => $action) {

            $new_actions[$key] = $action;

            if ($key === 'edit') {
                $new_actions['im_mail_form_duplicate'] =
                    $duplicate_action;
            }
        }

        return $new_actions;
    }

    $actions['im_mail_form_duplicate'] =
        $duplicate_action;

    return $actions;

}

add_filter(
    'post_row_actions',
    'immf_add_duplicate_row_action',
    10,
    2
);


/*----------------------------------------
フォーム一覧：既存フォームIDを一覧取得
----------------------------------------*/
function immf_get_all_form_ids() {

    $post_ids = get_posts([
        'post_type'      => 'im_mail_form',
        'post_status'    => 'any',
        'posts_per_page' => -1,
        'fields'         => 'ids',
        'no_found_rows'  => true,
    ]);

    $form_ids = [];

    foreach ($post_ids as $post_id) {

        $form_id = get_post_meta(
            $post_id,
            'immf_id',
            true
        );

        if ($form_id !== '') {
            $form_ids[] = $form_id;
        }
    }

    return $form_ids;

}


/*----------------------------------------
フォーム一覧：既存フォームタイトルを一覧取得
----------------------------------------*/
function immf_get_all_form_titles() {

    $posts = get_posts([
        'post_type'      => 'im_mail_form',
        'post_status'    => 'any',
        'posts_per_page' => -1,
        'no_found_rows'  => true,
    ]);

    return wp_list_pluck(
        $posts,
        'post_title'
    );

}


/*----------------------------------------
複製用のフォームIDを生成
----------------------------------------*/
function immf_generate_duplicate_form_id($source_form_id) {

    $source_form_id = sanitize_key($source_form_id);

    if ($source_form_id === '') {
        $source_form_id = 'form';
    }

    $existing_ids = immf_get_all_form_ids();

    $base_id = $source_form_id . '-copy';

    if (
        !in_array(
            $base_id,
            $existing_ids,
            true
        )
    ) {
        return $base_id;
    }

    /*
    * 既存の"{元ID}-copy-N"から最大番号を探し、
    * 常に"-copy"を含む形で次の番号を採番する。
    */
    $max_number = 1;

    $pattern =
        '/^'
        . preg_quote($source_form_id, '/')
        . '-copy-(\d+)$/';

    foreach ($existing_ids as $existing_id) {

        if (
            preg_match(
                $pattern,
                $existing_id,
                $matches
            )
        ) {
            $max_number = max(
                $max_number,
                (int) $matches[1]
            );
        }
    }

    return $source_form_id
        . '-copy-'
        . ($max_number + 1);

}


/*----------------------------------------
複製用のフォームタイトルを生成
----------------------------------------*/
function immf_generate_duplicate_title($source_title) {

    $copy_suffix = __(
        'Copy',
        'im-mail-form'
    );

    $base_title =
        $source_title
        . ' - '
        . $copy_suffix;

    $existing_titles = immf_get_all_form_titles();

    if (
        !in_array(
            $base_title,
            $existing_titles,
            true
        )
    ) {
        return $base_title;
    }

    /*
    * 既存の"{ベースタイトル} (N)"から最大番号を探し、
    * 重複しないタイトルを採番する。
    */
    $max_number = 1;

    $pattern =
        '/^'
        . preg_quote($base_title, '/')
        . ' \((\d+)\)$/';

    foreach ($existing_titles as $existing_title) {

        if (
            preg_match(
                $pattern,
                $existing_title,
                $matches
            )
        ) {
            $max_number = max(
                $max_number,
                (int) $matches[1]
            );
        }
    }

    return $base_title
        . ' ('
        . ($max_number + 1)
        . ')';

}


/*----------------------------------------
フォームを複製
----------------------------------------*/
function immf_duplicate_form($source_id) {

    $source_post = get_post($source_id);

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

    $source_form_id = get_post_meta(
        $source_id,
        'immf_id',
        true
    );

    $new_form_id =
        immf_generate_duplicate_form_id(
            $source_form_id
        );

    $new_title =
        immf_generate_duplicate_title(
            $source_post->post_title
        );

    $new_post_id = wp_insert_post(
        [
            'post_type'   => 'im_mail_form',
            'post_status' => $source_post->post_status,
            'post_title'  => $new_title,
        ],
        true
    );

    if (is_wp_error($new_post_id)) {
        return 0;
    }

    /*----------------------------------------
    投稿ID・メールログ・作成日時・更新日時以外の
    IM Mail Form関連post metaをすべて複製する
    ----------------------------------------*/
    $source_meta = get_post_meta($source_id);

    if (is_array($source_meta)) {

        foreach ($source_meta as $meta_key => $meta_values) {

            if (
                !str_starts_with(
                    $meta_key,
                    'immf_'
                )
            ) {
                continue;
            }

            $meta_value = get_post_meta(
                $source_id,
                $meta_key,
                true
            );

            update_post_meta(
                $new_post_id,
                $meta_key,
                $meta_value
            );
        }
    }

    // フォームIDだけは複製用に生成した新しい値へ上書きする
    update_post_meta(
        $new_post_id,
        'immf_id',
        $new_form_id
    );

    return $new_post_id;

}


/*----------------------------------------
フォーム一覧：Duplicateアクションを処理
----------------------------------------*/
function immf_handle_duplicate_action() {

    $source_id = isset($_GET['post'])
        ? absint(wp_unslash($_GET['post']))
        : 0;

    if ($source_id === 0) {
        wp_die(
            esc_html__(
                'Invalid form.',
                'im-mail-form'
            )
        );
    }

    check_admin_referer(
        'im_mail_form_duplicate_' . $source_id
    );

    if (
        !current_user_can(
            'edit_post',
            $source_id
        )
    ) {
        wp_die(
            esc_html__(
                'You are not allowed to duplicate this form.',
                'im-mail-form'
            )
        );
    }

    if (
        get_post_type($source_id) !== 'im_mail_form' ||
        get_post_status($source_id) === 'trash'
    ) {
        wp_die(
            esc_html__(
                'Invalid form.',
                'im-mail-form'
            )
        );
    }

    $new_post_id = immf_duplicate_form(
        $source_id
    );

    if (!$new_post_id) {
        wp_die(
            esc_html__(
                'The form could not be duplicated.',
                'im-mail-form'
            )
        );
    }

    wp_safe_redirect(
        add_query_arg(
            'im_mail_form_duplicated',
            '1',
            admin_url(
                'post.php?action=edit&post=' . $new_post_id
            )
        )
    );

    exit;

}

add_action(
    'admin_action_im_mail_form_duplicate',
    'immf_handle_duplicate_action'
);


/*----------------------------------------
フォーム複製後の完了通知を表示
----------------------------------------*/
function immf_show_duplicate_notice() {

    $screen = get_current_screen();

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

    if (!current_user_can('manage_options')) {
        return;
    }

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This value is only used to display an admin notice after duplication.
    $duplicated = isset($_GET['im_mail_form_duplicated'])
        ? sanitize_text_field(
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            wp_unslash($_GET['im_mail_form_duplicated'])
        )
        : '';

    if ($duplicated !== '1') {
        return;
    }

    ?>

    <div class="notice notice-success is-dismissible">
        <p>
            <?php esc_html_e(
                'Form duplicated. You are now editing the new copy.',
                'im-mail-form'
            ); ?>
        </p>
    </div>

    <?php
}

add_action(
    'admin_notices',
    'immf_show_duplicate_notice'
);
