<?php
/**
 * [1.5.401] PARTICIPAÇÃO (FEAT) COM CONSENTIMENTO do participante.
 *
 * Quando o dono submete um projeto "Ganhar Vídeo" com participação de um
 * artista QUE TEM CONTA 1MZ, o participante é convidado em todos os canais:
 *   - ACEITA:  tem de concordar com os Termos da Participação; o dono é
 *              notificado e a produção segue normalmente.
 *   - RECUSA:  o projeto é AUTOMATICAMENTE CANCELADO — sem o participante
 *              não há como fazer o vídeo. O dono é notificado em todos os
 *              canais de que não foi possível.
 *
 * Estado guardado em extra_data['feat']['consent']:
 *   { status: pending|accepted|declined, invited_at, responded_at,
 *     terms_accepted_at }
 *
 * Também expõe a VERIFICAÇÃO DE CONTA usada pelos formulários (site + app):
 * ao digitar o número do participante aparece "✔ Artista válido — Nome".
 */

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

/* ====================================================================== */
/* TERMOS DA PARTICIPAÇÃO                                                  */
/* ====================================================================== */

/**
 * Regras que o participante aceita. Usadas no site (modal) e devolvidas
 * pela API para o app mostrar o mesmo texto.
 */
function rmbz_feat_terms() {
    return [
        [ 'O que é a participação', 'Foste declarado como participação (feat) na música deste projeto de videoclipe. Ao aceitares, o teu nome artístico fica associado ao projeto e aos créditos do vídeo.' ],
        [ 'Imagem e voz', 'Autorizas a 1MZ e o dono do projeto a usar o teu nome artístico, a tua imagem e a tua participação no videoclipe e na promoção do mesmo (plataforma, redes e YouTube).' ],
        [ 'Presença nas gravações', 'Se a tua parte exigir presença, podes ser chamado às gravações nas datas confirmadas na plataforma. Faltas sem aviso podem atrasar a produção e gerar custos para o dono do projeto.' ],
        [ 'Pagamentos', 'A participação NÃO altera pagamentos, orçamento nem o contrato do projeto na plataforma. Qualquer acordo financeiro entre ti e o dono é feito fora da plataforma e é da responsabilidade de ambos.' ],
        [ 'Propriedade do projeto', 'O projeto e o videoclipe pertencem ao dono do projeto. Aceitar não te dá acesso ao chat, ao orçamento, ao contrato nem à carteira do projeto.' ],
        [ 'Recusar cancela o projeto', 'Se recusares este convite, o projeto é automaticamente CANCELADO — sem o participante não há como produzir o vídeo. O dono será notificado.' ],
        [ 'Depois de aceitar', 'Se aceitares e depois desistires (ou impedires a publicação) sem motivo válido, a equipa pode aplicar bloqueios à tua conta e o dono pode ser compensado nos termos da plataforma.' ],
        [ 'Identidade verdadeira', 'Confirmas que és mesmo a pessoa indicada como participação. Participações falsas são removidas pela equipa e podem levar a sanções nas duas contas.' ],
        [ 'Registo da resposta', 'A tua resposta (aceitar ou recusar) fica registada no histórico do projeto com data e hora, e todas as partes são notificadas.' ],
    ];
}

/* ====================================================================== */
/* VERIFICAÇÃO DE CONTA                                                    */
/* ====================================================================== */

/**
 * Verifica se um número tem conta na plataforma.
 * @return array [ 'exists'=>bool, 'name'=>string, 'tel'=>string normalizado ]
 */
function rmbz_feat_check_account( $tel ) {
    global $wpdb;
    $tel = preg_replace( '/[^0-9+]/', '', (string) $tel );
    if ( strlen( $tel ) < 7 ) return [ 'exists' => false, 'name' => '', 'tel' => $tel ];
    $name = $wpdb->get_var( $wpdb->prepare(
        "SELECT user_nome FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel = %s", $tel
    ) );
    return [ 'exists' => $name !== null, 'name' => (string) $name, 'tel' => $tel ];
}

