<?php
/**
 * Programa de Parceria da 1MZ For Artists.
 * A publicacao no site e independente; monetizacao e controlo do painel exigem
 * uma candidatura aprovada para o Art Track.
 */

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

/** Art Track associado a uma conta 1MZ. */
function rmbz_partnership_track_for_phone( $telemovel ) {
    $user_id = function_exists( 'rmbz_artists_ensure_wp_user' )
        ? rmbz_artists_ensure_wp_user( (string) $telemovel )
        : 0;
    return $user_id && function_exists( 'rmbz_artists_get_art_track_for_user' )
        ? rmbz_artists_get_art_track_for_user( $user_id )
        : 0;
}

/** Estado canonico da candidatura. */
function rmbz_partnership_status( $telemovel ) {
    $track_id = rmbz_partnership_track_for_phone( $telemovel );
    if ( ! $track_id ) return '';
    if ( function_exists( 'rmbz_partnership_application_get' ) ) {
        $application = rmbz_partnership_application_get( $track_id );
        if ( $application ) return $application->status === 'none' ? '' : sanitize_key( $application->status );
    }
    return sanitize_key( (string) get_post_meta( $track_id, '_imz_partnership_status', true ) );
}

function rmbz_partnership_has_access( $telemovel ) {
    return rmbz_partnership_status( $telemovel ) === 'approved';
}

/** Requisitos objetivos para enviar uma candidatura. */
function rmbz_partnership_eligibility( $telemovel, $track_id = 0 ) {
    global $wpdb;

    $track_id = $track_id ? absint( $track_id ) : rmbz_partnership_track_for_phone( $telemovel );
    $wallet = function_exists( 'rmbz_artists_find_wallet_by_identity' )
        ? rmbz_artists_find_wallet_by_identity( (string) $telemovel )
        : null;
    $real_email = $wallet ? sanitize_email( (string) $wallet->user_email ) : '';
    if ( $real_email !== '' && substr( strtolower( $real_email ), -10 ) === '@1mz.local' ) {
        $real_email = '';
    }

    $published_count = 0;
    if ( $track_id && function_exists( 'rmbz_art_track_published_count' ) && rmbz_art_track_is_valid( $track_id, true ) ) {
        $published_count = rmbz_art_track_published_count( $track_id );
    } elseif ( $track_id ) {
        $published_ids = get_posts( [ 'post_type'=>'post', 'post_status'=>'publish', 'posts_per_page'=>-1, 'fields'=>'ids', 'meta_key'=>'_imz_artista_id', 'meta_value'=>$track_id, 'no_found_rows'=>true ] );
        foreach ( $published_ids as $published_id ) if ( ! function_exists( 'rmbz_site_publication_is_visible' ) || rmbz_site_publication_is_visible( $published_id ) ) $published_count++;
    }

    $requirements = [
        'account' => [
            'label' => 'Conta 1MZ ativa e sem bloqueio',
            'detail' => 'A conta deve estar válida para receber pagamentos e gerir conteúdos.',
            'met' => (bool) ( $wallet && empty( $wallet->is_banned ) ),
            'icon' => 'verified_user',
        ],
        'subscription' => [
            'label' => 'Subscrição VIP ativa',
            'detail' => 'É aceite uma subscrição ativa de qualquer pacote disponível na 1MZ.',
            'met' => function_exists( 'rmbz_user_has_active_subscription' )
                && rmbz_user_has_active_subscription( (string) $telemovel ),
            'icon' => 'workspace_premium',
        ],
        'email' => [
            'label' => 'Email real associado à conta',
            'detail' => 'Usamos este endereço para contratos e decisões do programa.',
            'met' => $real_email !== '',
            'icon' => 'alternate_email',
        ],
        'track' => [
            'label' => 'Art Track ligado à conta',
            'detail' => 'O Art Track confirma a identidade e a propriedade do catálogo.',
            'met' => (bool) ( $track_id && ( ! function_exists( 'rmbz_art_track_is_valid' ) || rmbz_art_track_is_valid( $track_id ) ) ),
            'icon' => 'album',
        ],
        'publication' => [
            'label' => 'Pelo menos 3 músicas publicadas pela 1MZ',
            'detail' => $published_count >= 3
                ? $published_count . ' músicas principais publicadas e validadas.'
                : $published_count . ' de 3 músicas principais publicadas. Faltam ' . ( 3 - $published_count ) . '.',
            'met' => $published_count >= 3,
            'icon' => 'library_music',
        ],
    ];

    $met_count = count( array_filter( $requirements, static fn( $item ) => ! empty( $item['met'] ) ) );
    return [
        'eligible'        => $met_count === count( $requirements ),
        'met_count'       => $met_count,
        'total'           => count( $requirements ),
        'requirements'    => $requirements,
        'track_id'        => $track_id,
        'published_count' => $published_count,
        'wallet'          => $wallet,
    ];
}

/** Notifica o artista sobre uma decisao do programa. */
function rmbz_partnership_notify( $telemovel, $status, $reason = '' ) {
    if ( ! function_exists( 'rmbz_notify_create' ) ) {
        return;
    }
    $map = [
        'pending'   => [ 'info', 'Candidatura recebida', 'A equipa vai analisar a tua entrada no Programa de Parceria.' ],
        'approved'  => [ 'success', 'Programa de Parceria aprovado', 'O painel Músicas & Ganhos já está disponível na tua conta.' ],
        'rejected'  => [ 'warning', 'Candidatura ao programa não aprovada', $reason ?: 'Consulta o motivo no painel e volta a candidatar-te quando cumprires os requisitos.' ],
        'suspended' => [ 'danger', 'Acesso ao Programa de Parceria suspenso', $reason ?: 'Contacta o suporte para obter mais informações.' ],
    ];
    if ( empty( $map[ $status ] ) ) {
        return;
    }
    rmbz_notify_create( [
        'type'             => 'partnership_status_change',
        'severity'         => $map[ $status ][0],
        'title'            => $map[ $status ][1],
        'body'             => $map[ $status ][2],
        'action_url'       => add_query_arg( 'sect', 'musicas', home_url( '/minha-conta/' ) ),
        'action_label'     => 'Ver programa',
        'target_telemovel' => (string) $telemovel,
        'dedup_key'        => 'partnership_' . preg_replace( '/\D+/', '', (string) $telemovel ) . '_' . $status . '_' . gmdate( 'YmdHi' ),
        'created_by'       => 'partnership_program',
    ] );
}

/** Recebe a candidatura do artista. */
function rmbz_partnership_apply() {
    if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'rmbz_partnership_apply' ) ) {
        wp_die( 'Falha de segurança.' );
    }
    if ( ! function_exists( 'rmbz_is_user_logged_in' ) || ! rmbz_is_user_logged_in() ) {
        wp_die( 'Sessão expirada.' );
    }

    $telemovel = (string) rmbz_get_current_user_telemovel();
    $eligibility = rmbz_partnership_eligibility( $telemovel );
    $redirect = add_query_arg( 'sect', 'musicas', home_url( '/minha-conta/' ) );
    if ( ! $eligibility['eligible'] ) {
        wp_safe_redirect( add_query_arg( 'partner_notice', 'requirements', $redirect ) );
        exit;
    }
    if ( empty( $_POST['rights_confirmed'] ) || empty( $_POST['program_terms'] ) ) {
        wp_safe_redirect( add_query_arg( 'partner_notice', 'declarations', $redirect ) );
        exit;
    }

    $track_id = absint( $eligibility['track_id'] );
    $application = function_exists( 'rmbz_partnership_application_get' ) ? rmbz_partnership_application_get( $track_id ) : null;
    $current_status = $application ? sanitize_key( $application->status ) : sanitize_key( (string) get_post_meta( $track_id, '_imz_partnership_status', true ) );
    if ( in_array( $current_status, [ 'pending', 'approved' ], true ) ) { wp_safe_redirect( $redirect ); exit; }
    $now = current_time( 'mysql' );
    if ( function_exists( 'rmbz_partnership_application_save' ) ) {
        rmbz_partnership_application_save( $track_id, [ 'account_phone'=>$telemovel, 'status'=>'pending', 'rights_confirmed'=>1, 'terms_accepted'=>1, 'applied_at'=>$now, 'decision_reason'=>'', 'security_snapshot'=>[ 'requirements'=>$eligibility['met_count'].'/'.$eligibility['total'], 'published_count'=>$eligibility['published_count'], 'subscription_active'=>true ] ] );
        rmbz_partnership_audit_log( $track_id, 'application_submitted', $current_status, 'pending', 'Candidatura submetida pelo artista.', [ 'requirements'=>$eligibility['met_count'].'/'.$eligibility['total'] ] );
    }
    $native_track = function_exists( 'rmbz_art_track_get' ) ? rmbz_art_track_get( $track_id ) : null;
    if ( $native_track && $native_track->legacy_post_id ) {
        update_post_meta( (int)$native_track->legacy_post_id, '_imz_partnership_status', 'pending' );
        update_post_meta( (int)$native_track->legacy_post_id, '_imz_partnership_applied_at', $now );
        update_post_meta( (int)$native_track->legacy_post_id, '_imz_partnership_rights_confirmed', 1 );
        update_post_meta( (int)$native_track->legacy_post_id, '_imz_partnership_terms_accepted', 1 );
    }
    rmbz_partnership_notify( $telemovel, 'pending' );

    $admin_email = get_option( 'admin_email' );
    if ( is_email( $admin_email ) ) {
        wp_mail(
            $admin_email,
            'Nova candidatura ao Programa de Parceria',
            'O Art Track "' . ( function_exists( 'rmbz_art_track_name' ) ? rmbz_art_track_name( $track_id ) : get_the_title( $track_id ) ) . '" enviou uma candidatura. Analisa em 1MZ Admin > Programa de Parceria.'
        );
    }

    wp_safe_redirect( add_query_arg( 'partner_notice', 'submitted', $redirect ) );
    exit;
}
add_action( 'admin_post_rmbz_partnership_apply', 'rmbz_partnership_apply' );
add_action( 'admin_post_nopriv_rmbz_partnership_apply', 'rmbz_partnership_apply' );

