<?php
/**
 * [1.5.398] TRANSFERÊNCIA DE PROJETO DE VÍDEO entre artistas.
 *
 * Quando a equipa descobre que a música pertence a OUTRO artista, o projeto
 * pode ser transferido. Dois modos:
 *   - FORÇADA:       muda imediatamente, sem o artista atual saber.
 *   - COM ACEITAÇÃO: o artista atual recebe o pedido no site e tem de aceitar;
 *                    só depois o admin escolhe o novo dono na lista de artistas.
 *
 * Durante a transferência o admin pode mudar o NÍVEL (scenario_type), o
 * TÍTULO e o PITCH DO ARTISTA. O contrato/KYC do dono antigo é limpo — o novo
 * dono terá de assinar/validar de novo.
 *
 * Estado pendente guardado em extra_data['transfer_request']:
 *   { mode, status: pending|accepted, reason, requested_at, accepted_at,
 *     target_tel, changes: { title, scenario, pitch } }
 */

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

/* ====================================================================== */
/* NÚCLEO                                                                  */
/* ====================================================================== */

/**
 * Executa a transferência: muda o dono, aplica alterações, limpa KYC/contrato,
 * regista no histórico e notifica.
 *
 * @param int    $project_id
 * @param string $new_tel  Telemóvel do novo dono.
 * @param array  $changes  ['title'=>?, 'scenario'=>?, 'pitch'=>?] (vazios = manter).
 * @param string $mode     'forced'|'consent'
 * @return array [ 'success'=>bool, 'message'=>string ]
 */