// AJAX (site): verificação em tempo real no formulário Ganhar Vídeo.
function rmbz_ajax_feat_check_account() {
    if ( ! function_exists( 'rmbz_is_user_logged_in' ) || ! rmbz_is_user_logged_in() ) {
        wp_send_json( [ 'success' => false, 'message' => 'Sessão inválida.' ], 401 );
    }
    if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'rmbz_feat_check' ) ) {
        wp_send_json( [ 'success' => false, 'message' => 'Segurança expirada — atualiza a página.' ], 403 );
    }
    $res = rmbz_feat_check_account( isset( $_POST['tel'] ) ? wp_unslash( (string) $_POST['tel'] ) : '' );
    // Não deixar marcar o próprio dono como participante.
    $me = function_exists( 'rmbz_get_current_user_telemovel' ) ? (string) rmbz_get_current_user_telemovel() : '';
    if ( $res['exists'] && $me !== '' && $res['tel'] === $me ) {
        wp_send_json( [ 'success' => true, 'exists' => false, 'self' => true, 'name' => '' ] );
    }
    wp_send_json( [ 'success' => true, 'exists' => (bool) $res['exists'], 'name' => $res['name'] ] );
}
add_action( 'wp_ajax_rmbz_feat_check_account', 'rmbz_ajax_feat_check_account' );
add_action( 'wp_ajax_nopriv_rmbz_feat_check_account', 'rmbz_ajax_feat_check_account' );

/* ====================================================================== */
/* ESTADO DO CONSENTIMENTO                                                 */
/* ====================================================================== */

/** Lê extra_data['feat'] (com consent) de um projeto, ou null. */
function rmbz_feat_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 ) : [];
    return ( is_array( $extra ) && ! empty( $extra['feat'] ) && is_array( $extra['feat'] ) ) ? $extra['feat'] : null;
}

/** Atualiza só a chave feat.consent no extra_data. */
function rmbz_feat_consent_set( $project_id, $consent ) {
    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 ( empty( $extra['feat'] ) || ! is_array( $extra['feat'] ) ) return false;
    if ( $consent === null ) unset( $extra['feat']['consent'] );
    else $extra['feat']['consent'] = $consent;
    return false !== $wpdb->update( $t, [ 'extra_data' => wp_json_encode( $extra ) ], [ 'id' => (int) $project_id ], [ '%s' ], [ '%d' ] );
}

/* ====================================================================== */
/* CONVITE (ao submeter o projeto)                                         */
/* ====================================================================== */

/**
 * Cria o convite de participação para um projeto acabado de submeter e
 * notifica o participante em TODOS os canais. Chamado pelo site e pela API
 * logo depois do INSERT do projeto.
 *
 * Só faz alguma coisa quando o feat tem conta 1MZ válida (≠ dono).
 */
function rmbz_feat_invite_create( $project_id ) {
    global $wpdb;
    $p = $wpdb->get_row( $wpdb->prepare(
        "SELECT id, project_title, artist_telemovel, extra_data FROM {$wpdb->prefix}rmbz_artist_projects WHERE id=%d",
        (int) $project_id
    ) );
    if ( ! $p ) return false;
    $extra = ! empty( $p->extra_data ) ? json_decode( $p->extra_data, true ) : [];
    if ( ! is_array( $extra ) || empty( $extra['feat']['has_account'] ) || empty( $extra['feat']['tel'] ) ) return false;

    $feat_tel = preg_replace( '/[^0-9+]/', '', (string) $extra['feat']['tel'] );
    if ( $feat_tel === (string) $p->artist_telemovel ) return false; // não se convida a si próprio

    $check = rmbz_feat_check_account( $feat_tel );
    if ( ! $check['exists'] ) return false; // sem conta → fica só tracking

    $owner_name = (string) $wpdb->get_var( $wpdb->prepare(
        "SELECT user_nome FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel=%s", (string) $p->artist_telemovel
    ) ) ?: 'um artista';

    rmbz_feat_consent_set( (int) $project_id, [
        'status'     => 'pending',
        'invited_at' => current_time( 'mysql' ),
    ] );

    // Notificar o participante em TODOS os canais.
    if ( function_exists( 'rmbz_notify_user' ) ) {
        rmbz_notify_user(
            $feat_tel,
            '🎤 Foste adicionado como participação',
            sprintf( '%s adicionou-te como participação no Projecto de Vídeo "%s". Abre a app ou o site para aceitar ou recusar — sem a tua resposta a produção não avança.',
                $owner_name, (string) $p->project_title ),
            'warning'
        );
    }
    if ( function_exists( 'rmbz_notify' ) ) {
        rmbz_notify( $feat_tel, 'feat_invite', [
            'nome_artista' => $check['name'] ?: 'Artista',
            'dono'         => $owner_name,
            'musica'       => (string) $p->project_title,
            'site_name'    => get_bloginfo( 'name' ),
        ] );
    }
    if ( function_exists( 'rmbz_pchat_append_change_log' ) ) {
        rmbz_pchat_append_change_log( (int) $project_id, [
            'who'  => 'sistema',
            'what' => '🎤 Convite de participação enviado',
            'from' => '',
            'to'   => ( $check['name'] ?: $feat_tel ) . ' (' . $feat_tel . ')',
        ] );
    }
    return true;
}