/** Bloqueia também os handlers internos do painel, não apenas a interface. */
function rmbz_partnership_guard_artist_ajax() {
    if ( ! wp_doing_ajax() || current_user_can( 'manage_options' ) ) {
        return;
    }
    $action = sanitize_key( wp_unslash( $_REQUEST['action'] ?? '' ) );
    $protected_actions = [
        'imz_upload_claim_document',
        'imz_artist_contacted_buyer',
        'imz_artist_cancel_buyer',
        'imz_submit_takedown',
        'imz_save_music_settings',
        'imz_request_payout',
        'imz_save_payout_method',
        'imz_claim_music',
        'imz_get_dashboard_chart_data',
    ];
    if ( ! in_array( $action, $protected_actions, true ) ) {
        return;
    }
    $phone = function_exists( 'rmbz_get_current_user_telemovel' ) ? (string) rmbz_get_current_user_telemovel() : '';
    if ( $phone === '' || ! rmbz_partnership_has_access( $phone ) ) {
        wp_send_json_error( [ 'message' => 'Esta função requer aprovação no Programa de Parceria 1MZ For Artists.' ], 403 );
    }
}
add_action( 'init', 'rmbz_partnership_guard_artist_ajax', 4 );

/** Conteudo do bloqueio/candidatura no painel do artista. */
function rmbz_render_partnership_program( $telemovel ) {
    $eligibility = rmbz_partnership_eligibility( $telemovel );
    $track_id = absint( $eligibility['track_id'] );
    $application = $track_id && function_exists( 'rmbz_partnership_application_get' ) ? rmbz_partnership_application_get( $track_id ) : null;
    $status = $application ? ( $application->status === 'none' ? '' : sanitize_key( $application->status ) ) : ( $track_id ? sanitize_key( (string) get_post_meta( $track_id, '_imz_partnership_status', true ) ) : '' );
    $reason = $application ? trim( (string) $application->decision_reason ) : ( $track_id ? trim( (string) get_post_meta( $track_id, '_imz_partnership_rejection_reason', true ) ) : '' );
    $notice = sanitize_key( wp_unslash( $_GET['partner_notice'] ?? '' ) );
    $status_meta = [
        'pending'   => [ 'pending_actions', 'Em análise', 'A equipa está a verificar o catálogo, a conta e os direitos declarados.', 'pending' ],
        'rejected'  => [ 'assignment_late', 'Ainda não aprovado', $reason ?: 'Corrige os pontos indicados e envia uma nova candidatura.', 'danger' ],
        'suspended' => [ 'pause_circle', 'Acesso suspenso', $reason ?: 'Contacta o suporte para rever o acesso ao programa.', 'danger' ],
    ];

    ob_start();
    ?>
    <style>
    .partner-shell{display:grid;gap:18px;color:var(--text,#1d1b20)}
    .partner-hero{position:relative;overflow:hidden;display:grid;grid-template-columns:minmax(0,1.35fr) minmax(280px,.65fr);gap:22px;padding:30px;border:1px solid var(--border,#ded8ca);border-radius:28px;background:linear-gradient(135deg,#172d26 0%,#244c3b 62%,#ad8500 160%);color:#fff;box-shadow:0 18px 40px rgba(23,45,38,.13)}
    .partner-hero:after{content:"";position:absolute;width:250px;height:250px;border-radius:50%;right:-90px;top:-120px;background:rgba(255,191,0,.17)}
    .partner-eyebrow{display:flex;align-items:center;gap:8px;font-size:11px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:#ffd75d}.partner-eyebrow .ms{font-size:19px}
    .partner-title{max-width:680px;margin:12px 0 9px;font:750 clamp(25px,3vw,39px)/1.08 'Bricolage Grotesque',system-ui,sans-serif}.partner-copy{max-width:690px;margin:0;color:rgba(255,255,255,.76);font-size:13.5px;line-height:1.65}
    .partner-benefits{position:relative;z-index:1;display:grid;gap:9px;align-content:center}.partner-shell .partner-benefit{display:flex!important;width:100%;gap:11px;align-items:center;padding:12px;border:1px solid rgba(255,255,255,.14);border-radius:16px;background:rgba(255,255,255,.08);backdrop-filter:blur(8px);box-sizing:border-box}.partner-shell .partner-benefit>.ms{width:40px;height:40px;display:flex!important;align-items:center;justify-content:center;flex:0 0 40px;line-height:1!important;border-radius:13px;background:rgba(255,199,0,.16);color:#ffd75d}.partner-shell .partner-benefit>div{min-width:0;flex:1 1 auto}.partner-benefit strong{display:block;font-size:12.5px}.partner-benefit small{display:block;margin-top:2px;color:rgba(255,255,255,.65);font-size:10.5px}
    .partner-card{padding:25px;border:1px solid var(--border,#ded8ca);border-radius:24px;background:var(--surface,#fff)}.partner-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:18px}.partner-head h3{margin:0;font-size:18px}.partner-progress{display:inline-flex;align-items:center;justify-content:center;min-width:68px;min-height:32px;padding:0 12px;border-radius:999px;background:var(--brand-soft,#fff1c8);color:var(--brand-ink,#8b6800);font:750 11.5px 'JetBrains Mono',monospace;white-space:nowrap}
    .partner-shell .partner-reqs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.partner-shell .partner-req{display:flex!important;width:100%;gap:13px;align-items:center;min-height:86px;padding:14px 16px;border:1px solid var(--border,#ded8ca);border-radius:18px;background:var(--elev,#f5f1e8);box-sizing:border-box}.partner-shell .partner-req:last-child:nth-child(odd){grid-column:1/-1}.partner-shell .partner-req-icon{width:46px;height:46px;display:flex!important;align-items:center;justify-content:center;flex:0 0 46px;line-height:1!important;border-radius:14px;background:var(--surface,#fff);color:var(--muted,#7a7467)}.partner-shell .partner-req-copy{min-width:0;flex:1 1 auto;align-self:center}.partner-shell .partner-req.met{border-color:rgba(0,151,105,.24);background:var(--success-soft,#ddf5ec)}.partner-shell .partner-req.met .partner-req-icon,.partner-shell .partner-req.met .partner-check{color:var(--success,#008b62)}.partner-shell .partner-req strong{display:block;font-size:12.5px;line-height:1.35}.partner-shell .partner-req small{display:block;margin-top:4px;color:var(--muted,#7a7467);font-size:10.5px;line-height:1.45}.partner-shell .partner-check{width:26px;height:26px;display:flex!important;align-items:center;justify-content:center;align-self:center;flex:0 0 26px;margin-left:auto;line-height:1!important;font-size:20px;color:var(--muted,#7a7467)}
    .partner-shell .partner-state{display:flex!important;width:100%;gap:14px;align-items:center;padding:16px 18px;border:1px solid color-mix(in srgb,currentColor 16%,transparent);border-radius:18px;background:var(--info-soft,#e7efff);color:var(--info,#275dad);margin-top:16px;box-sizing:border-box}.partner-shell .partner-state.danger{background:var(--danger-soft,#fde8e7);color:var(--danger,#c93632)}.partner-shell .partner-state.pending{background:var(--brand-soft,#fff1c8);color:var(--brand-ink,#8b6800)}.partner-shell .partner-state>.ms{width:50px;height:50px;display:flex!important;align-items:center;justify-content:center;flex:0 0 50px;line-height:1!important;border:1px solid color-mix(in srgb,currentColor 14%,transparent);border-radius:16px;background:color-mix(in srgb,currentColor 8%,var(--surface,#fff));font-size:26px;font-variation-settings:'FILL' 0,'wght' 500,'GRAD' 0,'opsz' 24}.partner-shell .partner-state>div{min-width:0;flex:1 1 auto}.partner-state h4{margin:0;font-size:14px}.partner-state p{margin:4px 0 0;color:inherit;opacity:.82;font-size:11.5px;line-height:1.5}
    .partner-shell .partner-declarations-head{display:flex!important;align-items:center;gap:11px;margin-top:20px;padding-top:18px;border-top:1px solid var(--border,#ded8ca)}.partner-shell .partner-declarations-head>.ms{width:38px;height:38px;display:flex!important;align-items:center;justify-content:center;flex:0 0 38px;line-height:1!important;border-radius:12px;background:var(--brand-soft,#fff1c8);color:var(--brand-ink,#8b6800)}.partner-shell .partner-declarations-head>div{min-width:0;flex:1 1 auto}.partner-declarations-head strong{display:block;font-size:13px}.partner-declarations-head small{display:block;margin-top:2px;color:var(--muted,#7a7467);font-size:10.5px}.partner-form{display:grid;gap:12px;margin-top:12px}.partner-confirm{display:grid;grid-template-columns:22px minmax(0,1fr);gap:11px;align-items:center;min-height:54px;padding:12px 15px;border:1px solid var(--border,#ded8ca);border-radius:16px;background:var(--elev,#f5f1e8);font-size:11.5px;line-height:1.5;box-sizing:border-box}.partner-confirm input{width:18px;height:18px;margin:0;accent-color:#f5b900}.partner-form-actions{display:flex;justify-content:flex-end;padding-top:2px}.partner-submit{min-height:47px;display:inline-flex;align-items:center;justify-content:center;gap:9px;padding:0 22px;border:0;border-radius:999px;background:#f5b900;color:#17130a;font-weight:800;cursor:pointer}.partner-submit:disabled{opacity:.45;cursor:not-allowed}.partner-note{padding:12px 14px;border-radius:14px;background:var(--success-soft,#ddf5ec);color:var(--success,#008b62);font-size:12px;font-weight:700}
    @media(max-width:820px){.partner-hero{grid-template-columns:1fr;padding:22px}.partner-benefits,.partner-shell .partner-reqs{grid-template-columns:1fr}.partner-shell .partner-req:last-child:nth-child(odd){grid-column:auto}}@media(max-width:520px){.partner-card{padding:16px}.partner-head{align-items:flex-start}.partner-shell .partner-req{min-height:80px;padding:12px;gap:11px}.partner-shell .partner-req-icon{width:42px;height:42px;flex-basis:42px}.partner-shell .partner-check{width:24px;height:24px;flex-basis:24px}.partner-shell .partner-state{padding:14px;gap:12px}.partner-shell .partner-state>.ms{width:46px;height:46px;flex-basis:46px;border-radius:14px}.partner-form-actions,.partner-submit{width:100%}}
    </style>
    <div class="partner-shell">
        <?php if ( $notice === 'submitted' ) : ?><div class="partner-note">Candidatura enviada. Vais receber uma notificação quando a equipa concluir a análise.</div><?php endif; ?>
        <?php if ( $notice === 'requirements' ) : ?><div class="partner-state danger"><span class="ms">error</span><div><h4>A candidatura ainda não pode ser enviada</h4><p>Conclui todos os requisitos automáticos apresentados abaixo.</p></div></div><?php endif; ?>
        <?php if ( $notice === 'declarations' ) : ?><div class="partner-state danger"><span class="ms">gavel</span><div><h4>Confirma as declarações</h4><p>As duas confirmações são obrigatórias para proteger os direitos da obra.</p></div></div><?php endif; ?>
        <section class="partner-hero">
            <div>
                <div class="partner-eyebrow"><span class="ms">handshake</span>Programa de Parceria 1MZ For Artists</div>
                <h2 class="partner-title">Transforma o teu catálogo publicado num espaço profissional de gestão e ganhos.</h2>
                <p class="partner-copy">Publicar uma música no site continua disponível através dos teus envios. O Programa de Parceria é a etapa adicional que desbloqueia o controlo das faixas, estatísticas, monetização e pagamentos no painel Músicas & Ganhos.</p>
            </div>
            <div class="partner-benefits">
                <div class="partner-benefit"><span class="ms">tune</span><div><strong>Controlo das músicas</strong><small>Gere as faixas principais ligadas ao teu Art Track.</small></div></div>
                <div class="partner-benefit"><span class="ms">monitoring</span><div><strong>Desempenho transparente</strong><small>Acompanha reproduções, downloads e atividade.</small></div></div>
                <div class="partner-benefit"><span class="ms">payments</span><div><strong>Ganhos e pagamentos</strong><small>Recebe valores elegíveis conforme as regras do programa.</small></div></div>
            </div>
        </section>
        <section class="partner-card">
            <div class="partner-head"><div><h3>Requisitos para candidatura</h3><p style="margin:4px 0 0;color:var(--muted);font-size:11px;">A verificação é feita com os dados reais da tua conta.</p></div><span class="partner-progress"><?php echo (int) $eligibility['met_count']; ?> de <?php echo (int) $eligibility['total']; ?></span></div>
            <div class="partner-reqs">
                <?php foreach ( $eligibility['requirements'] as $requirement ) : ?>
                    <div class="partner-req<?php echo ! empty( $requirement['met'] ) ? ' met' : ''; ?>">
                        <span class="ms partner-req-icon"><?php echo esc_html( $requirement['icon'] ); ?></span>
                        <div class="partner-req-copy"><strong><?php echo esc_html( $requirement['label'] ); ?></strong><small><?php echo esc_html( $requirement['detail'] ); ?></small></div>
                        <span class="ms partner-check"><?php echo ! empty( $requirement['met'] ) ? 'check_circle' : 'radio_button_unchecked'; ?></span>
                    </div>
                <?php endforeach; ?>
            </div>

            <?php if ( isset( $status_meta[ $status ] ) ) : $state = $status_meta[ $status ]; ?>
                <div class="partner-state <?php echo esc_attr( $state[3] ); ?>"><span class="ms"><?php echo esc_html( $state[0] ); ?></span><div><h4><?php echo esc_html( $state[1] ); ?></h4><p><?php echo esc_html( $state[2] ); ?></p></div></div>
            <?php endif; ?>

            <?php if ( ! in_array( $status, [ 'pending', 'suspended' ], true ) ) : ?>
                <div class="partner-declarations-head"><span class="ms">contract</span><div><strong>Declarações obrigatórias</strong><small>Confirma a titularidade das obras e aceita as regras antes de enviar.</small></div></div>
                <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" class="partner-form">
                    <input type="hidden" name="action" value="rmbz_partnership_apply">
                    <?php wp_nonce_field( 'rmbz_partnership_apply' ); ?>
                    <label class="partner-confirm"><input type="checkbox" name="rights_confirmed" value="1" required><span>Confirmo que sou titular ou representante autorizado das músicas ligadas ao meu Art Track e que não estou a usar conteúdo de terceiros sem autorização.</span></label>
                    <label class="partner-confirm"><input type="checkbox" name="program_terms" value="1" required><span>Aceito a análise da 1MZ, as regras de monetização, os controlos antifraude e a suspensão do programa em caso de informação ou atividade inválida.</span></label>
                    <div class="partner-form-actions"><button type="submit" class="partner-submit" <?php disabled( ! $eligibility['eligible'] ); ?>><span class="ms">send</span><?php echo $status === 'rejected' ? 'Enviar nova candidatura' : 'Candidatar ao programa'; ?></button></div>
                </form>
            <?php endif; ?>
        </section>
    </div>
    <?php
    return ob_get_clean();
}

/** Menu separado dentro do 1MZ Admin. */
function rmbz_partnership_admin_menu_legacy() {
    $pending = 0;
    $ids = get_posts( [
        'post_type'      => 'imz_artista',
        'post_status'    => [ 'publish', 'draft', 'pending', 'private' ],
        'posts_per_page' => -1,
        'fields'         => 'ids',
        'meta_key'       => '_imz_partnership_status',
        'meta_value'     => 'pending',
        'no_found_rows'  => true,
    ] );
    $pending = count( $ids );
    $label = 'Programa de Parceria' . ( $pending ? ' <span class="awaiting-mod count-' . $pending . '"><span class="pending-count">' . $pending . '</span></span>' : '' );
    add_submenu_page(
        'edit.php?post_type=impulsionamento',
        'Programa de Parceria',
        $label,
        'manage_options',
        'imz-partnership-program',
        'rmbz_partnership_admin_page'
    );
}
add_action( 'admin_menu', 'rmbz_partnership_admin_menu', 35 );

function rmbz_partnership_admin_status_label( $status ) {
    $labels = [
        ''          => [ 'Sem candidatura', 'neutral' ],
        'none'      => [ 'Sem candidatura', 'neutral' ],
        'pending'   => [ 'Em análise', 'pending' ],
        'approved'  => [ 'Parceiro ativo', 'approved' ],
        'rejected'  => [ 'Não aprovado', 'rejected' ],
        'suspended' => [ 'Suspenso', 'suspended' ],
    ];
    return $labels[ $status ] ?? $labels[''];
}

/** Lista e decisao administrativa das candidaturas. */
function rmbz_partnership_admin_page_legacy() {
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die( 'Sem permissão.' );
    }
    $tracks = get_posts( [
        'post_type'      => 'imz_artista',
        'post_status'    => [ 'publish', 'draft', 'pending', 'private' ],
        'posts_per_page' => -1,
        'orderby'        => 'modified',
        'order'          => 'DESC',
    ] );
    $filter = sanitize_key( wp_unslash( $_GET['partner_status'] ?? 'all' ) );
    if ( ! in_array( $filter, [ 'all', 'none', 'pending', 'approved', 'rejected', 'suspended' ], true ) ) $filter = 'all';
    $notice = sanitize_key( wp_unslash( $_GET['partner_admin_notice'] ?? '' ) );
    ?>
    <div class="wrap rmbz-partner-admin">
        <style>
        .rmbz-partner-admin{max-width:1280px}.rmbz-partner-admin h1{font-size:28px;margin-bottom:5px}.rmbz-pa-hero{display:flex;align-items:center;justify-content:space-between;gap:20px;margin:18px 0;padding:22px;border-radius:18px;background:linear-gradient(135deg,#17342b,#265f49);color:#fff}.rmbz-pa-hero p{margin:5px 0 0;color:rgba(255,255,255,.72)}.rmbz-pa-rules{display:flex;gap:8px;flex-wrap:wrap}.rmbz-pa-rules span{padding:7px 10px;border-radius:999px;background:rgba(255,255,255,.11);font-size:11px;font-weight:700}.rmbz-pa-filters{display:flex;gap:7px;flex-wrap:wrap;margin:16px 0}.rmbz-pa-filters a{padding:8px 12px;border:1px solid #dcdcde;border-radius:999px;background:#fff;text-decoration:none;color:#2c3338;font-weight:600}.rmbz-pa-filters a.active{background:#1d342c;color:#fff;border-color:#1d342c}.rmbz-pa-list{display:grid;gap:12px}.rmbz-pa-row{display:grid;grid-template-columns:minmax(220px,1fr) 150px 180px minmax(300px,1.2fr);gap:15px;align-items:center;padding:16px;border:1px solid #dcdcde;border-radius:16px;background:#fff;box-shadow:0 5px 16px rgba(0,0,0,.035)}.rmbz-pa-name{font-size:15px;font-weight:750}.rmbz-pa-meta{margin-top:4px;color:#646970;font-size:11px}.rmbz-pa-status{display:inline-flex;padding:6px 9px;border-radius:999px;font-size:11px;font-weight:750;background:#f0f0f1}.rmbz-pa-status.pending{background:#fff4ce;color:#7a5900}.rmbz-pa-status.approved{background:#dff5eb;color:#006b4c}.rmbz-pa-status.rejected,.rmbz-pa-status.suspended{background:#fbe5e5;color:#a4262c}.rmbz-pa-check{font-size:11px;line-height:1.5}.rmbz-pa-actions{display:grid;grid-template-columns:1fr auto auto;gap:7px}.rmbz-pa-actions textarea{grid-column:1/-1;min-height:48px;width:100%}.rmbz-pa-actions button{border:0;border-radius:9px;padding:8px 10px;font-weight:700;cursor:pointer}.rmbz-pa-actions .approve{background:#087f5b;color:#fff}.rmbz-pa-actions .reject{background:#fff0f0;color:#b4232b}.rmbz-pa-actions .suspend{background:#2c3338;color:#fff}@media(max-width:1050px){.rmbz-pa-row{grid-template-columns:1fr 1fr}.rmbz-pa-actions{grid-column:1/-1}}@media(max-width:650px){.rmbz-pa-hero,.rmbz-pa-row{display:grid;grid-template-columns:1fr}.rmbz-pa-actions{grid-column:auto}}
        </style>
        <h1>Programa de Parceria</h1>
        <p>Analisa quem pode aceder ao painel Músicas &amp; Ganhos. Publicar no site não concede monetização automaticamente.</p>
        <?php if ( $notice === 'updated' ) : ?><div class="notice notice-success is-dismissible"><p>Decisão guardada e artista notificado.</p></div><?php endif; ?>
        <?php if ( $notice === 'requirements' ) : ?><div class="notice notice-error is-dismissible"><p>Este Art Track ainda não cumpre os requisitos automáticos para aprovação.</p></div><?php endif; ?>
        <div class="rmbz-pa-hero"><div><strong style="font-size:17px;">Critérios atuais</strong><p>A aprovação é sempre manual, mesmo quando todos os critérios estão concluídos.</p></div><div class="rmbz-pa-rules"><span>Conta ativa</span><span>Subscrição VIP ativa</span><span>Email real</span><span>Art Track ligado</span><span>3 músicas publicadas</span><span>Direitos declarados</span></div></div>
        <div class="rmbz-pa-filters">
            <?php foreach ( [ 'all' => 'Todos', 'pending' => 'Em análise', 'approved' => 'Ativos', 'rejected' => 'Não aprovados', 'suspended' => 'Suspensos', 'none' => 'Sem candidatura' ] as $key => $text ) : ?>
                <a class="<?php echo $filter === $key ? 'active' : ''; ?>" href="<?php echo esc_url( add_query_arg( [ 'post_type' => 'impulsionamento', 'page' => 'imz-partnership-program', 'partner_status' => $key ], admin_url( 'edit.php' ) ) ); ?>"><?php echo esc_html( $text ); ?></a>
            <?php endforeach; ?>
        </div>
        <div class="rmbz-pa-list">
        <?php foreach ( $tracks as $track ) :
            $status = sanitize_key( (string) get_post_meta( $track->ID, '_imz_partnership_status', true ) );
            if ( $filter !== 'all' && ( $filter === 'none' ? $status !== '' : $status !== $filter ) ) continue;
            $phone = (string) get_post_meta( $track->ID, '_imz_artista_account_phone', true );
            $elig = rmbz_partnership_eligibility( $phone, $track->ID );
            $status_label = rmbz_partnership_admin_status_label( $status );
            $applied_at = (string) get_post_meta( $track->ID, '_imz_partnership_applied_at', true );
            ?>
            <?php $rights_ok = (bool) get_post_meta( $track->ID, '_imz_partnership_rights_confirmed', true ) && (bool) get_post_meta( $track->ID, '_imz_partnership_terms_accepted', true ); ?>
            <article class="rmbz-pa-row">
                <div><div class="rmbz-pa-name"><?php echo esc_html( get_the_title( $track ) ); ?></div><div class="rmbz-pa-meta"><?php echo esc_html( $phone ?: 'Conta ainda não ligada' ); ?><?php echo $applied_at ? ' · Candidatura: ' . esc_html( date_i18n( 'd/m/Y H:i', strtotime( $applied_at ) ) ) : ''; ?></div></div>
                <div><span class="rmbz-pa-status <?php echo esc_attr( $status_label[1] ); ?>"><?php echo esc_html( $status_label[0] ); ?></span></div>
                <div class="rmbz-pa-check"><strong><?php echo (int) $elig['met_count']; ?>/<?php echo (int) $elig['total']; ?> requisitos</strong><br><?php echo min( 3, (int) $elig['published_count'] ); ?> de 3 músicas publicadas<br>Declarações: <?php echo $rights_ok ? 'confirmadas' : 'em falta'; ?></div>
                <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" class="rmbz-pa-actions">
                    <input type="hidden" name="action" value="rmbz_partnership_review"><input type="hidden" name="track_id" value="<?php echo (int) $track->ID; ?>"><?php wp_nonce_field( 'rmbz_partnership_review_' . $track->ID ); ?>
                    <textarea name="reason" placeholder="Motivo para não aprovar ou suspender"></textarea>
                    <button class="approve" name="decision" value="approved">Aprovar</button>
                    <button class="reject" name="decision" value="rejected">Não aprovar</button>
                    <button class="suspend" name="decision" value="suspended">Suspender</button>
                </form>
            </article>
        <?php endforeach; ?>
        </div>
    </div>
    <?php
}

/** Guarda a decisao administrativa. */
function rmbz_partnership_review_legacy() {
    $track_id = absint( $_POST['track_id'] ?? 0 );
    if ( ! $track_id || get_post_type( $track_id ) !== 'imz_artista' ) wp_die( 'Art Track inválido.' );
    if ( ! current_user_can( 'manage_options' ) ) wp_die( 'Sem permissão.' );
    check_admin_referer( 'rmbz_partnership_review_' . $track_id );

    $decision = sanitize_key( wp_unslash( $_POST['decision'] ?? '' ) );
    if ( ! in_array( $decision, [ 'approved', 'rejected', 'suspended' ], true ) ) wp_die( 'Decisão inválida.' );
    $phone = (string) get_post_meta( $track_id, '_imz_artista_account_phone', true );
    $eligibility = rmbz_partnership_eligibility( $phone, $track_id );
    $rights_ok = (bool) get_post_meta( $track_id, '_imz_partnership_rights_confirmed', true )
        && (bool) get_post_meta( $track_id, '_imz_partnership_terms_accepted', true );
    if ( $decision === 'approved' && ( ! $eligibility['eligible'] || ! $rights_ok ) ) {
        wp_safe_redirect( add_query_arg( [ 'post_type' => 'impulsionamento', 'page' => 'imz-partnership-program', 'partner_admin_notice' => 'requirements' ], admin_url( 'edit.php' ) ) );
        exit;
    }

    $reason = trim( sanitize_textarea_field( wp_unslash( $_POST['reason'] ?? '' ) ) );
    if ( in_array( $decision, [ 'rejected', 'suspended' ], true ) && $reason === '' ) {
        $reason = $decision === 'rejected' ? 'A candidatura ainda não cumpre os critérios internos do programa.' : 'Acesso suspenso para revisão pela equipa 1MZ.';
    }
    update_post_meta( $track_id, '_imz_partnership_status', $decision );
    update_post_meta( $track_id, '_imz_partnership_reviewed_at', current_time( 'mysql' ) );
    update_post_meta( $track_id, '_imz_partnership_reviewed_by', get_current_user_id() );
    if ( $reason !== '' ) update_post_meta( $track_id, '_imz_partnership_rejection_reason', $reason );
    else delete_post_meta( $track_id, '_imz_partnership_rejection_reason' );
    rmbz_partnership_notify( $phone, $decision, $reason );

    wp_safe_redirect( add_query_arg( [ 'post_type' => 'impulsionamento', 'page' => 'imz-partnership-program', 'partner_admin_notice' => 'updated' ], admin_url( 'edit.php' ) ) );
    exit;
}
add_action( 'admin_post_rmbz_partnership_review', 'rmbz_partnership_review' );

/** Centro de operações nativo do Programa de Parceria. */
function rmbz_partnership_admin_can_manage() {
    return current_user_can( 'manage_options' ) || current_user_can( 'rmbz_manage_partnerships' );
}
function rmbz_partnership_admin_menu() {
    global $wpdb; $pending=0;
    if(function_exists('rmbz_art_tracks_native_ready')&&rmbz_art_tracks_native_ready()){$t=rmbz_art_tracks_native_tables();$pending=(int)$wpdb->get_var("SELECT COUNT(*) FROM {$t['applications']} WHERE status='pending'");}
    $label='Programa de Parceria'.($pending?' <span class="awaiting-mod count-'.$pending.'"><span class="pending-count">'.$pending.'</span></span>':'');
    add_submenu_page('edit.php?post_type=impulsionamento','Programa de Parceria',$label,'manage_options','imz-partnership-program','rmbz_partnership_admin_page');
}
function rmbz_partnership_admin_page() {
    if(!rmbz_partnership_admin_can_manage())wp_die('Sem permissão.');
    if(!rmbz_art_tracks_native_ready()){rmbz_art_tracks_native_install();rmbz_art_tracks_native_migrate_legacy();}
    global $wpdb;$t=rmbz_art_tracks_native_tables();$filter=sanitize_key(wp_unslash($_GET['partner_status']??'all'));if(!in_array($filter,['all','none','pending','approved','rejected','suspended'],true))$filter='all';$search=sanitize_text_field(wp_unslash($_GET['s']??''));$notice=sanitize_key(wp_unslash($_GET['partner_admin_notice']??''));$where='1=1';$params=[];
    if($filter!=='all'){$where.=" AND COALESCE(a.status,'none')=%s";$params[]=$filter;}if($search!==''){$like='%'.$wpdb->esc_like($search).'%';$where.=' AND (t.artist_name LIKE %s OR t.account_phone LIKE %s OR t.account_email LIKE %s)';array_push($params,$like,$like,$like);}
    $sql="SELECT t.*,a.id application_id,COALESCE(a.status,'none') partner_status,a.rights_confirmed,a.terms_accepted,a.applied_at,a.reviewed_at,a.reviewed_by,a.decision_reason,a.internal_note,COALESCE(a.risk_level,'low') risk_level FROM {$t['tracks']} t LEFT JOIN {$t['applications']} a ON a.art_track_id=t.id WHERE $where ORDER BY CASE COALESCE(a.status,'none') WHEN 'pending' THEN 0 WHEN 'suspended' THEN 1 WHEN 'rejected' THEN 2 WHEN 'approved' THEN 3 ELSE 4 END,t.updated_at DESC LIMIT 250";
    $rows=$params?$wpdb->get_results($wpdb->prepare($sql,$params)):$wpdb->get_results($sql);$status_counts=['none'=>0,'pending'=>0,'approved'=>0,'rejected'=>0,'suspended'=>0];foreach($status_counts as $key=>$zero)$status_counts[$key]=(int)$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$t['tracks']} t LEFT JOIN {$t['applications']} a ON a.art_track_id=t.id WHERE COALESCE(a.status,'none')=%s",$key));$total=array_sum($status_counts);$migrated=get_option('rmbz_art_tracks_native_migrated_at','');
    ?>
    <div class="wrap rmbz-partner-admin"><style>
    /* ===== Material Design 3 — Programa de Parceria (marca 1MZ: verde+dourado) ===== */
    .rmbz-partner-admin{
        /* Papéis de cor MD3 (esquema claro derivado da marca) */
        --md-primary:#186a4e;--md-on-primary:#ffffff;--md-primary-container:#a9f2d4;--md-on-primary-container:#002014;
        --md-secondary:#7a5900;--md-secondary-container:#ffe089;--md-on-secondary-container:#251a00;
        --md-error:#ba1a1a;--md-error-container:#ffdad6;--md-on-error-container:#410002;
        --md-surface:#f6faf6;--md-surface-c-low:#f0f5ef;--md-surface-c:#eaefe9;--md-surface-c-high:#e4e9e3;--md-surface-c-highest:#dee4dd;
        --md-on-surface:#171d1a;--md-on-surface-var:#404944;--md-outline:#6f7972;--md-outline-var:#bfc9c1;
        --md-inverse-surface:#2c322e;--md-inverse-on-surface:#edf2ec;
        --md-elev-1:0 1px 2px rgba(0,0,0,.30),0 1px 3px 1px rgba(0,0,0,.15);
        --md-elev-2:0 1px 2px rgba(0,0,0,.30),0 2px 6px 2px rgba(0,0,0,.15);
        max-width:none;margin:0 20px 0 2px;padding:24px 24px 72px;color:var(--md-on-surface);
        font-family:Roboto,'Google Sans','Segoe UI',system-ui,sans-serif;background:var(--md-surface);border-radius:0 0 28px 28px
    }
    /* Tipografia MD3 */
    .rmbz-pa-top h1{margin:0;font-size:32px;line-height:40px;font-weight:400}
    .rmbz-pa-top p{margin:6px 0 0;color:var(--md-on-surface-var);font-size:14px;line-height:20px}
    .rmbz-pa-top{display:flex;align-items:flex-start;justify-content:space-between;gap:20px}
    .rmbz-pa-secure{display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 14px;border-radius:8px;background:var(--md-primary-container);color:var(--md-on-primary-container);font-size:14px;font-weight:500}
    /* Visão geral */
    .rmbz-pa-overview{display:grid;grid-template-columns:1.2fr repeat(4,minmax(120px,.45fr));gap:12px;margin:22px 0}
    .rmbz-pa-intro{padding:20px 22px;border-radius:24px;background:linear-gradient(135deg,#0f3b2c,#1f5943);color:#fff}
    .rmbz-pa-intro strong{font-size:16px;line-height:24px;font-weight:500}
    .rmbz-pa-intro p{margin:6px 0 0;color:rgba(255,255,255,.74);font-size:12px;line-height:16px}
    .rmbz-pa-stat{padding:16px;border-radius:16px;background:var(--md-surface-c-low);box-shadow:var(--md-elev-1)}
    .rmbz-pa-stat small{display:block;color:var(--md-on-surface-var);font-size:11px;line-height:16px;font-weight:500;letter-spacing:.5px}
    .rmbz-pa-stat strong{display:block;margin-top:6px;font-size:28px;line-height:36px;font-weight:400}
    /* Barra de pesquisa MD3 (search bar) + filter chips */
    .rmbz-pa-toolbar{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap}
    .rmbz-pa-search{display:flex;align-items:center;flex:1;min-width:280px;height:56px;padding:0 16px;border-radius:28px;background:var(--md-surface-c-high)}
    .rmbz-pa-search .dashicons{color:var(--md-on-surface-var)}
    .rmbz-pa-search input{width:100%;min-height:54px;border:0!important;background:transparent!important;box-shadow:none!important;font-size:16px;color:var(--md-on-surface)}
    .rmbz-pa-filters{display:flex;gap:8px;flex-wrap:wrap}
    .rmbz-pa-filters a{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 14px;border:1px solid var(--md-outline-var);border-radius:8px;background:transparent;text-decoration:none;color:var(--md-on-surface-var);font-size:14px;font-weight:500;transition:background .15s}
    .rmbz-pa-filters a:hover{background:rgba(23,29,26,.08)}
    .rmbz-pa-filters a.active{background:var(--md-secondary-container);border-color:transparent;color:var(--md-on-secondary-container)}
    .rmbz-pa-filters a.active::before{content:"✓";font-weight:700}
    .rmbz-pa-filters a span{opacity:.75}
    /* Cartões MD3 (elevated card) */
    .rmbz-pa-list{display:grid;gap:14px}
    .rmbz-pa-card{padding:18px;border-radius:16px;background:var(--md-surface-c-low);box-shadow:var(--md-elev-1);transition:box-shadow .18s}
    .rmbz-pa-card:hover{box-shadow:var(--md-elev-2)}
    .rmbz-pa-main{display:grid;grid-template-columns:minmax(270px,1fr) 170px minmax(250px,.8fr);gap:18px;align-items:center}
    .rmbz-pa-person{display:flex;gap:14px;align-items:center}
    .rmbz-pa-avatar{width:48px;height:48px;display:grid;place-items:center;overflow:hidden;flex:0 0 48px;border-radius:50%;background:var(--md-secondary-container);color:var(--md-on-secondary-container);font-weight:600;font-size:18px}
    .rmbz-pa-avatar img{width:100%;height:100%;object-fit:cover}
    .rmbz-pa-name{font-size:16px;line-height:24px;font-weight:500}
    .rmbz-pa-meta{margin-top:2px;color:var(--md-on-surface-var);font-size:12px;line-height:16px}
    .rmbz-pa-age{color:var(--md-secondary)}
    .rmbz-pa-age.late{color:var(--md-error)}
    /* Estados como "badges" tonais MD3 */
    .rmbz-pa-status{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 12px;border-radius:8px;font-size:12px;font-weight:600;background:var(--md-surface-c-highest);color:var(--md-on-surface-var)}
    .rmbz-pa-status .dashicons{font-size:14px;width:14px;height:14px}
    .rmbz-pa-status.pending{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}
    .rmbz-pa-status.approved{background:var(--md-primary-container);color:var(--md-on-primary-container)}
    .rmbz-pa-status.rejected,.rmbz-pa-status.suspended{background:var(--md-error-container);color:var(--md-on-error-container)}
    /* Progresso dos requisitos */
    .rmbz-pa-health{display:grid;gap:6px;font-size:12px;color:var(--md-on-surface-var)}
    .rmbz-pa-health strong{color:var(--md-on-surface);font-weight:500}
    .rmbz-pa-progress{height:6px;overflow:hidden;border-radius:999px;background:var(--md-surface-c-highest)}
    .rmbz-pa-progress span{display:block;height:100%;border-radius:inherit;background:var(--md-primary)}
    /* Zona de decisão */
    .rmbz-pa-actions{grid-column:1/-1;display:grid;grid-template-columns:180px minmax(240px,1fr) minmax(240px,1fr);gap:12px;align-items:end;margin-top:16px;padding-top:16px;border-top:1px solid var(--md-outline-var)}
    .rmbz-pa-actions--empty{grid-template-columns:1fr auto;align-items:center}
    .rmbz-pa-waiting{margin:0;display:flex;align-items:center;gap:8px;color:var(--md-on-surface-var);font-size:14px}
    .rmbz-pa-waiting .dashicons{color:var(--md-secondary)}
    .rmbz-pa-field{display:grid;gap:6px;min-width:0}
    .rmbz-pa-field>span{color:var(--md-on-surface-var);font-size:12px;font-weight:500}
    .rmbz-pa-actions select,.rmbz-pa-actions textarea{width:100%;min-height:48px;margin:0;padding:12px 14px;border:1px solid var(--md-outline)!important;border-radius:8px!important;background:transparent!important;box-shadow:none!important;font-size:14px;color:var(--md-on-surface)}
    .rmbz-pa-actions textarea{height:48px;resize:vertical;line-height:1.4}
    .rmbz-pa-actions select:focus,.rmbz-pa-actions textarea:focus{border-color:var(--md-primary)!important;box-shadow:0 0 0 1px var(--md-primary)!important;outline:0}
    /* Botões MD3: filled / tonal / outlined / text (altura 40, raio total) */
    .rmbz-pa-buttons{grid-column:1/-1;display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;padding-top:4px}
    .rmbz-pa-btn{display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 24px;border:0;border-radius:999px;font-size:14px;font-weight:500;letter-spacing:.1px;cursor:pointer;transition:box-shadow .15s,background .15s}
    .rmbz-pa-btn-approve{background:var(--md-primary);color:var(--md-on-primary)}
    .rmbz-pa-btn-approve:hover{box-shadow:var(--md-elev-1);background:#1d7a5b}
    .rmbz-pa-btn-approve:disabled{background:rgba(23,29,26,.12);color:rgba(23,29,26,.38);cursor:not-allowed;box-shadow:none}
    .rmbz-pa-btn-reject{background:transparent;color:var(--md-error);border:1px solid var(--md-outline)}
    .rmbz-pa-btn-reject:hover{background:rgba(186,26,26,.08)}
    .rmbz-pa-btn-suspend{background:var(--md-inverse-surface);color:var(--md-inverse-on-surface)}
    .rmbz-pa-btn-suspend:hover{box-shadow:var(--md-elev-1)}
    .rmbz-pa-btn-reopen{background:var(--md-primary-container);color:var(--md-on-primary-container)}
    .rmbz-pa-btn-reopen:hover{box-shadow:var(--md-elev-1)}
    .rmbz-pa-details{background:transparent;color:var(--md-primary);padding:0 16px}
    .rmbz-pa-details:hover{background:rgba(24,106,78,.08)}
    .rmbz-pa-empty{padding:56px;text-align:center;border:1px dashed var(--md-outline-var);border-radius:16px;color:var(--md-on-surface-var)}
    /* Diálogo MD3 (raio 28, scrim) */
    .rmbz-pa-dialog{width:min(850px,calc(100vw - 40px));max-height:86vh;padding:0;border:0;border-radius:28px;background:var(--md-surface-c-low);box-shadow:var(--md-elev-2)}
    .rmbz-pa-dialog::backdrop{background:rgba(23,29,26,.42);backdrop-filter:blur(2px)}
    .rmbz-pa-dialog-head{display:flex;justify-content:space-between;gap:15px;padding:24px 24px 16px}
    .rmbz-pa-dialog-head h2{margin:0;font-size:24px;line-height:32px;font-weight:400}
    .rmbz-pa-close{width:40px;height:40px;border:0;border-radius:50%;cursor:pointer;background:var(--md-surface-c-high);color:var(--md-on-surface-var);font-size:18px}
    .rmbz-pa-close:hover{background:var(--md-surface-c-highest)}
    .rmbz-pa-dialog-body{padding:0 24px 24px;overflow:auto}
    .rmbz-pa-dialog-body h3{font-size:16px;line-height:24px;font-weight:500;margin:20px 0 10px}
    .rmbz-pa-security{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
    .rmbz-pa-security div{padding:12px 14px;border-radius:12px;background:var(--md-surface-c)}
    .rmbz-pa-security small,.rmbz-pa-security strong{display:block}
    .rmbz-pa-security small{color:var(--md-on-surface-var);font-size:10px;font-weight:600;letter-spacing:.5px}
    .rmbz-pa-security strong{margin-top:4px;font-weight:500}
    .rmbz-pa-req-list,.rmbz-pa-audit{display:grid;gap:8px;margin-top:4px}
    .rmbz-pa-req-item,.rmbz-pa-audit-item{display:flex;justify-content:space-between;gap:15px;padding:12px 14px;border-radius:12px;background:var(--md-surface-c)}
    .rmbz-pa-ok{color:var(--md-primary)}
    .rmbz-pa-no{color:var(--md-error)}
    .rmbz-pa-audit-item small{color:var(--md-on-surface-var)}
    @media(max-width:1280px){.rmbz-pa-overview{grid-template-columns:repeat(4,1fr)}.rmbz-pa-intro{grid-column:1/-1}.rmbz-pa-main{grid-template-columns:minmax(240px,1fr) 150px minmax(220px,.8fr)}}
    @media(max-width:1000px){.rmbz-pa-actions{grid-template-columns:160px 1fr 1fr}}
    @media(max-width:800px){.rmbz-partner-admin{padding:18px 10px}.rmbz-pa-top,.rmbz-pa-toolbar{display:grid}.rmbz-pa-overview{grid-template-columns:1fr 1fr}.rmbz-pa-main{grid-template-columns:1fr;align-items:start}.rmbz-pa-security{grid-template-columns:1fr}.rmbz-pa-actions{grid-template-columns:1fr}.rmbz-pa-actions--empty{grid-template-columns:1fr}.rmbz-pa-buttons{grid-column:1;justify-content:stretch}.rmbz-pa-btn{flex:1}}
    </style>    <header class="rmbz-pa-top"><div><h1>Programa de Parceria</h1><p>Aprovação, segurança, monetização e auditoria num único centro de operações.</p></div><div class="rmbz-pa-secure"><span class="dashicons dashicons-shield"></span>Base nativa 1MZ</div></header>
    <?php if($notice==='updated'):?><div class="notice notice-success is-dismissible"><p>Decisão guardada, auditada e comunicada ao artista.</p></div><?php elseif($notice==='requirements'):?><div class="notice notice-error is-dismissible"><p>Não é possível aprovar: faltam requisitos automáticos ou declarações.</p></div><?php elseif($notice==='reason'):?><div class="notice notice-error is-dismissible"><p>Indica um motivo para rejeitar ou suspender.</p></div><?php elseif($notice==='conflict'):?><div class="notice notice-warning is-dismissible"><p>A candidatura foi alterada por outra sessão. Revê os dados antes de decidir.</p></div><?php elseif($notice==='noapplication'):?><div class="notice notice-error is-dismissible"><p>Este artista ainda não se candidatou ao programa — não há nada para decidir. A vinculação parte sempre do artista.</p></div><?php elseif($notice==='transition'):?><div class="notice notice-error is-dismissible"><p>Transição de estado inválida para esta candidatura.</p></div><?php endif;?>
    <section class="rmbz-pa-overview"><article class="rmbz-pa-intro"><strong>Decisão manual com controlo de concorrência</strong><p>Cada ação exige nonce, capacidade própria e regista utilizador, data, transição, contexto e hash do IP. Última migração: <?php echo esc_html($migrated?:'pendente');?></p></article><article class="rmbz-pa-stat"><small>EM ANÁLISE</small><strong><?php echo $status_counts['pending'];?></strong></article><article class="rmbz-pa-stat"><small>PARCEIROS</small><strong><?php echo $status_counts['approved'];?></strong></article><article class="rmbz-pa-stat"><small>REVISÃO</small><strong><?php echo $status_counts['rejected']+$status_counts['suspended'];?></strong></article><article class="rmbz-pa-stat"><small>ART TRACKS</small><strong><?php echo $total;?></strong></article></section>
    <div class="rmbz-pa-toolbar"><form class="rmbz-pa-search" method="get"><input type="hidden" name="post_type" value="impulsionamento"><input type="hidden" name="page" value="imz-partnership-program"><input type="hidden" name="partner_status" value="<?php echo esc_attr($filter);?>"><span class="dashicons dashicons-search"></span><input type="search" name="s" value="<?php echo esc_attr($search);?>" placeholder="Pesquisar artista, telefone ou email"></form><nav class="rmbz-pa-filters"><?php foreach(['all'=>'Todos','pending'=>'Em análise','approved'=>'Ativos','rejected'=>'Não aprovados','suspended'=>'Suspensos','none'=>'Sem candidatura'] as $key=>$label):$count=$key==='all'?$total:$status_counts[$key];?><a class="<?php echo $filter===$key?'active':'';?>" href="<?php echo esc_url(add_query_arg(['post_type'=>'impulsionamento','page'=>'imz-partnership-program','partner_status'=>$key,'s'=>$search],admin_url('edit.php')));?>"><?php echo esc_html($label);?> <span><?php echo (int)$count;?></span></a><?php endforeach;?></nav></div>
    <section class="rmbz-pa-list">
    <?php if(!$rows):?><div class="rmbz-pa-empty"><span class="dashicons dashicons-search"></span><h3>Nenhum resultado</h3><p>Altera a pesquisa ou o filtro selecionado.</p></div><?php endif;?>
    <?php foreach($rows as $row):$status=(string)$row->partner_status;$status_meta=rmbz_partnership_admin_status_label($status);$elig=rmbz_partnership_eligibility($row->account_phone,$row->id);$rights_ok=(bool)$row->rights_confirmed&&(bool)$row->terms_accepted;$pct=$elig['total']?(int)round(($elig['met_count']/$elig['total'])*100):0;$initial=function_exists('mb_substr')?mb_substr($row->artist_name,0,1):substr($row->artist_name,0,1);$audits=rmbz_partnership_audit_for_track($row->id,12);$dialog_id='rmbz-pa-dialog-'.(int)$row->id;?>
        <article class="rmbz-pa-card"><div class="rmbz-pa-main"><div class="rmbz-pa-person"><span class="rmbz-pa-avatar"><?php if($row->photo_url):?><img src="<?php echo esc_url($row->photo_url);?>" alt=""><?php else:echo esc_html(strtoupper($initial));endif;?></span><div><div class="rmbz-pa-name"><?php echo esc_html($row->artist_name);?></div><div class="rmbz-pa-meta"><?php echo esc_html($row->account_phone?:'Conta ainda não ligada');?><?php echo $row->applied_at?' · '.esc_html(date_i18n('d/m/Y H:i',strtotime($row->applied_at))):'';?><?php if($status==='pending'&&$row->applied_at):$dias=max(0,(int)floor((time()-strtotime($row->applied_at))/DAY_IN_SECONDS));?> · <strong class="rmbz-pa-age<?php echo $dias>=3?' late':'';?>">em análise há <?php echo $dias===0?'menos de 1 dia':$dias.' dia'.($dias===1?'':'s');?></strong><?php endif;?></div></div></div><div><span class="rmbz-pa-status <?php echo esc_attr($status_meta[1]);?>"><span class="dashicons dashicons-marker"></span><?php echo esc_html($status_meta[0]);?></span></div><div class="rmbz-pa-health"><strong><?php echo (int)$elig['met_count'];?>/<?php echo (int)$elig['total'];?> requisitos</strong><div class="rmbz-pa-progress"><span style="width:<?php echo $pct;?>%"></span></div><span><?php echo min(3,(int)$elig['published_count']);?>/3 músicas · Direitos <?php echo $rights_ok?'confirmados':'em falta';?></span></div><?php
            // MÁQUINA DE ESTADOS na UI (espelha o servidor): sem candidatura não
            // há NADA para decidir — a vinculação parte sempre do artista.
            $can_approve = in_array( $status, [ 'pending', 'suspended' ], true );
            $can_reject  = $status === 'pending';
            $can_suspend = $status === 'approved';
            $can_reopen  = in_array( $status, [ 'rejected', 'suspended' ], true );
            $approve_ok  = $elig['eligible'] && $rights_ok;
            ?>
            <?php if ( $status === 'none' ) : ?>
            <div class="rmbz-pa-actions rmbz-pa-actions--empty">
                <p class="rmbz-pa-waiting"><span class="dashicons dashicons-hourglass"></span> Este artista ainda não se candidatou — não há decisões a tomar. Quando submeter a candidatura, aparece em «Em análise».</p>
                <div class="rmbz-pa-buttons"><button type="button" class="rmbz-pa-btn rmbz-pa-details" data-dialog="<?php echo esc_attr($dialog_id);?>">Ver detalhes</button></div>
            </div>
            <?php else : ?>
            <form class="rmbz-pa-actions" data-review-form method="post" action="<?php echo esc_url(admin_url('admin-post.php'));?>"><input type="hidden" name="action" value="rmbz_partnership_review"><input type="hidden" name="track_id" value="<?php echo (int)$row->id;?>"><input type="hidden" name="expected_status" value="<?php echo esc_attr($status);?>"><?php wp_nonce_field('rmbz_partnership_review_'.$row->id);?><label class="rmbz-pa-field"><span>Nível de risco</span><select name="risk_level"><option value="low" <?php selected($row->risk_level,'low');?>>Risco baixo</option><option value="medium" <?php selected($row->risk_level,'medium');?>>Risco médio</option><option value="high" <?php selected($row->risk_level,'high');?>>Risco alto</option></select></label><label class="rmbz-pa-field"><span>Motivo visível ao artista</span><textarea name="reason" placeholder="Obrigatório ao rejeitar ou suspender"><?php echo esc_textarea((string)$row->decision_reason);?></textarea></label><label class="rmbz-pa-field"><span>Nota interna da equipa</span><textarea name="internal_note" placeholder="Apenas a administração pode ver"><?php echo esc_textarea((string)$row->internal_note);?></textarea></label><div class="rmbz-pa-buttons"><button type="button" class="rmbz-pa-btn rmbz-pa-details" data-dialog="<?php echo esc_attr($dialog_id);?>">Ver detalhes</button><?php if($can_reopen):?><button class="rmbz-pa-btn rmbz-pa-btn-reopen" name="decision" value="pending" data-confirm="Reabrir esta candidatura para análise?">Reabrir</button><?php endif;?><?php if($can_suspend):?><button class="rmbz-pa-btn rmbz-pa-btn-suspend" name="decision" value="suspended" data-reason-required="1" data-confirm="Suspender o acesso deste artista?">Suspender</button><?php endif;?><?php if($can_reject):?><button class="rmbz-pa-btn rmbz-pa-btn-reject" name="decision" value="rejected" data-reason-required="1" data-confirm="Não aprovar esta candidatura?">Não aprovar</button><?php endif;?><?php if($can_approve):?><button class="rmbz-pa-btn rmbz-pa-btn-approve" name="decision" value="approved" <?php disabled(!$approve_ok);?> title="<?php echo $approve_ok?'':'Faltam requisitos ou declarações — vê os detalhes';?>" data-confirm="Aprovar este artista no Programa de Parceria?">Aprovar</button><?php endif;?></div></form>
            <?php endif; ?></div>
        <dialog class="rmbz-pa-dialog" id="<?php echo esc_attr($dialog_id);?>"><div class="rmbz-pa-dialog-head"><div><h2><?php echo esc_html($row->artist_name);?></h2><p class="description">Art Track nativo #<?php echo (int)$row->id;?></p></div><button type="button" class="rmbz-pa-close" data-close-dialog aria-label="Fechar">×</button></div><div class="rmbz-pa-dialog-body"><div class="rmbz-pa-security"><div><small>CONTA</small><strong><?php echo $row->linked_user_id?'Ligada':'Não ligada';?></strong></div><div><small>EMAIL</small><strong><?php echo esc_html($row->account_email?:'Em falta');?></strong></div><div><small>SUBSCRIÇÃO</small><strong><?php echo !empty($elig['requirements']['subscription']['met'])?'Ativa':'Inativa';?></strong></div><div><small>RISCO</small><strong><?php echo esc_html(ucfirst($row->risk_level));?></strong></div><div><small>CATÁLOGO</small><strong><?php echo (int)$elig['published_count'];?> publicadas</strong></div><div><small>LEGADO</small><strong><?php echo $row->legacy_post_id?'Migrado #'.(int)$row->legacy_post_id:'100% nativo';?></strong></div></div><h3>Requisitos verificados</h3><div class="rmbz-pa-req-list"><?php foreach($elig['requirements'] as $req):?><div class="rmbz-pa-req-item"><span><?php echo esc_html($req['label']);?><small style="display:block;color:#6b716d"><?php echo esc_html($req['detail']);?></small></span><strong class="<?php echo $req['met']?'rmbz-pa-ok':'rmbz-pa-no';?>"><?php echo $req['met']?'Concluído':'Pendente';?></strong></div><?php endforeach;?><div class="rmbz-pa-req-item"><span>Declarações legais</span><strong class="<?php echo $rights_ok?'rmbz-pa-ok':'rmbz-pa-no';?>"><?php echo $rights_ok?'Confirmadas':'Em falta';?></strong></div></div><h3>Histórico de auditoria</h3><div class="rmbz-pa-audit"><?php if(!$audits):?><p class="description">Ainda não existem eventos registados.</p><?php endif;foreach($audits as $audit):$actor=$audit->actor_user_id?get_userdata($audit->actor_user_id):null;?><div class="rmbz-pa-audit-item"><span><strong><?php echo esc_html(str_replace('_',' ',ucfirst($audit->event_type)));?></strong><small style="display:block"><?php echo esc_html($audit->note?:trim($audit->from_status.' → '.$audit->to_status));?></small></span><small><?php echo esc_html(date_i18n('d/m/Y H:i',strtotime($audit->created_at)));?> · <?php echo esc_html($actor?$actor->display_name:'Sistema');?></small></div><?php endforeach;?></div></div></dialog>
        </article>
    <?php endforeach;?></section></div>
    <script>(function(){document.querySelectorAll('[data-dialog]').forEach(function(b){b.addEventListener('click',function(){var d=document.getElementById(b.dataset.dialog);if(d&&d.showModal)d.showModal();});});document.querySelectorAll('[data-close-dialog]').forEach(function(b){b.addEventListener('click',function(){b.closest('dialog').close();});});document.querySelectorAll('[data-review-form]').forEach(function(f){f.addEventListener('submit',function(e){var b=e.submitter;if(!b)return;var reason=f.querySelector('[name="reason"]');if(b.dataset.reasonRequired&&(!reason||!reason.value.trim())){e.preventDefault();alert('Indica o motivo antes de continuar.');if(reason)reason.focus();return;}if(b.dataset.confirm&&!window.confirm(b.dataset.confirm))e.preventDefault();});});})();</script>
    <?php
}
function rmbz_partnership_review() {
    $track_id=absint($_POST['track_id']??0);
    if(!$track_id||!function_exists('rmbz_art_track_is_valid')||!rmbz_art_track_is_valid($track_id,true))wp_die('Art Track inválido.');
    if(!rmbz_partnership_admin_can_manage())wp_die('Sem permissão.');
    check_admin_referer('rmbz_partnership_review_'.$track_id);
    $decision=sanitize_key(wp_unslash($_POST['decision']??''));
    if(!in_array($decision,['approved','rejected','suspended','pending'],true))wp_die('Decisão inválida.');
    $application=rmbz_partnership_application_get($track_id);$current=$application?sanitize_key($application->status):'none';$expected=sanitize_key(wp_unslash($_POST['expected_status']??''));
    $base=['post_type'=>'impulsionamento','page'=>'imz-partnership-program'];
    if($expected!==''&&$expected!==$current){wp_safe_redirect(add_query_arg($base+['partner_admin_notice'=>'conflict'],admin_url('edit.php')));exit;}
    // MÁQUINA DE ESTADOS: só transições legítimas. Em especial, NUNCA se decide
    // sobre quem não se candidatou ('none' não tem transições) — a vinculação
    // parte sempre do artista.
    $allowed_transitions=[
        'none'      => [],
        'pending'   => ['approved','rejected'],
        'approved'  => ['suspended'],
        'rejected'  => ['pending'],
        'suspended' => ['pending','approved'],
    ];
    if(!in_array($decision,$allowed_transitions[$current]??[],true)){
        wp_safe_redirect(add_query_arg($base+['partner_admin_notice'=>$current==='none'?'noapplication':'transition'],admin_url('edit.php')));exit;
    }
    $track=rmbz_art_track_get($track_id);$phone=(string)$track->account_phone;$eligibility=rmbz_partnership_eligibility($phone,$track_id);$rights_ok=$application&&(bool)$application->rights_confirmed&&(bool)$application->terms_accepted;
    if($decision==='approved'&&(!$eligibility['eligible']||!$rights_ok)){wp_safe_redirect(add_query_arg($base+['partner_admin_notice'=>'requirements'],admin_url('edit.php')));exit;}
    $reason=trim(sanitize_textarea_field(wp_unslash($_POST['reason']??'')));$internal=trim(sanitize_textarea_field(wp_unslash($_POST['internal_note']??'')));$risk=sanitize_key(wp_unslash($_POST['risk_level']??'low'));if(!in_array($risk,['low','medium','high'],true))$risk='low';
    if(in_array($decision,['rejected','suspended'],true)&&$reason===''){wp_safe_redirect(add_query_arg($base+['partner_admin_notice'=>'reason'],admin_url('edit.php')));exit;}
    $now=current_time('mysql');$snapshot=['requirements_met'=>(int)$eligibility['met_count'],'requirements_total'=>(int)$eligibility['total'],'published_count'=>(int)$eligibility['published_count'],'rights_confirmed'=>(bool)$rights_ok,'subscription_active'=>!empty($eligibility['requirements']['subscription']['met']),'risk_level'=>$risk];
    rmbz_partnership_application_save($track_id,['account_phone'=>$phone,'status'=>$decision,'reviewed_at'=>$now,'reviewed_by'=>get_current_user_id(),'decision_reason'=>$reason,'internal_note'=>$internal,'risk_level'=>$risk,'security_snapshot'=>$snapshot]);
    rmbz_partnership_audit_log($track_id,'application_'.$decision,$current,$decision,$internal?:$reason,$snapshot);
    if($track->legacy_post_id){update_post_meta((int)$track->legacy_post_id,'_imz_partnership_status',$decision);update_post_meta((int)$track->legacy_post_id,'_imz_partnership_reviewed_at',$now);update_post_meta((int)$track->legacy_post_id,'_imz_partnership_reviewed_by',get_current_user_id());if($reason!=='')update_post_meta((int)$track->legacy_post_id,'_imz_partnership_rejection_reason',$reason);else delete_post_meta((int)$track->legacy_post_id,'_imz_partnership_rejection_reason');}
    rmbz_partnership_notify($phone,$decision,$reason);wp_safe_redirect(add_query_arg($base+['partner_admin_notice'=>'updated'],admin_url('edit.php')));exit;
}