function rmbz_project_transfer_execute( $project_id, $new_tel, array $changes, $mode ) {
    global $wpdb;
    $t_proj    = $wpdb->prefix . 'rmbz_artist_projects';
    $t_wallets = $wpdb->prefix . 'rmbz_wallets';

    $p = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t_proj} WHERE id=%d", (int) $project_id ) );
    if ( ! $p ) return [ 'success' => false, 'message' => 'Projeto não encontrado.' ];

    $new_tel = trim( (string) $new_tel );
    $new_owner = $wpdb->get_row( $wpdb->prepare(
        "SELECT user_telemovel, user_nome FROM {$t_wallets} WHERE user_telemovel=%s", $new_tel
    ) );
    if ( ! $new_owner ) return [ 'success' => false, 'message' => 'Novo dono não encontrado na lista de artistas.' ];
    if ( $new_tel === (string) $p->artist_telemovel ) {
        return [ 'success' => false, 'message' => 'O novo dono é o dono atual — nada a transferir.' ];
    }

    $old_tel  = (string) $p->artist_telemovel;
    $old_name = (string) $wpdb->get_var( $wpdb->prepare(
        "SELECT user_nome FROM {$t_wallets} WHERE user_telemovel=%s", $old_tel
    ) ) ?: $old_tel;
    $new_name = $new_owner->user_nome ?: $new_tel;

    $extra = ! empty( $p->extra_data ) ? json_decode( $p->extra_data, true ) : [];
    if ( ! is_array( $extra ) ) $extra = [];

    // Campos alteráveis na transferência.
    $update = [ 'artist_telemovel' => $new_tel ];
    $fmt    = [ '%s' ];
    $new_title    = isset( $changes['title'] ) ? trim( (string) $changes['title'] ) : '';
    $new_scenario = isset( $changes['scenario'] ) ? trim( (string) $changes['scenario'] ) : '';
    $new_pitch    = isset( $changes['pitch'] ) ? trim( (string) $changes['pitch'] ) : '';
    if ( $new_title !== '' && $new_title !== (string) $p->project_title ) {
        $update['project_title'] = sanitize_text_field( $new_title ); $fmt[] = '%s';
    }
    if ( $new_scenario !== '' && $new_scenario !== (string) $p->scenario_type ) {
        $update['scenario_type'] = sanitize_text_field( $new_scenario ); $fmt[] = '%s';
    }
    if ( $new_pitch !== '' && $new_pitch !== (string) $p->project_pitch ) {
        $update['project_pitch'] = sanitize_textarea_field( $new_pitch ); $fmt[] = '%s';
    }

    // Extra: novo nome, limpar KYC/contrato do dono antigo e o pedido pendente.
    $extra['artist_name'] = (string) $new_name;
    foreach ( [ 'contract_accepted', 'contract_rejected', 'contract_real_name', 'kyc_status',
                'contract_kyc_photo', 'kyc_rejection_reason', 'contract_deadline', 'transfer_request' ] as $k ) {
        unset( $extra[ $k ] );
    }
    $extra['transferred_from'] = [ 'tel' => $old_tel, 'name' => $old_name, 'at' => current_time( 'mysql' ), 'mode' => $mode ];
    $update['extra_data'] = wp_json_encode( $extra );
    $fmt[] = '%s';

    // [1.5.398] Migração à prova de falhas:
    //  - o WHERE inclui o dono ATUAL (old_tel) — se outro admin transferiu
    //    entretanto, este update afeta 0 linhas e NÃO aplica por cima;
    //  - depois do update RELEMOS a linha e confirmamos que o dono é mesmo o
    //    novo antes de registar histórico e disparar notificações. Assim as
    //    notificações futuras do projeto (que seguem artist_telemovel) vão
    //    garantidamente para o novo dono.
    $ok = $wpdb->update(
        $t_proj,
        $update,
        [ 'id' => (int) $project_id, 'artist_telemovel' => $old_tel ],
        $fmt,
        [ '%d', '%s' ]
    );
    if ( $ok === false ) {
        return [ 'success' => false, 'message' => 'Falha na base de dados: ' . $wpdb->last_error ];
    }
    if ( (int) $ok === 0 ) {
        return [ 'success' => false, 'message' => 'A transferência não foi aplicada — o projeto mudou entretanto (outro admin?). Recarrega a página e tenta de novo.' ];
    }
    $verify = $wpdb->get_var( $wpdb->prepare( "SELECT artist_telemovel FROM {$t_proj} WHERE id=%d", (int) $project_id ) );
    if ( (string) $verify !== $new_tel ) {
        return [ 'success' => false, 'message' => 'Verificação pós-migração falhou — o dono do projeto não corresponde ao esperado. Nada foi notificado; verifica o projeto.' ];
    }

    // Histórico do projeto.
    if ( function_exists( 'rmbz_pchat_append_change_log' ) ) {
        $who = function_exists( 'rmbz_pchat_current_admin_who' ) ? rmbz_pchat_current_admin_who() : 'admin';
        rmbz_pchat_append_change_log( (int) $project_id, [
            'who'  => $who,
            'what' => $mode === 'forced' ? '🔁 Transferiu o projeto (forçada)' : '🔁 Transferiu o projeto (aceite pelo artista)',
            'from' => $old_name . ' (' . $old_tel . ')',
            'to'   => $new_name . ' (' . $new_tel . ')',
        ] );
        if ( isset( $update['project_title'] ) ) {
            rmbz_pchat_append_change_log( (int) $project_id, [ 'who' => $who, 'what' => '✏️ Alterou o título na transferência', 'from' => (string) $p->project_title, 'to' => $update['project_title'] ] );
        }
        if ( isset( $update['scenario_type'] ) ) {
            rmbz_pchat_append_change_log( (int) $project_id, [ 'who' => $who, 'what' => '🎚️ Alterou o nível na transferência', 'from' => (string) $p->scenario_type, 'to' => $update['scenario_type'] ] );
        }
        if ( isset( $update['project_pitch'] ) ) {
            rmbz_pchat_append_change_log( (int) $project_id, [ 'who' => $who, 'what' => '💬 Alterou o pitch do artista na transferência', 'from' => '(anterior)', 'to' => '(novo)' ] );
        }
    }

    $title_now = isset( $update['project_title'] ) ? $update['project_title'] : (string) $p->project_title;

    $site_name = get_bloginfo( 'name' );

    // Notificar o NOVO dono em TODOS os canais (push/sino do app + email/sino do site).
    if ( function_exists( 'rmbz_notify_user' ) ) {
        rmbz_notify_user(
            $new_tel,
            '🎬 Projeto transferido para a tua conta',
            sprintf( 'O projeto de vídeo "%s" é agora teu. Revê o contrato na tua conta — precisas de o assinar para a produção continuar.', $title_now ),
            'success'
        );
    }
    if ( function_exists( 'rmbz_notify' ) ) {
        rmbz_notify( $new_tel, 'project_transfer_done_new', [
            'nome_artista' => $new_name,
            'musica'       => $title_now,
            'site_name'    => $site_name,
        ] );
    }
    // Notificar o dono ANTIGO apenas no modo com aceitação (ele participou).
    if ( $mode !== 'forced' ) {
        if ( function_exists( 'rmbz_notify_user' ) ) {
            rmbz_notify_user(
                $old_tel,
                '🔁 Transferência concluída',
                sprintf( 'O projeto "%s" foi transferido conforme aceitaste. Obrigado!', (string) $p->project_title ),
                'info'
            );
        }
        if ( function_exists( 'rmbz_notify' ) ) {
            rmbz_notify( $old_tel, 'project_transfer_done_old', [
                'nome_artista' => $old_name,
                'musica'       => (string) $p->project_title,
                'site_name'    => $site_name,
            ] );
        }
    }

    return [ 'success' => true, 'message' => sprintf( 'Projeto transferido de %s para %s.', $old_name, $new_name ) ];
}