/**
 * Convites PENDENTES para um artista (ele é o participante).
 * @return array de [ project_id, title, owner_name, owner_tel, level, feat_name, invited_at ]
 */
function rmbz_feat_pending_for( $tel ) {
    global $wpdb;
    $tel = preg_replace( '/[^0-9+]/', '', (string) $tel );
    if ( strlen( $tel ) < 7 ) return [];
    // Pré-filtro por LIKE (rápido); confirmação exata em PHP.
    $like = '%' . $wpdb->esc_like( $tel ) . '%';
    $rows = $wpdb->get_results( $wpdb->prepare(
        "SELECT p.id, p.project_title, p.scenario_type, p.artist_telemovel, p.extra_data, w.user_nome AS owner_name
         FROM {$wpdb->prefix}rmbz_artist_projects p
         LEFT JOIN {$wpdb->prefix}rmbz_wallets w ON w.user_telemovel = p.artist_telemovel
         WHERE p.extra_data LIKE '%%\"feat\"%%' AND p.extra_data LIKE %s
           AND p.production_status NOT IN ('rejected','cancelled_no_confirmation','done')
         ORDER BY p.id DESC LIMIT 20",
        $like
    ) );
    $levels = [ 'basic' => 'Básico', 'professional' => 'Profissional', 'cinema' => 'Cinema' ];
    $out = [];
    foreach ( (array) $rows as $r ) {
        $extra = ! empty( $r->extra_data ) ? json_decode( $r->extra_data, true ) : [];
        $feat  = ( is_array( $extra ) && ! empty( $extra['feat'] ) ) ? $extra['feat'] : null;
        if ( ! $feat || preg_replace( '/[^0-9+]/', '', (string) ( $feat['tel'] ?? '' ) ) !== $tel ) continue;
        if ( ( $feat['consent']['status'] ?? '' ) !== 'pending' ) continue;
        $out[] = [
            'project_id' => (int) $r->id,
            'title'      => (string) $r->project_title,
            'owner_name' => (string) ( $r->owner_name ?: $r->artist_telemovel ),
            'level'      => $levels[ (string) $r->scenario_type ] ?? (string) $r->scenario_type,
            'feat_name'  => (string) ( $feat['name'] ?? '' ),
            'invited_at' => (string) ( $feat['consent']['invited_at'] ?? '' ),
        ];
    }
    return $out;
}

/* ====================================================================== */
/* ADMIN DEFINE A PARTICIPAÇÃO (núcleo partilhado WP admin + app admin)    */
/* ====================================================================== */

/**
 * [1.5.403] O admin define/altera/remove a participação de um projeto.
 * Dois modos (como na transferência):
 *   - 'forced'  : fica ACEITE imediatamente — o participante NÃO precisa de
 *                 aceitar (é apenas informado de que a equipa confirmou).
 *   - 'consent' : o participante recebe o CONVITE normal (termos; recusar
 *                 cancela o projeto).
 * Nome vazio = REMOVER a participação do projeto.
 *
 * @return array [ 'success'=>bool, 'message'=>string ]
 */
function rmbz_feat_admin_set( $project_id, $name, $has_account, $tel, $mode = 'consent' ) {
    global $wpdb;
    $t = $wpdb->prefix . 'rmbz_artist_projects';
    $p = $wpdb->get_row( $wpdb->prepare(
        "SELECT id, project_title, artist_telemovel, extra_data FROM {$t} WHERE id=%d", (int) $project_id
    ) );
    if ( ! $p ) return [ 'success' => false, 'message' => 'Projeto não encontrado.' ];

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

    $name = sanitize_text_field( (string) $name );
    $tel  = preg_replace( '/[^0-9+]/', '', (string) $tel );
    $mode = ( $mode === 'forced' ) ? 'forced' : 'consent';

    $who = function_exists( 'rmbz_pchat_current_admin_who' ) ? rmbz_pchat_current_admin_who() : 'admin';

    // ─── REMOVER ─────────────────────────────────────────────────────────
    if ( $name === '' ) {
        if ( empty( $extra['feat'] ) ) {
            return [ 'success' => false, 'message' => 'Este projeto não tem participação para remover.' ];
        }
        $old = (string) ( $extra['feat']['name'] ?? '' );
        unset( $extra['feat'] );
        $wpdb->update( $t, [ 'extra_data' => wp_json_encode( $extra ) ], [ 'id' => (int) $p->id ], [ '%s' ], [ '%d' ] );
        if ( function_exists( 'rmbz_pchat_append_change_log' ) ) {
            rmbz_pchat_append_change_log( (int) $p->id, [
                'who' => $who, 'what' => '🎤 Removeu a participação (feat)', 'from' => $old, 'to' => '—',
            ] );
        }
        return [ 'success' => true, 'message' => 'Participação removida do projeto.' ];
    }

    // ─── VALIDAR conta (quando tem conta 1MZ) ────────────────────────────
    $has_account = (bool) $has_account;
    $feat_display_name = $name;
    if ( $has_account ) {
        $chk = rmbz_feat_check_account( $tel );
        if ( ! $chk['exists'] ) {
            return [ 'success' => false, 'message' => 'O número da conta do participante não foi encontrado na plataforma.' ];
        }
        if ( $chk['tel'] === (string) $p->artist_telemovel ) {
            return [ 'success' => false, 'message' => 'O participante não pode ser a conta do próprio dono do projeto.' ];
        }
        $tel = $chk['tel'];
    } else {
        $tel = '';
    }

    // ─── GRAVAR a participação ───────────────────────────────────────────
    $extra['feat'] = [
        'name'        => $name,
        'has_account' => $has_account,
        'tel'         => $tel,
    ];
    if ( $has_account && $mode === 'forced' ) {
        $extra['feat']['consent'] = [
            'status'          => 'accepted',
            'forced_by_admin' => true,
            'invited_at'      => current_time( 'mysql' ),
            'responded_at'    => current_time( 'mysql' ),
        ];
    }
    $wpdb->update( $t, [ 'extra_data' => wp_json_encode( $extra ) ], [ 'id' => (int) $p->id ], [ '%s' ], [ '%d' ] );

    if ( function_exists( 'rmbz_pchat_append_change_log' ) ) {
        rmbz_pchat_append_change_log( (int) $p->id, [
            'who'  => $who,
            'what' => $has_account
                ? ( $mode === 'forced'
                    ? '🎤 Definiu a participação (FORÇADA — aceite sem confirmação do participante)'
                    : '🎤 Definiu a participação (com aceitação — convite enviado)' )
                : '🎤 Definiu a participação (sem conta 1MZ — só registo)',
            'from' => '',
            'to'   => $name . ( $tel !== '' ? ' (' . $tel . ')' : '' ),
        ] );
    }

    // ─── NOTIFICAR ───────────────────────────────────────────────────────
    if ( $has_account && $mode === 'forced' ) {
        // Participante: apenas informado (não precisa de fazer nada).
        if ( function_exists( 'rmbz_notify_user' ) ) {
            rmbz_notify_user(
                $tel,
                '🎤 A tua participação foi confirmada',
                sprintf( 'A equipa 1MZ confirmou a tua participação no Projecto de Vídeo "%s". Não precisas de fazer nada — a produção segue normalmente.', (string) $p->project_title ),
                'success'
            );
        }
        // Dono: informado no app.
        if ( function_exists( 'rmbz_notify_user' ) ) {
            rmbz_notify_user(
                (string) $p->artist_telemovel,
                '🎤 Participação confirmada pela equipa',
                sprintf( 'A equipa 1MZ definiu e confirmou a participação de %s no teu projeto "%s".', $feat_display_name, (string) $p->project_title ),
                'info'
            );
        }
        return [ 'success' => true, 'message' => sprintf( 'Participação de %s definida e ACEITE (forçada) — participante e dono informados.', $name ) ];
    }

    if ( $has_account ) {
        // Com aceitação: convite normal (todos os canais; recusar cancela).
        rmbz_feat_invite_create( (int) $p->id );
        return [ 'success' => true, 'message' => sprintf( 'Participação de %s definida — o participante recebeu o convite e tem de aceitar (se recusar, o projeto é cancelado).', $name ) ];
    }

    return [ 'success' => true, 'message' => sprintf( 'Participação de %s registada (sem conta 1MZ — apenas registo).', $name ) ];
}