/** Lê o pedido pendente (ou null). */
function rmbz_project_transfer_request_get( $project_id ) {
    global $wpdb;
    $extra = $wpdb->get_var( $wpdb->prepare(
        "SELECT extra_data FROM {$wpdb->prefix}rmbz_artist_projects WHERE id=%d", (int) $project_id
    ) );
    $extra = $extra ? json_decode( $extra, true ) : [];
    $req = is_array( $extra ) && ! empty( $extra['transfer_request'] ) && is_array( $extra['transfer_request'] )
        ? $extra['transfer_request'] : null;
    return $req;
}

/** Grava/atualiza o transfer_request no extra_data. */
function rmbz_project_transfer_request_set( $project_id, $req ) {
    global $wpdb;
    $t = $wpdb->prefix . 'rmbz_artist_projects';
    $extra = $wpdb->get_var( $wpdb->prepare( "SELECT extra_data FROM {$t} WHERE id=%d", (int) $project_id ) );
    $extra = $extra ? json_decode( $extra, true ) : [];
    if ( ! is_array( $extra ) ) $extra = [];
    if ( $req === null ) unset( $extra['transfer_request'] );
    else $extra['transfer_request'] = $req;
    return false !== $wpdb->update( $t, [ 'extra_data' => wp_json_encode( $extra ) ], [ 'id' => (int) $project_id ], [ '%s' ], [ '%d' ] );
}

/**
 * [1.5.398] Cria o pedido de transferência (modo com aceitação) e notifica o
 * artista atual em TODOS os canais. Usado pelo WP admin e pelo app admin.
 */
function rmbz_project_transfer_create_request( $project_id, $reason = '', $target = '', $changes = [] ) {
    global $wpdb;
    $p = $wpdb->get_row( $wpdb->prepare(
        "SELECT id, project_title, artist_telemovel FROM {$wpdb->prefix}rmbz_artist_projects WHERE id=%d", (int) $project_id
    ) );
    if ( ! $p ) return [ 'success' => false, 'message' => 'Projeto não encontrado.' ];

    $existing = rmbz_project_transfer_request_get( (int) $project_id );
    if ( $existing && in_array( (string) ( $existing['status'] ?? '' ), [ 'pending', 'accepted' ], true ) ) {
        return [ 'success' => false, 'message' => 'Já existe um pedido de transferência em curso neste projeto.' ];
    }

    $reason = sanitize_textarea_field( (string) $reason );
    rmbz_project_transfer_request_set( (int) $project_id, [
        'mode'         => 'consent',
        'status'       => 'pending',
        'reason'       => $reason,
        'requested_at' => current_time( 'mysql' ),
        'target_tel'   => sanitize_text_field( (string) $target ),
        'changes'      => is_array( $changes ) ? $changes : [],
    ] );

    if ( function_exists( 'rmbz_notify_user' ) ) {
        rmbz_notify_user(
            (string) $p->artist_telemovel,
            '🔁 Pedido de transferência de projeto',
            sprintf( 'A 1MZ pediu para transferir o projeto "%s" para outra conta.%s Abre o projeto para aceitar ou recusar.',
                (string) $p->project_title, $reason !== '' ? ' Motivo: ' . $reason . '.' : '' ),
            'warning'
        );
    }
    if ( function_exists( 'rmbz_notify' ) ) {
        $nome = $wpdb->get_var( $wpdb->prepare(
            "SELECT user_nome FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel=%s", (string) $p->artist_telemovel
        ) ) ?: 'Artista';
        rmbz_notify( (string) $p->artist_telemovel, 'project_transfer_request', [
            'nome_artista' => $nome,
            'musica'       => (string) $p->project_title,
            'motivo'       => $reason !== '' ? ' Motivo da equipa: ' . $reason . '.' : '',
            'site_name'    => get_bloginfo( 'name' ),
        ] );
    }
    return [ 'success' => true, 'message' => 'Pedido enviado ao artista — aguarda aceitação.' ];
}