// WP admin: definir/alterar/remover a participação a partir do projeto.
add_action( 'admin_post_rmbz_feat_admin_set', 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_feat_admin_set_' . $project_id );

    $remove = ! empty( $_POST['feat_remove'] );
    $res = rmbz_feat_admin_set(
        $project_id,
        $remove ? '' : ( isset( $_POST['feat_name'] ) ? wp_unslash( (string) $_POST['feat_name'] ) : '' ),
        ! empty( $_POST['feat_has_account'] ),
        isset( $_POST['feat_tel'] ) ? wp_unslash( (string) $_POST['feat_tel'] ) : '',
        isset( $_POST['feat_mode'] ) ? (string) $_POST['feat_mode'] : 'consent'
    );
    wp_redirect( add_query_arg( 'msg', rawurlencode( (string) $res['message'] ),
        admin_url( 'admin.php?page=rmbz-projetos&action=edit&id=' . $project_id ) ) );
    exit;
} );

/* ====================================================================== */
/* RESPOSTA DO PARTICIPANTE (núcleo partilhado site + app)                 */
/* ====================================================================== */

/**
 * Aceitar exige termos; recusar CANCELA o projeto e notifica o dono.
 * @return array [ 'success'=>bool, 'message'=>string, 'code'=>string ]
 */