/**
 * [1.5.398] Cancela o pedido em curso e avisa o artista (em todos os canais)
 * de que a transferência NÃO foi avante. Usado pelo WP admin e pelo app admin.
 */
function rmbz_project_transfer_cancel_request( $project_id ) {
    global $wpdb;
    $req = rmbz_project_transfer_request_get( (int) $project_id );
    rmbz_project_transfer_request_set( (int) $project_id, null );
    if ( ! $req || ! in_array( (string) ( $req['status'] ?? '' ), [ 'pending', 'accepted' ], true ) ) {
        return false;
    }
    $p = $wpdb->get_row( $wpdb->prepare(
        "SELECT p.project_title, p.artist_telemovel, w.user_nome
         FROM {$wpdb->prefix}rmbz_artist_projects p
         LEFT JOIN {$wpdb->prefix}rmbz_wallets w ON w.user_telemovel = p.artist_telemovel
         WHERE p.id=%d", (int) $project_id
    ) );
    if ( $p ) {
        if ( function_exists( 'rmbz_notify_user' ) ) {
            rmbz_notify_user(
                (string) $p->artist_telemovel,
                '🔁 Transferência não foi possível',
                sprintf( 'A transferência do projeto "%s" não foi concluída. O projeto continua na tua conta, tudo como antes.', (string) $p->project_title ),
                'info'
            );
        }
        if ( function_exists( 'rmbz_notify' ) ) {
            rmbz_notify( (string) $p->artist_telemovel, 'project_transfer_failed', [
                'nome_artista' => $p->user_nome ?: 'Artista',
                'musica'       => (string) $p->project_title,
                'site_name'    => get_bloginfo( 'name' ),
            ] );
        }
    }
    return true;
}

/* ====================================================================== */
/* ADMIN (admin-post)                                                      */
/* ====================================================================== */

// Iniciar transferência (forçada executa já; com aceitação cria o pedido).
add_action( 'admin_post_rmbz_project_transfer', function () {
    if ( ! current_user_can( 'manage_options' ) ) wp_die( 'Sem permissão.' );
    $project_id = isset( $_POST['project_id'] ) ? (int) $_POST['project_id'] : 0;
    check_admin_referer( 'rmbz_project_transfer_' . $project_id );

    $mode    = ( isset( $_POST['transfer_mode'] ) && $_POST['transfer_mode'] === 'forced' ) ? 'forced' : 'consent';
    $target  = isset( $_POST['target_tel'] ) ? sanitize_text_field( wp_unslash( (string) $_POST['target_tel'] ) ) : '';
    $reason  = isset( $_POST['transfer_reason'] ) ? sanitize_textarea_field( wp_unslash( (string) $_POST['transfer_reason'] ) ) : '';
    $changes = [
        'title'    => isset( $_POST['new_title'] ) ? wp_unslash( (string) $_POST['new_title'] ) : '',
        'scenario' => isset( $_POST['new_scenario'] ) ? wp_unslash( (string) $_POST['new_scenario'] ) : '',
        'pitch'    => isset( $_POST['new_pitch'] ) ? wp_unslash( (string) $_POST['new_pitch'] ) : '',
    ];
    $back = admin_url( 'admin.php?page=rmbz-projetos&action=edit&id=' . $project_id );

    if ( $mode === 'forced' ) {
        if ( $target === '' ) { wp_redirect( add_query_arg( 'msg', rawurlencode( 'Escolhe o novo dono para a transferência forçada.' ), $back ) ); exit; }
        $res = rmbz_project_transfer_execute( $project_id, $target, $changes, 'forced' );
        wp_redirect( add_query_arg( 'msg', rawurlencode( $res['message'] ), $back ) ); exit;
    }

    // Com aceitação: helper partilhado (cria pedido + notifica todos os canais).
    $res = rmbz_project_transfer_create_request( $project_id, $reason, $target, $changes );
    wp_redirect( add_query_arg( 'msg', rawurlencode( (string) $res['message'] ), $back ) ); exit;
} );