function rmbz_feat_respond_core( $telemovel, $project_id, $decision, $terms_ok ) {
    global $wpdb;
    $tel = preg_replace( '/[^0-9+]/', '', (string) $telemovel );
    $p = $wpdb->get_row( $wpdb->prepare(
        "SELECT id, project_title, artist_telemovel, production_status, extra_data
         FROM {$wpdb->prefix}rmbz_artist_projects WHERE id=%d", (int) $project_id
    ) );
    $extra = $p && ! empty( $p->extra_data ) ? json_decode( $p->extra_data, true ) : [];
    $feat  = ( is_array( $extra ) && ! empty( $extra['feat'] ) ) ? $extra['feat'] : null;

    if ( ! $p || ! $feat
         || preg_replace( '/[^0-9+]/', '', (string) ( $feat['tel'] ?? '' ) ) !== $tel
         || ( $feat['consent']['status'] ?? '' ) !== 'pending' ) {
        return [ 'success' => false, 'code' => 'no_invite', 'message' => 'Não há convite de participação pendente para ti neste projeto.' ];
    }

    $consent    = (array) $feat['consent'];
    $owner_tel  = (string) $p->artist_telemovel;
    $owner_name = (string) $wpdb->get_var( $wpdb->prepare(
        "SELECT user_nome FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel=%s", $owner_tel
    ) ) ?: 'Artista';
    $feat_name  = (string) ( $feat['name'] ?: $tel );
    $title      = (string) $p->project_title;
    $site_name  = get_bloginfo( 'name' );

    if ( $decision === 'accept' ) {
        if ( ! $terms_ok ) {
            return [ 'success' => false, 'code' => 'terms_required', 'message' => 'Para aceitar tens de concordar com os Termos da Participação.' ];
        }
        $consent['status']            = 'accepted';
        $consent['responded_at']      = current_time( 'mysql' );
        $consent['terms_accepted_at'] = current_time( 'mysql' );
        rmbz_feat_consent_set( (int) $project_id, $consent );

        // Dono: todos os canais.
        if ( function_exists( 'rmbz_notify_user' ) ) {
            rmbz_notify_user( $owner_tel, '🎤 Participação confirmada',
                sprintf( '%s aceitou a participação no teu projeto "%s". A produção segue normalmente.', $feat_name, $title ), 'success' );
        }
        if ( function_exists( 'rmbz_notify' ) ) {
            rmbz_notify( $owner_tel, 'feat_accepted', [
                'nome_artista' => $owner_name, 'participante' => $feat_name,
                'musica' => $title, 'site_name' => $site_name,
            ] );
        }
        if ( function_exists( 'rmbz_admin_push' ) ) {
            rmbz_admin_push( '🎤 Participação aceite',
                sprintf( '%s aceitou participar em "%s" (#%d).', $feat_name, $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' => 'participante', 'what' => '✅ Aceitou o convite de participação (termos incluídos)',
                'from' => '', 'to' => $feat_name,
            ] );
        }
        return [ 'success' => true, 'code' => 'accepted', 'message' => 'Aceitaste a participação em "' . $title . '". O dono do projeto foi notificado — obrigado!' ];
    }

    // ─── RECUSA → CANCELA O PROJETO ───────────────────────────────────────
    $consent['status']       = 'declined';
    $consent['responded_at'] = current_time( 'mysql' );
    $extra['feat']['consent'] = $consent;
    $extra['admin_rejection_reason'] = sprintf(
        'O participante %s recusou a participação — sem o participante não é possível produzir o vídeo. O projeto foi cancelado automaticamente.',
        $feat_name
    );
    $extra['rejected_at'] = current_time( 'mysql' );

    $ok = $wpdb->update(
        $wpdb->prefix . 'rmbz_artist_projects',
        [ 'production_status' => 'rejected', 'extra_data' => wp_json_encode( $extra ) ],
        [ 'id' => (int) $project_id ],
        [ '%s', '%s' ], [ '%d' ]
    );
    if ( $ok === false ) {
        return [ 'success' => false, 'code' => 'db_error', 'message' => 'Falha ao cancelar o projeto: ' . $wpdb->last_error ];
    }

    // Dono: todos os canais — "não foi possível".
    if ( function_exists( 'rmbz_notify_user' ) ) {
        rmbz_notify_user( $owner_tel, '❌ Projeto cancelado — participação recusada',
            sprintf( '%s recusou a participação no projeto "%s". Sem o participante não é possível produzir o vídeo, por isso o projeto foi cancelado. Podes submeter uma nova candidatura sem essa participação.', $feat_name, $title ),
            'error' );
    }
    if ( function_exists( 'rmbz_notify' ) ) {
        rmbz_notify( $owner_tel, 'feat_declined', [
            'nome_artista' => $owner_name, 'participante' => $feat_name,
            'musica' => $title, 'site_name' => $site_name,
        ] );
    }
    if ( function_exists( 'rmbz_admin_push' ) ) {
        rmbz_admin_push( '❌ Participação recusada — projeto cancelado',
            sprintf( '%s recusou participar em "%s" (#%d). O projeto foi cancelado automaticamente.', $feat_name, $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' => 'participante', 'what' => '❌ Recusou o convite de participação — projeto cancelado automaticamente',
            'from' => '', 'to' => $feat_name,
        ] );
    }
    return [ 'success' => true, 'code' => 'declined', 'message' => 'Recusaste a participação. O projeto "' . $title . '" foi cancelado e o dono foi avisado.' ];
}

/* ====================================================================== */
/* SITE — responder (admin-post)                                           */
/* ====================================================================== */

function rmbz_site_feat_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_feat_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';

    $res = rmbz_feat_respond_core( (string) $telemovel, $project_id, $decision, $terms_ok );
    $_SESSION['rmbz_withdrawal_notice'] = [ ! empty( $res['success'] ) ? 'success' : 'error', (string) $res['message'] ];
    wp_redirect( $redirect_url ); exit;
}
add_action( 'admin_post_rmbz_feat_respond', 'rmbz_site_feat_respond' );
add_action( 'admin_post_nopriv_rmbz_feat_respond', 'rmbz_site_feat_respond' );