// Cancelar pedido pendente/aceite. O artista que estava envolvido é avisado
// em TODOS os canais de que a transferência NÃO foi avante (o projeto fica dele).
add_action( 'admin_post_rmbz_project_transfer_cancel', function () {
    if ( ! current_user_can( 'manage_options' ) ) wp_die( 'Sem permissão.' );
    $project_id = isset( $_GET['project_id'] ) ? (int) $_GET['project_id'] : 0;
    check_admin_referer( 'rmbz_project_transfer_cancel_' . $project_id );

    rmbz_project_transfer_cancel_request( $project_id );
    wp_redirect( add_query_arg( 'msg', rawurlencode( 'Pedido de transferência cancelado — o artista foi avisado de que não foi avante.' ),
        admin_url( 'admin.php?page=rmbz-projetos&action=edit&id=' . $project_id ) ) ); exit;
} );

// Finalizar (depois de o artista aceitar): admin nomeia o novo dono.
add_action( 'admin_post_rmbz_project_transfer_finalize', function () {
    if ( ! current_user_can( 'manage_options' ) ) wp_die( 'Sem permissão.' );
    $project_id = isset( $_POST['project_id'] ) ? (int) $_POST['project_id'] : 0;
    check_admin_referer( 'rmbz_project_transfer_finalize_' . $project_id );
    $back = admin_url( 'admin.php?page=rmbz-projetos&action=edit&id=' . $project_id );

    $req = rmbz_project_transfer_request_get( $project_id );
    if ( ! $req || ( $req['status'] ?? '' ) !== 'accepted' ) {
        wp_redirect( add_query_arg( 'msg', rawurlencode( 'O artista ainda não aceitou a transferência.' ), $back ) ); exit;
    }
    $target = isset( $_POST['target_tel'] ) ? sanitize_text_field( wp_unslash( (string) $_POST['target_tel'] ) ) : '';
    if ( $target === '' ) { wp_redirect( add_query_arg( 'msg', rawurlencode( 'Escolhe o novo dono do projeto.' ), $back ) ); exit; }

    $res = rmbz_project_transfer_execute( $project_id, $target, (array) ( $req['changes'] ?? [] ), 'consent' );
    wp_redirect( add_query_arg( 'msg', rawurlencode( $res['message'] ), $back ) ); exit;
} );

/* ====================================================================== */
/* ARTISTA — aceitar / recusar (núcleo partilhado site + app)              */
/* ====================================================================== */

/**
 * [1.5.398] Núcleo da resposta do artista ao pedido de transferência.
 * Usado pelo site (admin-post) e pela API do app.
 *
 * @return array [ 'success'=>bool, 'message'=>string, 'code'=>string ]
 */
function rmbz_project_transfer_respond_core( $telemovel, $project_id, $decision, $terms_ok, $suggested_name = '', $suggested_tel = '' ) {
    global $wpdb;
    $p = $wpdb->get_row( $wpdb->prepare(
        "SELECT id, project_title, artist_telemovel FROM {$wpdb->prefix}rmbz_artist_projects WHERE id=%d AND artist_telemovel=%s",
        (int) $project_id, (string) $telemovel
    ) );
    $req = $p ? rmbz_project_transfer_request_get( (int) $project_id ) : null;
    if ( ! $p || ! $req || ( $req['status'] ?? '' ) !== 'pending' ) {
        return [ 'success' => false, 'code' => 'no_request', 'message' => 'Não há pedido de transferência pendente neste projeto.' ];
    }

    if ( $decision === 'accept' ) {
        if ( ! $terms_ok ) {
            return [ 'success' => false, 'code' => 'terms_required', 'message' => 'Para aceitar tens de concordar com os Termos da Transferência.' ];
        }
        // [1.5.398] Ao aceitar, o artista SUGERE a conta de destino (é para
        // isso que o pedido serve — a equipa pode não saber o artista certo).
        $suggested_name = sanitize_text_field( (string) $suggested_name );
        $suggested_tel  = preg_replace( '/[^0-9+]/', '', (string) $suggested_tel );
        if ( mb_strlen( $suggested_name ) < 2 || strlen( $suggested_tel ) < 7 ) {
            return [ 'success' => false, 'code' => 'suggestion_required', 'message' => 'Indica o nome do artista e o número da conta para onde o projeto deve ir.' ];
        }
        $req['status']            = 'accepted';
        $req['accepted_at']       = current_time( 'mysql' );
        $req['terms_accepted_at'] = current_time( 'mysql' );
        $req['suggested_name']    = $suggested_name;
        $req['suggested_tel']     = $suggested_tel;
        rmbz_project_transfer_request_set( (int) $project_id, $req );
        if ( function_exists( 'rmbz_admin_push' ) ) {
            rmbz_admin_push(
                '🔁 Transferência aceite',
                sprintf( 'O artista aceitou transferir "%s" (#%d) e sugeriu: %s — %s. Confirma o novo dono no admin.',
                    (string) $p->project_title, (int) $project_id, $suggested_name, $suggested_tel ),
                [ 'module' => 'projects', 'project_id' => (string) $project_id ]
            );
        }
        if ( function_exists( 'rmbz_pchat_append_change_log' ) ) {
            rmbz_pchat_append_change_log( (int) $project_id, [
                'who'  => 'artista',
                'what' => '✅ Aceitou a transferência e sugeriu o novo dono',
                'from' => '',
                'to'   => $suggested_name . ' (' . $suggested_tel . ')',
            ] );
        }
        return [ 'success' => true, 'code' => 'accepted', 'message' => 'Aceitaste a transferência e sugeriste ' . $suggested_name . '. A equipa 1MZ vai concluir o processo.' ];
    }

    rmbz_project_transfer_request_set( (int) $project_id, null );
    if ( function_exists( 'rmbz_admin_push' ) ) {
        rmbz_admin_push( '🔁 Transferência recusada', sprintf( 'O artista recusou transferir "%s" (#%d).', (string) $p->project_title, (int) $project_id ), [ 'module' => 'projects', 'project_id' => (string) $project_id ] );
    }
    if ( function_exists( 'rmbz_pchat_append_change_log' ) ) {
        rmbz_pchat_append_change_log( (int) $project_id, [ 'who' => 'artista', 'what' => '❌ Recusou o pedido de transferência', 'from' => '', 'to' => '' ] );
    }
    return [ 'success' => true, 'code' => 'rejected', 'message' => 'Recusaste a transferência. O projeto continua na tua conta.' ];
}

function rmbz_site_project_transfer_respond() {
    $redirect_url = wp_get_referer() ? wp_get_referer() : home_url( '/minha-conta/' );
    if ( ! function_exists( 'rmbz_is_user_logged_in' ) || ! rmbz_is_user_logged_in() ) { wp_redirect( home_url() ); exit; }
    if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'rmbz_transfer_respond_nonce' ) ) {
        $_SESSION['rmbz_withdrawal_notice'] = [ 'error', 'Segurança expirada. Atualize a página.' ];
        wp_redirect( $redirect_url ); exit;
    }

    $telemovel  = rmbz_get_current_user_telemovel();
    $project_id = isset( $_POST['project_id'] ) ? (int) $_POST['project_id'] : 0;
    $decision   = ( isset( $_POST['decision'] ) && $_POST['decision'] === 'accept' ) ? 'accept' : 'reject';
    $terms_ok   = ! empty( $_POST['terms_accepted'] ) && $_POST['terms_accepted'] === '1';
    $sug_name   = isset( $_POST['suggested_name'] ) ? wp_unslash( (string) $_POST['suggested_name'] ) : '';
    $sug_tel    = isset( $_POST['suggested_tel'] ) ? wp_unslash( (string) $_POST['suggested_tel'] ) : '';

    $res = rmbz_project_transfer_respond_core( (string) $telemovel, $project_id, $decision, $terms_ok, $sug_name, $sug_tel );
    $_SESSION['rmbz_withdrawal_notice'] = [ ! empty( $res['success'] ) ? 'success' : 'error', (string) $res['message'] ];
    wp_redirect( $redirect_url ); exit;
}
add_action( 'admin_post_rmbz_project_transfer_respond', 'rmbz_site_project_transfer_respond' );
add_action( 'admin_post_nopriv_rmbz_project_transfer_respond', 'rmbz_site_project_transfer_respond' );
