<?php
/** URL estável de retorno para o formulário SOMAS antigo ou para o painel VIP. */
function rmbz_licensing_somas_return_url() {
    $referer = wp_get_referer();
    $fallback = add_query_arg( 'distro_action', 'licensing-somas', home_url( '/minha-conta/' ) );
    $referer = wp_validate_redirect( $referer, $fallback );
    $referer = remove_query_arg( [ 'somas_status', 'msg', 'id' ], $referer );
    $query = (string) wp_parse_url( $referer, PHP_URL_QUERY );
    parse_str( $query, $args );
    if ( ( $args['sect'] ?? '' ) === 'distro' || ( $args['return_to'] ?? '' ) === 'vip' ) {
        return add_query_arg( [ 'sect' => 'distro', 'dview' => 'somas' ], home_url( '/minha-conta/' ) );
    }
    return $referer;
}

/**
 * includes/distribution/distribution-licensing.php
 *
 * ============================================================================
 * MÓDULO DE LICENCIAMENTO MUSICAL (SOMAS)
 * ============================================================================
 *
 * Este módulo implementa o serviço de licenciamento musical via SOMAS
 * (Sociedade Moçambicana de Autores). Funciona em 2 caminhos:
 *
 *   CAMINHO A — Artista AINDA NÃO está registado na SOMAS:
 *     1. Artista preenche formulário SOMAS embutido (replica da ficha oficial)
 *     2. Cobra-se 700 MT da carteira (taxa de processamento + facilitação)
 *     3. Plugin gera PDF preenchido
 *     4. Admin envia para SOMAS, recebe nº de registo, aprova no painel
 *     5. Quando aprovado, artista recebe nº SOMAS e pode licenciar a 100MT/faixa
 *
 *   CAMINHO B — Artista TEM nº SOMAS aprovado:
 *     1. No wizard de envio, após o passo da capa, aparece passo "Licenciamento"
 *     2. Artista escolhe se quer licenciar este lançamento
 *     3. Sistema cobra 100 MT × nº de faixas (single=1, EP=2-6, álbum=7+)
 *     4. Pedido entra na lista de licenciamentos pendentes do admin
 *     5. Admin processa via SOMAS, aprova/rejeita
 *     6. Se rejeitado, valor é DEVOLVIDO automaticamente à carteira
 *
 * ============================================================================
 * TABELAS CRIADAS
 * ============================================================================
 *
 *   wp_rmbz_somas_registrations
 *     Registos SOMAS (formulários submetidos pelos artistas).
 *     Estados: 'pending', 'approved', 'returned', 'rejected'
 *     Quando 'approved', contém o número SOMAS oficial do artista.
 *
 *   wp_rmbz_licenses
 *     Pedidos de licenciamento de releases.
 *     Estados: 'pending', 'processing', 'approved', 'rejected', 'refunded'
 *     Vinculado a um release_id e contém o nº de faixas e valor cobrado.
 *
 * ============================================================================
 * OPÇÕES (wp_options)
 * ============================================================================
 *
 *   rmbz_licensing_price_registration   default: 700.00 (MT)
 *   rmbz_licensing_price_per_track      default: 100.00 (MT)
 *   rmbz_licensing_enabled              default: '1' (feature toggle)
 *
 * ============================================================================
 * CUPÕES — REUTILIZA SISTEMA EXISTENTE
 * ============================================================================
 *
 * Aproveita a tabela existente wp_rmbz_coupons (criada em functions-setup.php)
 * com novos reward_types:
 *   - 'licensing_discount_percent'  → desconto percentual no licenciamento
 *   - 'licensing_discount_fixed'    → desconto fixo (MT) no licenciamento
 *   - 'licensing_free_tracks'       → N faixas gratuitas
 *
 * ============================================================================
 * INTEGRAÇÃO COM CARTEIRA
 * ============================================================================
 *
 * Todas as operações financeiras usam rmbz_update_wallet_balance() —
 * a função oficial com lock anti-concorrência. Tipos de transação:
 *   - 'licensing_somas_fee'      → débito 700 MT (registo SOMAS)
 *   - 'licensing_track_fee'      → débito N×100 MT (licenciamento)
 *   - 'licensing_refund'         → crédito (devolução por rejeição)
 */

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


/* ============================================================================
 * 1. SCHEMA — CRIAÇÃO DE TABELAS
 * ============================================================================ */

/**
 * Cria/actualiza as 2 tabelas do módulo. Idempotente — pode correr múltiplas
 * vezes sem destruir dados (usa dbDelta).
 *
 * Hook: registado em rmbz_licensing_init()
 */
function rmbz_licensing_maybe_install_tables() {
    global $wpdb;
    $charset_collate = $wpdb->get_charset_collate();

    if ( ! function_exists('dbDelta') ) {
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    }

    // Tabela 1: Registos SOMAS (formulários submetidos)
    // [DS 1.5.82] Colunas bi_file_url + bi_file_path para upload BI/Passaporte.
    // [DS 1.5.83] Colunas submission_type + somas_card_file_* para suportar
    // 2 caminhos: artistas a registar PELA primeira vez na SOMAS vs artistas
    // que JÁ são membros e só precisam validar o seu nº.
    $sql1 = "CREATE TABLE {$wpdb->prefix}rmbz_somas_registrations (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        artist_telemovel varchar(20) NOT NULL,
        submission_type varchar(30) NOT NULL DEFAULT 'new_registration',
        status varchar(20) NOT NULL DEFAULT 'pending',
        somas_number varchar(50) DEFAULT NULL,
        form_data longtext NOT NULL,
        bi_file_url varchar(500) DEFAULT NULL,
        bi_file_path varchar(500) DEFAULT NULL,
        somas_card_file_url varchar(500) DEFAULT NULL,
        somas_card_file_path varchar(500) DEFAULT NULL,
        amount_charged decimal(10,2) DEFAULT 0.00,
        wallet_transaction_id bigint(20) DEFAULT NULL,
        admin_note text DEFAULT NULL,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        updated_at datetime DEFAULT CURRENT_TIMESTAMP,
        approved_at datetime DEFAULT NULL,
        PRIMARY KEY  (id),
        KEY artist_telemovel (artist_telemovel),
        KEY status (status),
        KEY submission_type (submission_type)
    ) $charset_collate;";
    dbDelta( $sql1 );

    // Tabela 2: Licenças (pedidos de licenciamento por release)
    $sql2 = "CREATE TABLE {$wpdb->prefix}rmbz_licenses (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        release_id bigint(20) NOT NULL,
        artist_telemovel varchar(20) NOT NULL,
        somas_number varchar(50) NOT NULL,
        status varchar(20) NOT NULL DEFAULT 'pending',
        track_count int(11) NOT NULL DEFAULT 1,
        unit_price decimal(10,2) NOT NULL,
        total_price decimal(10,2) NOT NULL,
        coupon_id mediumint(9) DEFAULT NULL,
        coupon_discount decimal(10,2) DEFAULT 0.00,
        amount_charged decimal(10,2) NOT NULL,
        wallet_transaction_id bigint(20) DEFAULT NULL,
        refund_transaction_id bigint(20) DEFAULT NULL,
        admin_note text DEFAULT NULL,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        updated_at datetime DEFAULT CURRENT_TIMESTAMP,
        completed_at datetime DEFAULT NULL,
        PRIMARY KEY  (id),
        KEY release_id (release_id),
        KEY artist_telemovel (artist_telemovel),
        KEY status (status)
    ) $charset_collate;";
    dbDelta( $sql2 );
}

/**
 * Regista as tabelas no schema-health-check para reparação automática.
 */
add_filter( 'rmbz_schema_expected_tables_extra', function( $extras ) {
    $extras['rmbz_somas_registrations'] = [
        'description' => 'Registos SOMAS dos artistas (Licenciamento)',
        'installer'   => 'rmbz_licensing_maybe_install_tables',
        'critical'    => false,
    ];
    $extras['rmbz_licenses'] = [
        'description' => 'Pedidos de licenciamento por release (Licenciamento)',
        'installer'   => 'rmbz_licensing_maybe_install_tables',
        'critical'    => false,
    ];
    return $extras;
});


/* ============================================================================
 * 2. OPÇÕES — PREÇOS E TOGGLE DE FEATURE
 * ============================================================================ */

/**
 * Devolve o preço actual do registo SOMAS (default 700 MT).
 * Admin pode mudar via página de Configurações do Licenciamento.
 */
function rmbz_licensing_get_registration_price() {
    return (float) get_option( 'rmbz_licensing_price_registration', 700.00 );
}

/**
 * Devolve o preço por faixa licenciada (default 100 MT).
 */
function rmbz_licensing_get_per_track_price() {
    return (float) get_option( 'rmbz_licensing_price_per_track', 100.00 );
}

/**
 * [DS 1.5.83] Preço para validação de artistas que JÁ são membros SOMAS.
 * Default 0 (grátis) — admin pode mudar nas configurações.
 *
 * Estes artistas já pagaram à SOMAS directamente, então não há custo de
 * processamento de pedido novo. Mas pode haver uma pequena taxa de
 * verificação manual (admin tem de confirmar comprovante + BI).
 */
function rmbz_licensing_get_existing_member_price() {
    return (float) get_option( 'rmbz_licensing_price_existing_member', 0.00 );
}

/**
 * Verifica se a feature de licenciamento está activa globalmente.
 * Permite desactivar temporariamente sem desinstalar o módulo.
 */
function rmbz_licensing_is_enabled() {
    return get_option( 'rmbz_licensing_enabled', '1' ) === '1';
}

/**
 * [DS 1.5.84] Renderiza a notificação visual de "serviço indisponível".
 * Vermelho com X — comunica claramente "não dá para usar isto agora".
 * Centralizado aqui para todos os pontos do plugin usarem o mesmo visual.
 */
function rmbz_licensing_render_disabled_notice() {
    ?>
    <div class="rmbz-licensing-disabled">
        <div class="rmbz-licensing-disabled__icon" aria-hidden="true">
            <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
                <path d="M8 8l8 8M16 8l-8 8" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/>
            </svg>
        </div>
        <div class="rmbz-licensing-disabled__body">
            <h3>Serviço indisponível</h3>
            <p>O serviço de licenciamento está temporariamente desactivado. Por favor tenta mais tarde ou contacta o suporte.</p>
        </div>
    </div>
    <style>
    .rmbz-licensing-disabled {
        display: flex;
        gap: 16px;
        align-items: flex-start;
        background: linear-gradient(135deg, rgba(231,76,60,0.10), rgba(231,76,60,0.03));
        border: 1px solid rgba(231,76,60,0.35);
        border-left: 4px solid #e74c3c;
        border-radius: 10px;
        padding: 22px 24px;
        margin: 16px 0;
        color: var(--rmbz-text-primary, #fff);
    }
    .rmbz-licensing-disabled__icon {
        flex-shrink: 0;
        width: 36px; height: 36px;
        color: var(--rmbz-danger, #ef4444);
        line-height: 0;
    }
    .rmbz-licensing-disabled__icon svg { width: 100%; height: 100%; display: block; }
    .rmbz-licensing-disabled__body { flex: 1; min-width: 0; }
    .rmbz-licensing-disabled__body h3 {
        margin: 0 0 6px;
        color: var(--rmbz-danger, #ef4444);
        font-size: 17px;
        font-weight: 700;
    }
    .rmbz-licensing-disabled__body p {
        margin: 0;
        color: var(--rmbz-text-secondary, #ccc);
        font-size: 14px;
        line-height: 1.6;
    }
    @media (max-width: 600px) {
        .rmbz-licensing-disabled { flex-direction: column; gap: 10px; padding: 18px; }
        .rmbz-licensing-disabled__icon { width: 32px; height: 32px; }
    }
    </style>
    <?php
}


/* ============================================================================
 * 3. HELPERS — CONSULTAS DE ESTADO DO ARTISTA
 * ============================================================================ */

/**
 * Devolve o registo SOMAS ACTIVO do artista (se houver).
 *
 * Estados possíveis:
 *   - null              → nunca submeteu pedido
 *   - status='pending'  → submetido, aguarda processamento da SOMAS
 *   - status='returned' → admin devolveu para correcções (artista pode editar)
 *   - status='approved' → tem nº SOMAS válido — pode licenciar a 100MT/faixa
 *   - status='rejected' → pedido recusado (raro — submete novo se quiser)
 *
 * Devolve sempre o registo MAIS RECENTE (artista pode ter várias tentativas).
 *
 * @param string $telemovel
 * @return object|null
 */
function rmbz_licensing_get_artist_somas_registration( $telemovel ) {
    global $wpdb;
    if ( empty($telemovel) ) return null;

    $table = $wpdb->prefix . 'rmbz_somas_registrations';
    return $wpdb->get_row( $wpdb->prepare(
        "SELECT * FROM {$table}
         WHERE artist_telemovel = %s
         ORDER BY created_at DESC
         LIMIT 1",
        $telemovel
    ) );
}

/**
 * Verifica rapidamente se o artista tem nº SOMAS aprovado.
 * Atalho usado no wizard.
 */
function rmbz_licensing_artist_has_approved_somas( $telemovel ) {
    $reg = rmbz_licensing_get_artist_somas_registration( $telemovel );
    return $reg && $reg->status === 'approved' && ! empty( $reg->somas_number );
}

/**
 * Devolve a licença activa para um release (pode estar pendente ou aprovada).
 * Releases não podem ter mais que uma licença não-rejeitada/não-reembolsada.
 *
 * @param int $release_id
 * @return object|null
 */
function rmbz_licensing_get_release_license( $release_id ) {
    global $wpdb;
    $release_id = (int) $release_id;
    if ( $release_id <= 0 ) return null;

    $table = $wpdb->prefix . 'rmbz_licenses';
    return $wpdb->get_row( $wpdb->prepare(
        "SELECT * FROM {$table}
         WHERE release_id = %d
           AND status NOT IN ('rejected','refunded')
         ORDER BY created_at DESC
         LIMIT 1",
        $release_id
    ) );
}

/**
 * Conta as faixas de um release (necessário para calcular preço).
 *
 * @param int $release_id
 * @return int
 */
function rmbz_licensing_count_release_tracks( $release_id ) {
    global $wpdb;
    $release_id = (int) $release_id;
    if ( $release_id <= 0 ) return 0;

    $table = $wpdb->prefix . 'rmbz_distro_tracks';
    return (int) $wpdb->get_var( $wpdb->prepare(
        "SELECT COUNT(*) FROM {$table} WHERE release_id = %d",
        $release_id
    ) );
}


/* ============================================================================
 * 4. CUPÕES — VALIDAÇÃO E APLICAÇÃO PARA LICENCIAMENTO
 * ============================================================================ */

/**
 * Valida e calcula desconto de cupão para um pedido de licenciamento.
 *
 * Reutiliza a tabela rmbz_coupons existente — o sistema já valida
 * usage_limit, expiry_date e status, mas só conhece reward_types antigos.
 * Aqui implementamos os 3 novos types específicos do licenciamento:
 *
 *   - 'licensing_discount_percent' → reward_value = % desconto (ex: 20 = 20%)
 *   - 'licensing_discount_fixed'   → reward_value = MT a descontar (ex: 50)
 *   - 'licensing_free_tracks'      → reward_value = N faixas grátis
 *
 * Devolve array:
 *   ['valid' => bool, 'error' => string, 'coupon' => object|null,
 *    'discount' => float, 'final_total' => float]
 *
 * @param string $code         Código submetido pelo utilizador
 * @param string $telemovel    Telemóvel do artista (para verificar uso prévio)
 * @param int    $track_count  Nº de faixas no pedido
 * @param float  $unit_price   Preço unitário (já com cupão? não — antes)
 * @return array
 */
function rmbz_licensing_validate_coupon( $code, $telemovel, $track_count, $unit_price ) {
    global $wpdb;

    $code = trim( strtoupper( (string) $code ) );
    $base_total = (float) $unit_price * (int) $track_count;

    if ( empty($code) ) {
        return [ 'valid' => false, 'error' => 'Código vazio.', 'coupon' => null,
                 'discount' => 0.00, 'final_total' => $base_total ];
    }

    $table_coupons = $wpdb->prefix . 'rmbz_coupons';
    $table_usage   = $wpdb->prefix . 'rmbz_coupon_usage';

    $coupon = $wpdb->get_row( $wpdb->prepare(
        "SELECT * FROM {$table_coupons} WHERE coupon_code = %s LIMIT 1", $code
    ) );

    if ( ! $coupon ) {
        return [ 'valid' => false, 'error' => 'Cupão não encontrado.', 'coupon' => null,
                 'discount' => 0.00, 'final_total' => $base_total ];
    }

    // Tipos aceites para licenciamento
    $allowed_types = [
        'licensing_discount_percent',
        'licensing_discount_fixed',
        'licensing_free_tracks',
    ];
    if ( ! in_array( $coupon->reward_type, $allowed_types, true ) ) {
        return [ 'valid' => false, 'error' => 'Este cupão não é válido para licenciamento.',
                 'coupon' => null, 'discount' => 0.00, 'final_total' => $base_total ];
    }

    // Validações standard: status, expiração, limite global, uso prévio
    if ( $coupon->status !== 'ativo' ) {
        return [ 'valid' => false, 'error' => 'Cupão inactivo.', 'coupon' => null,
                 'discount' => 0.00, 'final_total' => $base_total ];
    }
    if ( ! empty( $coupon->expiry_date ) && strtotime( $coupon->expiry_date ) < time() ) {
        return [ 'valid' => false, 'error' => 'Cupão expirado.', 'coupon' => null,
                 'discount' => 0.00, 'final_total' => $base_total ];
    }
    if ( $coupon->usage_limit > 0 && $coupon->used_count >= $coupon->usage_limit ) {
        return [ 'valid' => false, 'error' => 'Cupão esgotou o limite de utilizações.',
                 'coupon' => null, 'discount' => 0.00, 'final_total' => $base_total ];
    }

    $already_used = $wpdb->get_var( $wpdb->prepare(
        "SELECT COUNT(*) FROM {$table_usage} WHERE coupon_id = %d AND user_telemovel = %s",
        $coupon->id, $telemovel
    ) );
    if ( (int) $already_used > 0 ) {
        return [ 'valid' => false, 'error' => 'Já usaste este cupão antes.',
                 'coupon' => null, 'discount' => 0.00, 'final_total' => $base_total ];
    }

    // Calcular desconto consoante o tipo
    $discount = 0.00;
    switch ( $coupon->reward_type ) {
        case 'licensing_discount_percent':
            $pct = max( 0, min( 100, (float) $coupon->reward_value ) );
            $discount = round( $base_total * ($pct / 100), 2 );
            break;

        case 'licensing_discount_fixed':
            $discount = min( $base_total, (float) $coupon->reward_value );
            break;

        case 'licensing_free_tracks':
            // N faixas grátis — desconta o equivalente, até no máximo o total
            $free_tracks = max( 0, min( $track_count, (int) $coupon->reward_value ) );
            $discount = $free_tracks * (float) $unit_price;
            break;
    }

    $final_total = max( 0, $base_total - $discount );

    return [
        'valid'       => true,
        'error'       => '',
        'coupon'      => $coupon,
        'discount'    => $discount,
        'final_total' => $final_total,
    ];
}

/**
 * Marca um cupão como usado pelo artista. Chama-se DEPOIS do pagamento ter sucesso.
 * Idempotente — usa UNIQUE KEY (coupon_id, user_telemovel) na tabela.
 */
function rmbz_licensing_consume_coupon( $coupon_id, $telemovel ) {
    global $wpdb;
    $table_coupons = $wpdb->prefix . 'rmbz_coupons';
    $table_usage   = $wpdb->prefix . 'rmbz_coupon_usage';

    $wpdb->insert(
        $table_usage,
        [
            'coupon_id'      => (int) $coupon_id,
            'user_telemovel' => (string) $telemovel,
            'used_at'        => current_time('mysql'),
        ],
        [ '%d', '%s', '%s' ]
    );
    $wpdb->query( $wpdb->prepare(
        "UPDATE {$table_coupons} SET used_count = used_count + 1 WHERE id = %d",
        (int) $coupon_id
    ) );
}


/* ============================================================================
 * 4B. VALIDAÇÃO INTELIGENTE DE CAMPOS — anti-erro do utilizador
 * ============================================================================
 *
 * Pessoas distraídas escrevem o bairro no campo do nome, ou o telefone no
 * apelido. O admin acaba a perder tempo a devolver formulários por isso.
 *
 * Estas funções detectam padrões suspeitos e devolvem avisos AMARELOS
 * (não bloqueiam submissão — só alertam para o utilizador rever).
 * São usadas no servidor (PHP) e expostas via AJAX para o cliente também.
 *
 * Filosofia: "ajudar sem irritar". Falsos positivos são piores que falsos
 * negativos aqui — se temos dúvida, deixamos passar.
 * ──────────────────────────────────────────────────────────────────────── */

/**
 * Valida UM campo individual. Devolve array de avisos (vazio se ok).
 * Cada aviso = string em português a mostrar ao utilizador.
 *
 * @param string $field   Nome do campo (apelido, nome, bi_passaporte, ...)
 * @param string $value   Valor submetido
 * @param array  $context Outros campos do form (para validação cruzada)
 * @return array  Lista de avisos (strings)
 */
function rmbz_licensing_validate_field( $field, $value, $context = [] ) {
    $value = trim( (string) $value );
    if ( $value === '' ) return []; // Validação de obrigatoriedade é noutro lado

    $warnings = [];

    switch ( $field ) {
        case 'apelido':
        case 'nome':
            // Não devem ter dígitos (ninguém se chama "João123")
            if ( preg_match('/\d/', $value) ) {
                $warnings[] = 'Parece ter números — confirma que escreveste mesmo o nome.';
            }
            // Devem ter pelo menos 2 caracteres
            if ( mb_strlen($value) < 2 ) {
                $warnings[] = 'Parece muito curto.';
            }
            // Caracteres estranhos (@, #, etc) — só letras + espaços + apóstrofo + hífen
            if ( ! preg_match('/^[\p{L}\s\'\-]+$/u', $value) ) {
                $warnings[] = 'Tem caracteres não usuais num nome (@, #, etc).';
            }
            // "Bairro X" no campo do nome
            if ( preg_match('/\b(bairro|rua|avenida|av\.|n[º°ª]|av |rua )\b/iu', $value) ) {
                $warnings[] = 'Parece morada e não nome — verifica o campo correcto.';
            }
            break;

        case 'morada':
            // Morada deve ter pelo menos uma palavra que indique localização
            $localizacao_keywords = '/\b(bairro|rua|avenida|av\.|av |estrada|est\.|n[º°ª]|n\.\s*\d|quarteir|talhao|talhão|maputo|matola|nampula|beira|chimoio|tete|quelimane|pemba|inhambane|xai-xai)\b/iu';
            if ( ! preg_match($localizacao_keywords, $value) && mb_strlen($value) < 15 ) {
                $warnings[] = 'Parece incompleta — inclui Bairro/Rua/Avenida e número.';
            }
            // Morada que é só números é suspeita
            if ( preg_match('/^\d+$/', $value) ) {
                $warnings[] = 'Morada parece ser só números — falta o nome do local.';
            }
            break;

        case 'localidade':
            // Não deve ter números (Maputo, Matola, etc)
            if ( preg_match('/\d/', $value) ) {
                $warnings[] = 'Localidade não devia ter números.';
            }
            break;

        case 'bi_passaporte':
            // 2 formatos válidos:
            // - BI moçambicano: 12 dígitos + letra (ex: 110100123456A)
            //   ou 13 caracteres alfanuméricos
            // - Passaporte: 6-12 caracteres alfanuméricos (varia por país)
            $clean = strtoupper( preg_replace('/\s+/', '', $value) );
            $is_bi_mz = preg_match('/^\d{12,13}[A-Z]$/', $clean);
            $is_passport_like = preg_match('/^[A-Z0-9]{6,12}$/', $clean);
            if ( ! $is_bi_mz && ! $is_passport_like ) {
                $warnings[] = 'Formato não reconhecido. BI moçambicano: 12 dígitos + letra (ex: 110100123456A). Passaporte: 6-12 caracteres alfanuméricos.';
            }
            break;

        case 'data_nascimento':
            $ts = strtotime($value);
            if ( ! $ts ) {
                $warnings[] = 'Data inválida.';
            } else {
                $now = time();
                $age = (int) floor( ($now - $ts) / 31556952 ); // anos
                if ( $ts > $now ) {
                    $warnings[] = 'Data está no futuro.';
                } elseif ( $age < 12 ) {
                    $warnings[] = 'Idade parece muito baixa para registar direitos autorais.';
                } elseif ( $age > 110 ) {
                    $warnings[] = 'Idade parece improvável (>110 anos).';
                }
            }
            break;

        case 'data_emissao':
            $ts = strtotime($value);
            if ( ! $ts ) {
                $warnings[] = 'Data inválida.';
            } else {
                $now = time();
                if ( $ts > $now ) {
                    $warnings[] = 'Data de emissão não pode ser no futuro.';
                }
                // Validação cruzada: emissão deve ser depois do nascimento
                if ( ! empty($context['data_nascimento']) ) {
                    $nasc = strtotime($context['data_nascimento']);
                    if ( $nasc && $ts < $nasc ) {
                        $warnings[] = 'Data de emissão é anterior à data de nascimento.';
                    }
                    if ( $nasc && ($ts - $nasc) < 12 * 31556952 ) {
                        $warnings[] = 'Tinha menos de 12 anos quando o documento foi emitido — verifica.';
                    }
                }
            }
            break;

        case 'email':
            if ( ! is_email($value) ) {
                $warnings[] = 'Email não parece válido.';
            }
            break;

        case 'telemovel_contacto':
        case 'telefone':
            // Limpar tudo o que não é dígito
            $digits = preg_replace('/\D/', '', $value);
            // Telemóveis MZ têm 9 dígitos começando por 8 (84/85/86/87)
            // Aceita também com indicativo +258
            if ( strlen($digits) === 9 ) {
                if ( ! preg_match('/^8[2-7]/', $digits) ) {
                    $warnings[] = 'Número de 9 dígitos deve começar por 82, 83, 84, 85, 86 ou 87.';
                }
            } elseif ( strlen($digits) === 12 && strpos($digits, '258') === 0 ) {
                // OK, com indicativo
                $local = substr($digits, 3);
                if ( ! preg_match('/^8[2-7]/', $local) ) {
                    $warnings[] = 'Número moçambicano deve começar por 82, 83, 84, 85, 86 ou 87.';
                }
            } else {
                if ( $field === 'telemovel_contacto' ) {
                    $warnings[] = 'Formato esperado: 9 dígitos (84xxxxxxx) ou +258 84xxxxxxx.';
                }
                // telefone fixo é mais flexível, sem aviso
            }
            break;

        case 'nome_cartao':
            // Geralmente versão curta do nome+apelido. Avisar se MUITO diferente
            // dos campos nome+apelido (mais de 50% diferente).
            if ( ! empty($context['nome']) && ! empty($context['apelido']) ) {
                $combined = mb_strtolower(trim($context['nome'] . ' ' . $context['apelido']));
                $cartao = mb_strtolower($value);
                similar_text($combined, $cartao, $percent);
                if ( $percent < 30 ) {
                    $warnings[] = 'Não parece relacionado com o teu nome e apelido — verifica.';
                }
            }
            // Não deve ter dígitos
            if ( preg_match('/\d/', $value) ) {
                $warnings[] = 'Nome do cartão não devia ter números.';
            }
            break;

        case 'somas_number':
            // Formato típico: alguma combinação alfanumérica.
            // Aceitamos qualquer coisa entre 4-30 caracteres.
            if ( mb_strlen($value) < 4 ) {
                $warnings[] = 'Número parece muito curto — verifica.';
            }
            if ( mb_strlen($value) > 30 ) {
                $warnings[] = 'Número parece longo demais — verifica.';
            }
            break;
    }

    return $warnings;
}

/**
 * Valida o formulário inteiro. Devolve array [field => [warnings]].
 */
function rmbz_licensing_validate_form( array $form_data ) {
    $all_warnings = [];
    $fields_to_check = [
        'apelido', 'nome', 'morada', 'localidade', 'bi_passaporte',
        'data_nascimento', 'data_emissao', 'email', 'telemovel_contacto',
        'telefone', 'nome_cartao', 'somas_number'
    ];
    foreach ( $fields_to_check as $f ) {
        if ( ! isset($form_data[$f]) ) continue;
        $w = rmbz_licensing_validate_field( $f, $form_data[$f], $form_data );
        if ( ! empty($w) ) $all_warnings[$f] = $w;
    }
    return $all_warnings;
}

/**
 * AJAX: validar um campo em tempo real (usado pelo JS do formulário).
 */
function rmbz_licensing_ajax_validate_field() {
    if ( ! function_exists('rmbz_get_current_user_telemovel') || ! rmbz_get_current_user_telemovel() ) {
        wp_send_json_error(['msg' => 'Sessão expirada.'], 401);
    }
    $field = isset($_POST['field']) ? sanitize_key($_POST['field']) : '';
    $value = isset($_POST['value']) ? sanitize_text_field($_POST['value']) : '';
    $context = isset($_POST['context']) && is_array($_POST['context'])
        ? array_map('sanitize_text_field', $_POST['context']) : [];
    $warnings = rmbz_licensing_validate_field( $field, $value, $context );
    wp_send_json_success(['warnings' => $warnings]);
}
add_action('wp_ajax_rmbz_validate_somas_field', 'rmbz_licensing_ajax_validate_field');
add_action('wp_ajax_nopriv_rmbz_validate_somas_field', 'rmbz_licensing_ajax_validate_field');


/* ============================================================================
 * 5. SUBMISSÃO — REGISTO SOMAS (CAMINHO A: artista sem nº SOMAS)
 * ============================================================================ */

/**
 * Processa a submissão do formulário SOMAS pelo artista:
 *   1. Valida campos obrigatórios + ficheiro BI
 *   2. Verifica saldo da carteira (>= preço de registo)
 *   3. Faz upload do BI (validado: img/PDF, ≤10MB)
 *   4. DÉBITO: cobra preço de registo
 *   5. INSERT: cria registo somas com status='pending'
 *   6. Envia notificação email ao admin
 *
 * Atómico: se algo falhar depois do débito, faz rollback do saldo +
 * remove o ficheiro BI já uploaded.
 *
 * @param string $telemovel
 * @param array  $form_data  Campos do formulário SOMAS (sanitizados)
 * @param array  $bi_file    $_FILES['bi_file'] (ou null se re-submissão sem novo BI)
 * @return array  ['success' => bool, 'error' => string, 'registration_id' => int|null]
 */
function rmbz_licensing_submit_somas_registration( $telemovel, array $form_data, $bi_file = null ) {
    global $wpdb;

    if ( ! rmbz_licensing_is_enabled() ) {
        return [ 'success' => false, 'error' => 'Serviço de licenciamento desactivado temporariamente.', 'registration_id' => null ];
    }

    // Validação básica — campos obrigatórios para SOMAS
    $required = [ 'apelido', 'nome', 'morada', 'localidade', 'telemovel_contacto',
                  'email', 'bi_passaporte', 'local_emissao', 'data_emissao',
                  'nacionalidade', 'data_nascimento', 'nome_cartao' ];
    $missing = [];
    foreach ( $required as $field ) {
        if ( empty( $form_data[$field] ) ) $missing[] = $field;
    }
    if ( ! empty( $missing ) ) {
        return [ 'success' => false,
                 'error' => 'Campos obrigatórios em falta: ' . implode(', ', $missing),
                 'registration_id' => null ];
    }

    // Validar ficheiro BI obrigatório (excepto se for upload prévio re-aproveitado)
    if ( ! is_array($bi_file) || empty($bi_file['tmp_name']) ) {
        return [ 'success' => false,
                 'error' => 'Tens de anexar a foto/scan do BI ou Passaporte (campo obrigatório).',
                 'registration_id' => null ];
    }

    $bi_validation = rmbz_licensing_validate_bi_upload( $bi_file );
    if ( ! $bi_validation['valid'] ) {
        return [ 'success' => false, 'error' => $bi_validation['error'], 'registration_id' => null ];
    }

    // Verificar se já existe pedido pendente — não permite duplicados
    $existing = rmbz_licensing_get_artist_somas_registration( $telemovel );
    if ( $existing && in_array( $existing->status, ['pending', 'approved'], true ) ) {
        return [ 'success' => false,
                 'error' => 'Já tens um pedido SOMAS ' . ($existing->status === 'approved' ? 'aprovado' : 'em análise') . '.',
                 'registration_id' => null ];
    }

    // Verificar saldo
    $price = rmbz_licensing_get_registration_price();
    $balance = rmbz_get_wallet_balance_by_phone( $telemovel );
    if ( $balance < $price ) {
        return [ 'success' => false,
                 'error' => sprintf( 'Saldo insuficiente. Precisas de %.2f MT (tens %.2f MT). Carrega a tua carteira primeiro.', $price, $balance ),
                 'registration_id' => null ];
    }

    // Fazer upload do BI ANTES de cobrar (se upload falha, não deixamos o artista pagar à toa)
    $bi_upload = rmbz_licensing_handle_bi_upload( $bi_file, $telemovel );
    if ( ! $bi_upload['success'] ) {
        return [ 'success' => false,
                 'error' => 'Erro ao guardar o BI: ' . $bi_upload['error'],
                 'registration_id' => null ];
    }

    // Cobrar da carteira
    $debit = rmbz_update_wallet_balance(
        $telemovel,
        -$price,
        'licensing_somas_fee',
        null,
        'Taxa de registo na SOMAS (Licenciamento musical)'
    );
    if ( ! $debit['success'] ) {
        // ROLLBACK: apagar o ficheiro BI já uploaded
        if ( ! empty($bi_upload['path']) && file_exists($bi_upload['path']) ) {
            @unlink($bi_upload['path']);
        }
        return [ 'success' => false,
                 'error' => 'Falha ao cobrar da carteira: ' . ($debit['error'] ?? 'desconhecido'),
                 'registration_id' => null ];
    }

    // Inserir registo
    $table = $wpdb->prefix . 'rmbz_somas_registrations';
    $now = current_time('mysql');
    $inserted = $wpdb->insert(
        $table,
        [
            'artist_telemovel'      => $telemovel,
            'status'                => 'pending',
            'somas_number'          => null,
            'form_data'             => wp_json_encode( $form_data ),
            'bi_file_url'           => $bi_upload['url'],
            'bi_file_path'          => $bi_upload['path'],
            'amount_charged'        => $price,
            'wallet_transaction_id' => isset($debit['transaction_id']) ? (int) $debit['transaction_id'] : null,
            'created_at'            => $now,
            'updated_at'            => $now,
        ],
        [ '%s','%s','%s','%s','%s','%s','%f','%d','%s','%s' ]
    );

    if ( $inserted === false ) {
        // ROLLBACK do débito + ficheiro BI
        if ( ! empty($bi_upload['path']) && file_exists($bi_upload['path']) ) {
            @unlink($bi_upload['path']);
        }
        rmbz_update_wallet_balance(
            $telemovel,
            $price,
            'licensing_refund',
            null,
            'Reversão automática: falha ao gravar registo SOMAS'
        );
        return [ 'success' => false,
                 'error' => 'Erro ao gravar pedido (saldo devolvido).',
                 'registration_id' => null ];
    }

    $registration_id = (int) $wpdb->insert_id;

    // Notificar admin
    if ( function_exists('wp_mail') ) {
        $admin_email = get_option('admin_email');
        $artist_name = $form_data['nome'] . ' ' . $form_data['apelido'];
        wp_mail(
            $admin_email,
            '[1MZ] Novo pedido de registo SOMAS - ' . $artist_name,
            "O artista {$artist_name} ({$telemovel}) submeteu um pedido de registo SOMAS.\n\n" .
            "Foi cobrada a quantia de {$price} MT da carteira.\n\n" .
            "Acede ao painel para processar (lembra-te de validar o BI):\n" .
            admin_url('admin.php?page=rmbz-licensing&tab=somas&id=' . $registration_id)
        );
    }

    return [ 'success' => true, 'error' => '', 'registration_id' => $registration_id ];
}

/**
 * Valida um upload do BI (tamanho, tipo, integridade).
 * Não move o ficheiro — apenas valida o $_FILES.
 *
 * Aceites: JPG, PNG, PDF. Tamanho máximo: 10MB.
 *
 * @param array $file  $_FILES['nome_campo']
 * @return array ['valid' => bool, 'error' => string]
 */
function rmbz_licensing_validate_bi_upload( $file ) {
    if ( ! is_array($file) ) {
        return [ 'valid' => false, 'error' => 'Ficheiro inválido.' ];
    }

    // Erro do PHP no upload
    if ( ! empty($file['error']) && (int)$file['error'] !== UPLOAD_ERR_OK ) {
        $php_errors = [
            UPLOAD_ERR_INI_SIZE   => 'Ficheiro maior que o permitido pelo servidor.',
            UPLOAD_ERR_FORM_SIZE  => 'Ficheiro maior que o permitido pelo formulário.',
            UPLOAD_ERR_PARTIAL    => 'Ficheiro foi enviado parcialmente.',
            UPLOAD_ERR_NO_FILE    => 'Nenhum ficheiro foi enviado.',
            UPLOAD_ERR_NO_TMP_DIR => 'Erro de sistema (pasta temporária).',
            UPLOAD_ERR_CANT_WRITE => 'Erro de sistema (escrita).',
        ];
        return [ 'valid' => false,
                 'error' => $php_errors[ $file['error'] ] ?? 'Erro desconhecido no upload.' ];
    }

    if ( empty($file['tmp_name']) || ! is_uploaded_file($file['tmp_name']) ) {
        return [ 'valid' => false, 'error' => 'Ficheiro inválido.' ];
    }

    // Tamanho ≤ 10 MB
    $max_bytes = 10 * 1024 * 1024;
    if ( (int) $file['size'] > $max_bytes ) {
        return [ 'valid' => false,
                 'error' => sprintf('Ficheiro demasiado grande (máximo: 10 MB, actual: %.1f MB).', $file['size'] / 1024 / 1024) ];
    }

    // Verificar tipo (não confiar no client) — usar wp_check_filetype_and_ext
    if ( ! function_exists('wp_check_filetype_and_ext') ) {
        require_once ABSPATH . 'wp-admin/includes/file.php';
    }
    $allowed_mimes = [
        'jpg|jpeg' => 'image/jpeg',
        'png'      => 'image/png',
        'pdf'      => 'application/pdf',
    ];
    $check = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'], $allowed_mimes );
    if ( empty($check['ext']) || empty($check['type']) ) {
        return [ 'valid' => false,
                 'error' => 'Formato não aceite. Usa JPG, PNG ou PDF.' ];
    }

    return [ 'valid' => true, 'error' => '' ];
}

/**
 * Move o ficheiro BI para uploads/. Devolve URL e path absoluto.
 * Renomeia o ficheiro com hash random para impedir guess de URLs.
 *
 * @param array  $file
 * @param string $telemovel  (usado no nome para distinguir)
 * @return array  ['success' => bool, 'url' => string, 'path' => string, 'error' => string]
 */
function rmbz_licensing_handle_bi_upload( $file, $telemovel ) {
    if ( ! function_exists('wp_handle_upload') ) {
        require_once ABSPATH . 'wp-admin/includes/file.php';
    }

    // Renomear: bi_<telemovel>_<random>.<ext> — random impede guess das URLs
    if ( ! function_exists('wp_check_filetype') ) {
        require_once ABSPATH . 'wp-admin/includes/file.php';
    }
    $ftype = wp_check_filetype( $file['name'] );
    $ext = strtolower( $ftype['ext'] ?: 'bin' );
    if ( $ext === 'jpeg' ) $ext = 'jpg';

    $tel_safe = preg_replace('/[^0-9]/', '', $telemovel);
    $random = wp_generate_password( 24, false, false );
    $new_name = "bi_{$tel_safe}_{$random}.{$ext}";

    $file['name'] = $new_name;

    // Forçar mimes aceites no wp_handle_upload (defesa em profundidade)
    $overrides = [
        'test_form' => false,
        'mimes' => [
            'jpg|jpeg' => 'image/jpeg',
            'png'      => 'image/png',
            'pdf'      => 'application/pdf',
        ],
    ];
    $uploaded = wp_handle_upload( $file, $overrides );

    if ( ! is_array($uploaded) || isset($uploaded['error']) ) {
        return [
            'success' => false,
            'url' => '',
            'path' => '',
            'error' => $uploaded['error'] ?? 'Erro desconhecido ao guardar.',
        ];
    }

    return [
        'success' => true,
        'url'     => $uploaded['url'],
        'path'    => $uploaded['file'],
        'error'   => '',
    ];
}


/* ============================================================================
 * 5B. SUBMISSÃO — MEMBRO EXISTENTE SOMAS (CAMINHO B)
 * ============================================================================
 *
 * Para artistas que já se cadastraram na SOMAS por conta própria. O
 * formulário é mais curto: número SOMAS + comprovante (cartão/documento que
 * a SOMAS enviou) + BI/Passaporte para validação.
 *
 * O admin valida que (a) o nº é genuíno, (b) o comprovante bate com o nº,
 * (c) o BI corresponde ao titular do registo SOMAS — e aprova.
 *
 * Cobrança configurável (default 0 MT, mas admin pode mudar).
 */
function rmbz_licensing_submit_existing_member( $telemovel, array $form_data, $bi_file = null, $somas_card_file = null ) {
    global $wpdb;

    if ( ! rmbz_licensing_is_enabled() ) {
        return [ 'success' => false, 'error' => 'Serviço de licenciamento desactivado temporariamente.', 'registration_id' => null ];
    }

    // Validação: campos obrigatórios para este caminho
    $required = [ 'apelido', 'nome', 'email', 'somas_number' ];
    $missing = [];
    foreach ( $required as $field ) {
        if ( empty( $form_data[$field] ) ) $missing[] = $field;
    }
    if ( ! empty( $missing ) ) {
        return [ 'success' => false,
                 'error' => 'Campos obrigatórios em falta: ' . implode(', ', $missing),
                 'registration_id' => null ];
    }

    // Ficheiros obrigatórios: BI + comprovante SOMAS
    if ( ! is_array($bi_file) || empty($bi_file['tmp_name']) ) {
        return [ 'success' => false,
                 'error' => 'Tens de anexar a foto/scan do BI ou Passaporte.',
                 'registration_id' => null ];
    }
    $bi_validation = rmbz_licensing_validate_bi_upload( $bi_file );
    if ( ! $bi_validation['valid'] ) {
        return [ 'success' => false, 'error' => 'BI: ' . $bi_validation['error'], 'registration_id' => null ];
    }

    if ( ! is_array($somas_card_file) || empty($somas_card_file['tmp_name']) ) {
        return [ 'success' => false,
                 'error' => 'Tens de anexar o documento de inscrição que a SOMAS te enviou.',
                 'registration_id' => null ];
    }
    $card_validation = rmbz_licensing_validate_bi_upload( $somas_card_file ); // mesmas regras
    if ( ! $card_validation['valid'] ) {
        return [ 'success' => false, 'error' => 'Comprovante SOMAS: ' . $card_validation['error'], 'registration_id' => null ];
    }

    // Não permitir duplicados
    $existing = rmbz_licensing_get_artist_somas_registration( $telemovel );
    if ( $existing && in_array( $existing->status, ['pending', 'approved'], true ) ) {
        return [ 'success' => false,
                 'error' => 'Já tens um pedido SOMAS ' . ($existing->status === 'approved' ? 'aprovado' : 'em análise') . '.',
                 'registration_id' => null ];
    }

    // Verificar saldo (preço pode ser 0)
    $price = rmbz_licensing_get_existing_member_price();
    if ( $price > 0 ) {
        $balance = rmbz_get_wallet_balance_by_phone( $telemovel );
        if ( $balance < $price ) {
            return [ 'success' => false,
                     'error' => sprintf( 'Saldo insuficiente. Precisas de %.2f MT (tens %.2f MT).', $price, $balance ),
                     'registration_id' => null ];
        }
    }

    // Upload dos 2 ficheiros ANTES de cobrar
    $bi_upload = rmbz_licensing_handle_bi_upload( $bi_file, $telemovel );
    if ( ! $bi_upload['success'] ) {
        return [ 'success' => false, 'error' => 'Erro ao guardar BI: ' . $bi_upload['error'], 'registration_id' => null ];
    }

    $card_upload = rmbz_licensing_handle_bi_upload( $somas_card_file, $telemovel . '_card' );
    if ( ! $card_upload['success'] ) {
        // Rollback do BI
        if ( ! empty($bi_upload['path']) && file_exists($bi_upload['path']) ) @unlink($bi_upload['path']);
        return [ 'success' => false, 'error' => 'Erro ao guardar comprovante: ' . $card_upload['error'], 'registration_id' => null ];
    }

    // Cobrar (se preço > 0)
    $debit_transaction_id = null;
    if ( $price > 0 ) {
        $debit = rmbz_update_wallet_balance(
            $telemovel,
            -$price,
            'licensing_somas_validation_fee',
            null,
            'Validação de membro SOMAS existente (Licenciamento)'
        );
        if ( ! $debit['success'] ) {
            // Rollback dos uploads
            if ( ! empty($bi_upload['path']) && file_exists($bi_upload['path']) ) @unlink($bi_upload['path']);
            if ( ! empty($card_upload['path']) && file_exists($card_upload['path']) ) @unlink($card_upload['path']);
            return [ 'success' => false,
                     'error' => 'Falha ao cobrar: ' . ($debit['error'] ?? 'desconhecido'),
                     'registration_id' => null ];
        }
        $debit_transaction_id = isset($debit['transaction_id']) ? (int) $debit['transaction_id'] : null;
    }

    // Inserir registo
    $table = $wpdb->prefix . 'rmbz_somas_registrations';
    $now = current_time('mysql');
    $inserted = $wpdb->insert(
        $table,
        [
            'artist_telemovel'      => $telemovel,
            'submission_type'       => 'existing_member',
            'status'                => 'pending',
            'somas_number'          => sanitize_text_field( $form_data['somas_number'] ),
            'form_data'             => wp_json_encode( $form_data ),
            'bi_file_url'           => $bi_upload['url'],
            'bi_file_path'          => $bi_upload['path'],
            'somas_card_file_url'   => $card_upload['url'],
            'somas_card_file_path'  => $card_upload['path'],
            'amount_charged'        => $price,
            'wallet_transaction_id' => $debit_transaction_id,
            'created_at'            => $now,
            'updated_at'            => $now,
        ],
        [ '%s','%s','%s','%s','%s','%s','%s','%s','%s','%f','%d','%s','%s' ]
    );

    if ( $inserted === false ) {
        // Rollback completo
        if ( ! empty($bi_upload['path']) && file_exists($bi_upload['path']) ) @unlink($bi_upload['path']);
        if ( ! empty($card_upload['path']) && file_exists($card_upload['path']) ) @unlink($card_upload['path']);
        if ( $price > 0 ) {
            rmbz_update_wallet_balance(
                $telemovel, $price, 'licensing_refund', null,
                'Reversão automática: falha ao gravar validação SOMAS'
            );
        }
        return [ 'success' => false,
                 'error' => 'Erro ao gravar pedido' . ($price > 0 ? ' (saldo devolvido)' : '') . '.',
                 'registration_id' => null ];
    }

    $registration_id = (int) $wpdb->insert_id;

    // Notificar admin
    if ( function_exists('wp_mail') ) {
        $artist_name = ($form_data['nome'] ?? '') . ' ' . ($form_data['apelido'] ?? '');
        wp_mail(
            get_option('admin_email'),
            '[1MZ] Validação de membro SOMAS - ' . $artist_name,
            "O artista {$artist_name} ({$telemovel}) afirma ser membro SOMAS:\n\n" .
            "Nº SOMAS declarado: {$form_data['somas_number']}\n" .
            "Foi cobrado: " . number_format($price, 2, ',', '.') . " MT\n\n" .
            "Valida o comprovante + BI antes de aprovar:\n" .
            admin_url('admin.php?page=rmbz-licensing&tab=somas&id=' . $registration_id)
        );
    }

    return [ 'success' => true, 'error' => '', 'registration_id' => $registration_id ];
}


/* ============================================================================
 * 6. SUBMISSÃO — LICENCIAMENTO DE RELEASE (CAMINHO B: artista com nº SOMAS)
 * ============================================================================ */

/**
 * Submete pedido de licenciamento para um release.
 *
 * Pré-requisitos:
 *   - Artista tem nº SOMAS aprovado
 *   - Release existe e pertence ao artista
 *   - Release tem pelo menos 1 faixa
 *   - Release ainda não tem licença activa
 *   - Saldo suficiente (após cupão)
 *
 * @param string $telemovel
 * @param int    $release_id
 * @param string $coupon_code  (opcional)
 * @return array  ['success' => bool, 'error' => string, 'license_id' => int|null,
 *                 'amount_charged' => float, 'discount' => float]
 */
function rmbz_licensing_submit_release_license( $telemovel, $release_id, $coupon_code = '' ) {
    global $wpdb;
    $release_id = (int) $release_id;

    if ( ! rmbz_licensing_is_enabled() ) {
        return [ 'success' => false, 'error' => 'Serviço de licenciamento desactivado temporariamente.', 'license_id' => null, 'amount_charged' => 0, 'discount' => 0 ];
    }

    // 1. Verificar nº SOMAS
    $somas_reg = rmbz_licensing_get_artist_somas_registration( $telemovel );
    if ( ! $somas_reg || $somas_reg->status !== 'approved' || empty($somas_reg->somas_number) ) {
        return [ 'success' => false,
                 'error' => 'Precisas de ter um nº SOMAS aprovado para licenciar.',
                 'license_id' => null, 'amount_charged' => 0, 'discount' => 0 ];
    }

    // 2. Verificar release pertence ao artista
    $rel_table = $wpdb->prefix . 'rmbz_distro_releases';
    $release = $wpdb->get_row( $wpdb->prepare(
        "SELECT id, title, artist_telemovel FROM {$rel_table}
         WHERE id = %d AND artist_telemovel = %s",
        $release_id, $telemovel
    ) );
    if ( ! $release ) {
        return [ 'success' => false, 'error' => 'Release não encontrado.',
                 'license_id' => null, 'amount_charged' => 0, 'discount' => 0 ];
    }

    // 3. Não pode haver licença activa (pending/processing/approved)
    $existing = rmbz_licensing_get_release_license( $release_id );
    if ( $existing ) {
        return [ 'success' => false,
                 'error' => 'Este release já tem um pedido de licenciamento ' . $existing->status . '.',
                 'license_id' => null, 'amount_charged' => 0, 'discount' => 0 ];
    }

    // 4. Contar faixas
    $track_count = rmbz_licensing_count_release_tracks( $release_id );
    if ( $track_count < 1 ) {
        return [ 'success' => false, 'error' => 'Release sem faixas — adiciona faixas primeiro.',
                 'license_id' => null, 'amount_charged' => 0, 'discount' => 0 ];
    }

    // 5. Calcular preço (com cupão se houver)
    $unit_price = rmbz_licensing_get_per_track_price();
    $base_total = $unit_price * $track_count;
    $discount = 0.00;
    $coupon_id = null;
    $coupon_obj = null;

    if ( ! empty( $coupon_code ) ) {
        $check = rmbz_licensing_validate_coupon( $coupon_code, $telemovel, $track_count, $unit_price );
        if ( ! $check['valid'] ) {
            return [ 'success' => false, 'error' => 'Cupão inválido: ' . $check['error'],
                     'license_id' => null, 'amount_charged' => 0, 'discount' => 0 ];
        }
        $discount = $check['discount'];
        $coupon_obj = $check['coupon'];
        $coupon_id = (int) $coupon_obj->id;
    }
    $final_total = max( 0, $base_total - $discount );

    // 6. Verificar saldo (apenas se preço > 0)
    if ( $final_total > 0 ) {
        $balance = rmbz_get_wallet_balance_by_phone( $telemovel );
        if ( $balance < $final_total ) {
            return [ 'success' => false,
                     'error' => sprintf( 'Saldo insuficiente. Precisas de %.2f MT (tens %.2f MT).', $final_total, $balance ),
                     'license_id' => null, 'amount_charged' => 0, 'discount' => 0 ];
        }
    }

    // 7. Cobrar (se preço > 0)
    $debit_transaction_id = null;
    if ( $final_total > 0 ) {
        $debit = rmbz_update_wallet_balance(
            $telemovel,
            -$final_total,
            'licensing_track_fee',
            $release_id,
            sprintf( 'Licenciamento de "%s" (%d %s × %.2f MT%s)',
                $release->title,
                $track_count,
                $track_count === 1 ? 'faixa' : 'faixas',
                $unit_price,
                $discount > 0 ? sprintf(' − %.2f desconto', $discount) : ''
            )
        );
        if ( ! $debit['success'] ) {
            return [ 'success' => false,
                     'error' => 'Falha ao cobrar: ' . ($debit['error'] ?? 'desconhecido'),
                     'license_id' => null, 'amount_charged' => 0, 'discount' => 0 ];
        }
        $debit_transaction_id = isset($debit['transaction_id']) ? (int) $debit['transaction_id'] : null;
    }

    // 8. Inserir licença
    $table = $wpdb->prefix . 'rmbz_licenses';
    $now = current_time('mysql');
    $inserted = $wpdb->insert(
        $table,
        [
            'release_id'            => $release_id,
            'artist_telemovel'      => $telemovel,
            'somas_number'          => $somas_reg->somas_number,
            'status'                => 'pending',
            'track_count'           => $track_count,
            'unit_price'            => $unit_price,
            'total_price'           => $base_total,
            'coupon_id'             => $coupon_id,
            'coupon_discount'       => $discount,
            'amount_charged'        => $final_total,
            'wallet_transaction_id' => $debit_transaction_id,
            'created_at'            => $now,
            'updated_at'            => $now,
        ],
        [ '%d','%s','%s','%s','%d','%f','%f','%d','%f','%f','%d','%s','%s' ]
    );

    if ( $inserted === false ) {
        // ROLLBACK do débito
        if ( $final_total > 0 ) {
            rmbz_update_wallet_balance(
                $telemovel, $final_total, 'licensing_refund', $release_id,
                'Reversão automática: falha ao gravar licença'
            );
        }
        return [ 'success' => false, 'error' => 'Erro ao gravar pedido (saldo devolvido).',
                 'license_id' => null, 'amount_charged' => 0, 'discount' => 0 ];
    }

    $license_id = (int) $wpdb->insert_id;

    // 9. Consumir cupão (depois do sucesso)
    if ( $coupon_obj ) {
        rmbz_licensing_consume_coupon( $coupon_id, $telemovel );
    }

    // 10. Notificar admin
    if ( function_exists('wp_mail') ) {
        wp_mail(
            get_option('admin_email'),
            '[1MZ] Novo pedido de licenciamento - ' . $release->title,
            "Artista: {$telemovel}\nRelease: {$release->title}\nFaixas: {$track_count}\n" .
            "Cobrado: {$final_total} MT" . ($discount > 0 ? " (desconto cupão: {$discount} MT)" : '') . "\n\n" .
            admin_url('admin.php?page=rmbz-licensing&tab=licenses&id=' . $license_id)
        );
    }

    return [
        'success'        => true,
        'error'          => '',
        'license_id'     => $license_id,
        'amount_charged' => $final_total,
        'discount'       => $discount,
    ];
}


/* ============================================================================
 * 7. AÇÕES DO ADMIN — APROVAR/REJEITAR/DEVOLVER (com reembolso automático)
 * ============================================================================ */

/**
 * Admin aprova um registo SOMAS, atribuindo o nº oficial.
 * A partir deste momento, o artista pode licenciar releases a 100MT/faixa.
 *
 * @param int    $registration_id
 * @param string $somas_number    Nº atribuído pela SOMAS (ex: "MZ-2026-12345")
 * @param string $admin_note      (opcional)
 * @return array
 */
function rmbz_licensing_admin_approve_somas( $registration_id, $somas_number, $admin_note = '' ) {
    global $wpdb;
    $table = $wpdb->prefix . 'rmbz_somas_registrations';
    $registration_id = (int) $registration_id;
    $somas_number = sanitize_text_field( $somas_number );

    if ( empty($somas_number) ) {
        return [ 'success' => false, 'error' => 'Número SOMAS obrigatório.' ];
    }

    $reg = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $registration_id ) );
    if ( ! $reg ) return [ 'success' => false, 'error' => 'Registo não encontrado.' ];
    if ( $reg->status === 'approved' ) return [ 'success' => false, 'error' => 'Já aprovado.' ];

    $wpdb->update( $table,
        [
            'status'       => 'approved',
            'somas_number' => $somas_number,
            'admin_note'   => $admin_note ?: $reg->admin_note,
            'approved_at'  => current_time('mysql'),
            'updated_at'   => current_time('mysql'),
        ],
        [ 'id' => $registration_id ],
        [ '%s','%s','%s','%s','%s' ], [ '%d' ]
    );

    // Notificar artista
    rmbz_licensing_notify_artist_somas_approved( $reg, $somas_number );

    // [1.5.184] Hook para sistema de notificações inline (banner no topo).
    do_action( 'rmbz_somas_registration_approved', $reg, $somas_number );

    return [ 'success' => true ];
}

/**
 * Admin devolve o registo ao artista para correcções (status -> 'returned').
 */
function rmbz_licensing_admin_return_somas( $registration_id, $reason ) {
    global $wpdb;
    $table = $wpdb->prefix . 'rmbz_somas_registrations';
    $registration_id = (int) $registration_id;

    $reg = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $registration_id ) );
    if ( ! $reg ) return [ 'success' => false, 'error' => 'Registo não encontrado.' ];

    $wpdb->update( $table,
        [
            'status'     => 'returned',
            'admin_note' => sanitize_textarea_field( $reason ),
            'updated_at' => current_time('mysql'),
        ],
        [ 'id' => $registration_id ],
        [ '%s','%s','%s' ], [ '%d' ]
    );

    rmbz_licensing_notify_artist_somas_returned( $reg, $reason );

    // [1.5.184] Hook para sistema de notificações inline.
    do_action( 'rmbz_somas_registration_returned', $reg, $reason );

    return [ 'success' => true ];
}

/**
 * Admin rejeita definitivamente um registo SOMAS e devolve a taxa de 700 MT.
 */
function rmbz_licensing_admin_reject_somas( $registration_id, $reason ) {
    global $wpdb;
    $table = $wpdb->prefix . 'rmbz_somas_registrations';
    $registration_id = (int) $registration_id;

    $reg = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $registration_id ) );
    if ( ! $reg ) return [ 'success' => false, 'error' => 'Registo não encontrado.' ];
    if ( $reg->status === 'rejected' ) return [ 'success' => false, 'error' => 'Já rejeitado.' ];

    // Reembolsar
    if ( (float) $reg->amount_charged > 0 ) {
        rmbz_update_wallet_balance(
            $reg->artist_telemovel,
            (float) $reg->amount_charged,
            'licensing_refund',
            null,
            sprintf( 'Reembolso registo SOMAS #%d: %s', $registration_id, $reason )
        );
    }

    $wpdb->update( $table,
        [
            'status'     => 'rejected',
            'admin_note' => sanitize_textarea_field( $reason ),
            'updated_at' => current_time('mysql'),
        ],
        [ 'id' => $registration_id ],
        [ '%s','%s','%s' ], [ '%d' ]
    );

    rmbz_licensing_notify_artist_somas_rejected( $reg, $reason );

    // [1.5.184] Hook para sistema de notificações inline.
    do_action( 'rmbz_somas_registration_rejected', $reg, $reason );

    return [ 'success' => true ];
}

/**
 * Admin marca a licença como aprovada (processada com sucesso na SOMAS).
 */
function rmbz_licensing_admin_approve_license( $license_id, $admin_note = '' ) {
    global $wpdb;
    $table = $wpdb->prefix . 'rmbz_licenses';
    $license_id = (int) $license_id;

    $lic = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $license_id ) );
    if ( ! $lic ) return [ 'success' => false, 'error' => 'Licença não encontrada.' ];
    if ( $lic->status === 'approved' ) return [ 'success' => false, 'error' => 'Já aprovada.' ];

    $wpdb->update( $table,
        [
            'status'       => 'approved',
            'admin_note'   => $admin_note ?: $lic->admin_note,
            'completed_at' => current_time('mysql'),
            'updated_at'   => current_time('mysql'),
        ],
        [ 'id' => $license_id ],
        [ '%s','%s','%s','%s' ], [ '%d' ]
    );

    rmbz_licensing_notify_artist_license_approved( $lic );

    // [1.5.184] Hook para sistema de notificações inline.
    do_action( 'rmbz_somas_license_approved', $lic );

    return [ 'success' => true ];
}

/**
 * Admin rejeita licença e DEVOLVE AUTOMATICAMENTE o valor cobrado.
 *
 * Esta é a função mais sensível — protegida com checks múltiplos para evitar
 * dupla devolução em caso de cliques repetidos.
 */
function rmbz_licensing_admin_reject_license( $license_id, $reason ) {
    global $wpdb;
    $table = $wpdb->prefix . 'rmbz_licenses';
    $license_id = (int) $license_id;

    $lic = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $license_id ) );
    if ( ! $lic ) return [ 'success' => false, 'error' => 'Licença não encontrada.' ];
    if ( in_array( $lic->status, ['rejected','refunded'], true ) ) {
        return [ 'success' => false, 'error' => 'Já rejeitada/reembolsada.' ];
    }

    // Reembolso
    $refund_transaction_id = null;
    if ( (float) $lic->amount_charged > 0 ) {
        $credit = rmbz_update_wallet_balance(
            $lic->artist_telemovel,
            (float) $lic->amount_charged,
            'licensing_refund',
            (int) $lic->release_id,
            sprintf( 'Reembolso licenciamento #%d: %s', $license_id, $reason )
        );
        if ( ! $credit['success'] ) {
            return [ 'success' => false,
                     'error' => 'Falha ao reembolsar: ' . ($credit['error'] ?? 'desconhecido') ];
        }
        $refund_transaction_id = isset($credit['transaction_id']) ? (int) $credit['transaction_id'] : null;
    }

    $wpdb->update( $table,
        [
            'status'                => 'refunded',
            'refund_transaction_id' => $refund_transaction_id,
            'admin_note'            => sanitize_textarea_field( $reason ),
            'completed_at'          => current_time('mysql'),
            'updated_at'            => current_time('mysql'),
        ],
        [ 'id' => $license_id ],
        [ '%s','%d','%s','%s','%s' ], [ '%d' ]
    );

    rmbz_licensing_notify_artist_license_rejected( $lic, $reason );

    // [1.5.184] Hook para sistema de notificações inline.
    do_action( 'rmbz_somas_license_rejected', $lic, $reason );

    return [ 'success' => true ];
}


/* ============================================================================
 * 8. NOTIFICAÇÕES — emails ao artista em mudanças de estado
 * ============================================================================ */

function rmbz_licensing_get_artist_email( $telemovel ) {
    global $wpdb;
    return $wpdb->get_var( $wpdb->prepare(
        "SELECT user_email FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel = %s",
        $telemovel
    ) );
}

function rmbz_licensing_notify_artist_somas_approved( $reg, $somas_number ) {
    $email = rmbz_licensing_get_artist_email( $reg->artist_telemovel );
    if ( ! $email ) return;
    wp_mail(
        $email,
        '[1MZ] Registo SOMAS aprovado!',
        "O teu registo na SOMAS foi aprovado.\n\nNúmero atribuído: {$somas_number}\n\n" .
        "Já podes licenciar os teus lançamentos a " . rmbz_licensing_get_per_track_price() . " MT por faixa.\n\n" .
        "Vai ao painel para começar a licenciar."
    );
}

function rmbz_licensing_notify_artist_somas_returned( $reg, $reason ) {
    $email = rmbz_licensing_get_artist_email( $reg->artist_telemovel );
    if ( ! $email ) return;
    wp_mail(
        $email,
        '[1MZ] Pedido SOMAS - correções necessárias',
        "O teu pedido SOMAS precisa de correções:\n\n{$reason}\n\nVai ao painel para corrigir e re-submeter."
    );
}

function rmbz_licensing_notify_artist_somas_rejected( $reg, $reason ) {
    $email = rmbz_licensing_get_artist_email( $reg->artist_telemovel );
    if ( ! $email ) return;
    wp_mail(
        $email,
        '[1MZ] Pedido SOMAS rejeitado - reembolso processado',
        "O teu pedido SOMAS foi rejeitado.\n\nMotivo: {$reason}\n\n" .
        "A quantia de {$reg->amount_charged} MT foi devolvida à tua carteira."
    );
}

function rmbz_licensing_notify_artist_license_approved( $lic ) {
    $email = rmbz_licensing_get_artist_email( $lic->artist_telemovel );
    if ( ! $email ) return;
    wp_mail(
        $email,
        '[1MZ] Licenciamento aprovado',
        "O teu pedido de licenciamento foi processado com sucesso na SOMAS."
    );
}

function rmbz_licensing_notify_artist_license_rejected( $lic, $reason ) {
    $email = rmbz_licensing_get_artist_email( $lic->artist_telemovel );
    if ( ! $email ) return;
    wp_mail(
        $email,
        '[1MZ] Licenciamento rejeitado - reembolso processado',
        "O teu pedido de licenciamento foi rejeitado.\n\nMotivo: {$reason}\n\n" .
        "A quantia de {$lic->amount_charged} MT foi devolvida à tua carteira."
    );
}


/* ============================================================================
 * 9. FRONTEND — RENDER DO FORMULÁRIO SOMAS PARA O ARTISTA
 * ============================================================================ */

/**
 * Renderiza o formulário SOMAS para o artista preencher.
 * Pré-preenche com os dados que já temos na carteira (nome, telemóvel, email).
 *
 * Estado mostrado depende do registo actual:
 *   - sem registo / status='returned' → formulário editável
 *   - status='pending' → mensagem "em análise"
 *   - status='approved' → mostra nº SOMAS atribuído
 *   - status='rejected' → mostra motivo + botão "Submeter novo"
 */
function rmbz_licensing_render_somas_form( $telemovel ) {
    global $wpdb;

    if ( ! rmbz_licensing_is_enabled() ) {
        rmbz_licensing_render_disabled_notice();
        return;
    }

    $reg = rmbz_licensing_get_artist_somas_registration( $telemovel );
    $price = rmbz_licensing_get_registration_price();
    $existing_member_price = rmbz_licensing_get_existing_member_price();
    $per_track = rmbz_licensing_get_per_track_price();
    $balance = rmbz_get_wallet_balance_by_phone( $telemovel );

    // Estado: APROVADO — mostra info, pronto para licenciar
    if ( $reg && $reg->status === 'approved' ) {
        ?>
        <div class="rmbz-licensing-status rmbz-licensing-status--ok">
            <div class="rmbz-licensing-status__icon"><span class="ms" aria-hidden="true">verified</span></div>
            <h3>Estás registado na SOMAS</h3>
            <p>Número SOMAS: <strong><?php echo esc_html( $reg->somas_number ); ?></strong></p>
            <p class="rmbz-licensing-status__note">
                Podes licenciar os teus lançamentos por <?php echo number_format($per_track, 2, ',', '.'); ?> MT por faixa
                directamente no formulário de envio de música.
            </p>
        </div>
        <?php
        return;
    }

    // Estado: PENDING — aguarda processamento
    if ( $reg && $reg->status === 'pending' ) {
        ?>
        <div class="rmbz-licensing-status rmbz-licensing-status--pending">
            <div class="rmbz-licensing-status__icon"><span class="ms" aria-hidden="true">hourglass_top</span></div>
            <h3>Pedido em análise</h3>
            <p>Estamos a processar o teu pedido. Vais receber um email quando estiver aprovado.</p>
            <p class="rmbz-licensing-status__note">
                Submetido em <?php echo esc_html( date_i18n('d/m/Y', strtotime($reg->created_at)) ); ?>.
                <?php if ( (float)$reg->amount_charged > 0 ): ?>
                    Cobrámos <?php echo number_format((float)$reg->amount_charged, 2, ',', '.'); ?> MT da tua carteira.
                <?php endif; ?>
            </p>
        </div>
        <?php
        return;
    }

    /* ----------------------------------------------------------------------
     * BIFURCAÇÃO: caminho "novo registo" vs "membro existente"
     *
     * - Se for re-submissão (status='returned'), usa o tipo do pedido original
     * - Senão, lê query string ?somas_path=new|existing
     * - Se não há nada definido, mostra a pergunta inicial
     * ---------------------------------------------------------------------- */
    $is_resubmit = ( $reg && $reg->status === 'returned' );

    if ( $is_resubmit ) {
        // Re-submissão herda o tipo do registo original
        $somas_path = ( $reg->submission_type === 'existing_member' ) ? 'existing' : 'new';
    } else {
        $somas_path = isset($_GET['somas_path']) ? sanitize_key($_GET['somas_path']) : '';
        if ( ! in_array($somas_path, ['new', 'existing'], true) ) {
            // Mostra a pergunta inicial e termina aqui
            rmbz_licensing_render_somas_chooser( $telemovel, $reg, $price, $existing_member_price, $per_track );
            return;
        }
    }

    // Routing para o formulário certo
    if ( $somas_path === 'existing' ) {
        rmbz_licensing_render_existing_member_form( $telemovel, $reg, $existing_member_price, $balance );
        return;
    }

    // Caminho "new" — formulário completo de registo (continuação abaixo)
    rmbz_licensing_render_new_registration_form( $telemovel, $reg, $price, $balance );
}

/**
 * Pergunta inicial: artista escolhe se vai registar pela primeira vez
 * ou se já é membro SOMAS.
 */
function rmbz_licensing_render_somas_chooser( $telemovel, $reg, $price_new, $price_existing, $per_track ) {
    // Estado: REJECTED — informa antes de mostrar opções de novo pedido
    if ( $reg && $reg->status === 'rejected' ) {
        ?>
        <div class="rmbz-licensing-status rmbz-licensing-status--danger">
            <div class="rmbz-licensing-status__icon"><span class="ms" aria-hidden="true">cancel</span></div>
            <h3>Pedido anterior rejeitado</h3>
            <p><strong>Motivo:</strong> <?php echo esc_html( $reg->admin_note ?: '(sem detalhes)' ); ?></p>
            <p class="rmbz-licensing-status__note">A quantia foi devolvida à tua carteira. Podes fazer um novo pedido abaixo.</p>
        </div>
        <?php
    }
    ?>
    <div class="rmbz-somas-chooser">
        <h3 class="rmbz-somas-chooser__title">Antes de avançar — uma pergunta</h3>
        <p class="rmbz-somas-chooser__intro">
            Para licenciar as tuas músicas, precisas de um registo na SOMAS.
            Diz-nos a tua situação:
        </p>

        <div class="rmbz-somas-chooser__options">

            <a href="?distro_action=licensing-somas&amp;somas_path=new" class="rmbz-somas-chooser__option">
                <div class="rmbz-somas-chooser__option-icon"><span class="ms" aria-hidden="true">assignment</span></div>
                <h4>Ainda NÃO sou membro da SOMAS</h4>
                <p>Quero registar-me agora. Preencho o formulário oficial e vocês tratam do envio à SOMAS.</p>
                <div class="rmbz-somas-chooser__option-price">
                    Custo: <strong><?php echo number_format($price_new, 2, ',', '.'); ?> MT</strong>
                </div>
                <span class="rmbz-somas-chooser__option-cta">Começar registo &rarr;</span>
            </a>

            <a href="?distro_action=licensing-somas&amp;somas_path=existing" class="rmbz-somas-chooser__option">
                <div class="rmbz-somas-chooser__option-icon"><span class="ms" aria-hidden="true">verified_user</span></div>
                <h4>JÁ sou membro da SOMAS</h4>
                <p>Tenho o meu nº de registo SOMAS e o documento de inscrição que me foi enviado. Só preciso validar.</p>
                <div class="rmbz-somas-chooser__option-price">
                    Custo:
                    <?php if ( $price_existing > 0 ): ?>
                        <strong><?php echo number_format($price_existing, 2, ',', '.'); ?> MT</strong>
                        <small>(taxa de validação)</small>
                    <?php else: ?>
                        <strong style="color:var(--rmbz-success, #10b981);">GRÁTIS</strong>
                    <?php endif; ?>
                </div>
                <span class="rmbz-somas-chooser__option-cta">Validar registo &rarr;</span>
            </a>

        </div>

        <p class="rmbz-somas-chooser__footnote">
            Após aprovação, podes licenciar lançamentos por <?php echo number_format($per_track, 2, ',', '.'); ?> MT por faixa.
        </p>
    </div>

    <style>
    .rmbz-somas-chooser { color:var(--rmbz-text-primary, #fff); }
    .rmbz-somas-chooser__title { color:var(--rmbz-brand, #f0b90b); margin:0 0 10px; font-size:22px; }
    .rmbz-somas-chooser__intro { color:var(--rmbz-text-secondary, #ccc); margin:0 0 30px; font-size:15px; line-height:1.6; }
    .rmbz-somas-chooser__options { display:grid; grid-template-columns:repeat(auto-fit, minmax(320px, 1fr)); gap:20px; }
    .rmbz-somas-chooser__option {
        display:block; background:var(--rmbz-bg-surface, #1a1a1a); border:2px solid #2a2a2a;
        border-radius:12px; padding:24px; text-decoration:none; color:var(--rmbz-text-primary, #fff);
        transition: border-color .15s ease, transform .15s ease, background .15s ease;
    }
    .rmbz-somas-chooser__option:hover { border-color:var(--rmbz-brand, #f0b90b); transform:translateY(-3px); background:var(--rmbz-bg-elevated, #1f1f1f); }
    .rmbz-somas-chooser__option-icon { font-size:36px; margin-bottom:12px; }
    .rmbz-somas-chooser__option h4 { margin:0 0 10px; color:var(--rmbz-text-primary, #fff); font-size:17px; }
    .rmbz-somas-chooser__option p { margin:0 0 16px; color:var(--rmbz-text-secondary, #ccc); font-size:14px; line-height:1.5; }
    .rmbz-somas-chooser__option-price { padding:10px 14px; background:var(--rmbz-bg-elevated, #0e0e0e); border-radius:6px; font-size:13px; color:var(--rmbz-text-muted, #aaa); margin-bottom:14px; }
    .rmbz-somas-chooser__option-price strong { color:var(--rmbz-text-primary, #fff); font-size:15px; }
    .rmbz-somas-chooser__option-price small { color:var(--rmbz-text-faint, #888); }
    .rmbz-somas-chooser__option-cta { color:var(--rmbz-brand, #f0b90b); font-weight:700; font-size:14px; }
    .rmbz-somas-chooser__footnote { margin-top:30px; color:var(--rmbz-text-faint, #888); font-size:13px; text-align:center; }
    </style>
    <?php
}

/**
 * Formulário curto para artistas que JÁ são membros SOMAS.
 * Pede: nº SOMAS + dados básicos + comprovante SOMAS + BI.
 */
function rmbz_licensing_render_existing_member_form( $telemovel, $reg, $price, $balance ) {
    global $wpdb;

    // Pré-preencher com dados da carteira
    $wallet_data = $wpdb->get_row( $wpdb->prepare(
        "SELECT user_nome, user_email FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel = %s",
        $telemovel
    ) );
    $is_resubmit = ( $reg && $reg->status === 'returned' );
    $previous_data = $is_resubmit ? ( json_decode( $reg->form_data, true ) ?: [] ) : [];

    $get = function( $key, $default = '' ) use ( $previous_data, $wallet_data ) {
        if ( isset($previous_data[$key]) && $previous_data[$key] !== '' ) return $previous_data[$key];
        if ( $key === 'email' && $wallet_data ) return $wallet_data->user_email;
        if ( $key === 'nome' && $wallet_data ) return explode(' ', $wallet_data->user_nome ?? '')[0] ?? '';
        if ( $key === 'apelido' && $wallet_data ) {
            $parts = explode(' ', trim($wallet_data->user_nome ?? ''));
            return count($parts) > 1 ? end($parts) : '';
        }
        return $default;
    };

    $reg_id = $reg ? $reg->id : 0;
    $previous_bi_url = ( $reg && ! empty($reg->bi_file_url) ) ? $reg->bi_file_url : '';
    $previous_card_url = ( $reg && ! empty($reg->somas_card_file_url) ) ? $reg->somas_card_file_url : '';

    if ( $is_resubmit ) {
        ?>
        <div class="rmbz-licensing-status rmbz-licensing-status--warning">
            <div class="rmbz-licensing-status__icon"><span class="ms" aria-hidden="true">warning</span></div>
            <h3>Correções necessárias</h3>
            <p><strong>Nota do admin:</strong> <?php echo esc_html( $reg->admin_note ?: '(sem detalhes)' ); ?></p>
        </div>
        <?php
    }
    ?>

    <a href="?distro_action=licensing-somas" class="rmbz-somas-back"><span class="ms" aria-hidden="true">arrow_back</span>Escolher outra opção</a>

    <div class="rmbz-licensing-form-intro">
        <div class="rmbz-somas-intro-heading">
            <span class="rmbz-somas-intro-icon" aria-hidden="true"><span class="ms">verified</span></span>
            <h3>Validar registo SOMAS existente</h3>
        </div>
        <p>
            Vamos verificar o teu nº de registo na SOMAS e marcar a tua conta como "Membro SOMAS"
            para que possas licenciar lançamentos directamente.
        </p>
        <?php if ( ! $is_resubmit && $price > 0 ): ?>
        <div class="rmbz-licensing-balance-row">
            <span>Saldo na carteira:</span>
            <strong><?php echo number_format($balance, 2, ',', '.'); ?> MT</strong>
            <?php if ( $balance < $price ): ?>
                <span class="rmbz-licensing-balance-warn"><span class="ms" aria-hidden="true">error</span>Saldo insuficiente</span>
            <?php endif; ?>
        </div>
        <?php elseif ( ! $is_resubmit ): ?>
        <div class="rmbz-somas-free"><span class="ms" aria-hidden="true">check_circle</span><span>Validação <strong>grátis</strong> — não há custo para esta opção.</span></div>
        <?php endif; ?>
    </div>

    <form method="post" class="rmbz-somas-form" id="rmbz-somas-form-existing"
          enctype="multipart/form-data" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>">
        <?php wp_nonce_field( 'rmbz_submit_somas_' . $telemovel, '_rmbz_somas_nonce' ); ?>
        <input type="hidden" name="action" value="rmbz_submit_somas_registration">
        <input type="hidden" name="submission_type" value="existing_member">
        <input type="hidden" name="registration_id" value="<?php echo (int) $reg_id; ?>">

        <fieldset class="rmbz-somas-fieldset">
            <legend><span class="ms" aria-hidden="true">person</span>Os teus dados</legend>
            <div class="rmbz-somas-grid">
                <label>
                    <span>Nome *</span>
                    <input type="text" name="nome" required maxlength="120" data-validate="nome"
                           value="<?php echo esc_attr($get('nome')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="nome"></small>
                </label>
                <label>
                    <span>Apelido *</span>
                    <input type="text" name="apelido" required maxlength="80" data-validate="apelido"
                           value="<?php echo esc_attr($get('apelido')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="apelido"></small>
                </label>
                <label class="rmbz-somas-grid__full">
                    <span>Email *</span>
                    <input type="email" name="email" required data-validate="email"
                           value="<?php echo esc_attr($get('email')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="email"></small>
                </label>
            </div>
        </fieldset>

        <fieldset class="rmbz-somas-fieldset">
            <legend><span class="ms" aria-hidden="true">verified_user</span>Registo SOMAS</legend>
            <div class="rmbz-somas-grid">
                <label class="rmbz-somas-grid__full">
                    <span>Nº de registo SOMAS *</span>
                    <input type="text" name="somas_number" required maxlength="50" data-validate="somas_number"
                           value="<?php echo esc_attr($get('somas_number', $reg ? $reg->somas_number : '')); ?>"
                           placeholder="Ex: o número que a SOMAS te atribuiu">
                    <small class="rmbz-field-warn" data-warn-for="somas_number"></small>
                </label>
            </div>
        </fieldset>

        <fieldset class="rmbz-somas-fieldset rmbz-somas-fieldset--half">
            <legend><span class="ms" aria-hidden="true">description</span>Documento de inscrição *</legend>
            <p class="rmbz-somas-bi-help">
                Anexa o documento que a SOMAS te enviou a confirmar o teu registo
                (carta, cartão de membro, ou qualquer comprovante oficial).
                <strong>Aceites:</strong> JPG, PNG ou PDF · <strong>Máximo:</strong> 10 MB.
            </p>
            <?php if ( $previous_card_url ): ?>
                <div class="rmbz-somas-bi-current">
                    <span class="rmbz-somas-bi-current__label">Documento submetido anteriormente:</span>
                    <a href="<?php echo esc_url($previous_card_url); ?>" target="_blank" rel="noopener" class="rmbz-somas-bi-current__link">
                        Ver ficheiro actual ↗
                    </a>
                    <p class="rmbz-somas-bi-current__hint">Para manter o ficheiro actual, deixa o campo vazio.</p>
                </div>
            <?php endif; ?>
            <input type="file" name="somas_card_file" accept="image/jpeg,image/png,application/pdf"
                   class="rmbz-somas-bi-input" <?php if ( ! $previous_card_url ): ?>required<?php endif; ?>>
        </fieldset>

        <fieldset class="rmbz-somas-fieldset rmbz-somas-fieldset--half">
            <legend><span class="ms" aria-hidden="true">id_card</span>BI ou Passaporte *</legend>
            <p class="rmbz-somas-bi-help">
                Anexa uma foto/scan do teu BI ou Passaporte para confirmar a identidade.
                <strong>Aceites:</strong> JPG, PNG ou PDF · <strong>Máximo:</strong> 10 MB.
            </p>
            <?php if ( $previous_bi_url ): ?>
                <div class="rmbz-somas-bi-current">
                    <span class="rmbz-somas-bi-current__label">BI submetido anteriormente:</span>
                    <a href="<?php echo esc_url($previous_bi_url); ?>" target="_blank" rel="noopener" class="rmbz-somas-bi-current__link">
                        Ver ficheiro actual ↗
                    </a>
                    <p class="rmbz-somas-bi-current__hint">Para manter o ficheiro actual, deixa o campo vazio.</p>
                </div>
            <?php endif; ?>
            <input type="file" name="bi_file" accept="image/jpeg,image/png,application/pdf"
                   class="rmbz-somas-bi-input" <?php if ( ! $previous_bi_url ): ?>required<?php endif; ?>>
        </fieldset>

        <div class="rmbz-somas-actions">
            <button type="submit" class="rmbz-btn rmbz-btn--primary rmbz-btn--lg"
                <?php if ( ! $is_resubmit && $price > 0 && $balance < $price ): ?>disabled<?php endif; ?>>
                <span class="ms" aria-hidden="true">send</span>
                <?php if ( $is_resubmit ): ?>
                    Re-submeter validação
                <?php elseif ( $price > 0 ): ?>
                    Submeter e pagar <?php echo number_format($price, 2, ',', '.'); ?> MT
                <?php else: ?>
                    Submeter para validação
                <?php endif; ?>
            </button>
            <p class="rmbz-somas-disclaimer"><span class="ms" aria-hidden="true">info</span><span>A nossa equipa vai verificar o teu nº de registo, documento e BI. Quando aprovado, podes começar a licenciar imediatamente.</span></p>
        </div>
    </form>

    <?php rmbz_licensing_render_validation_js( $telemovel ); ?>
    <?php
}

/**
 * Renderiza o formulário longo de NOVO REGISTO SOMAS (caminho A).
 * Era o que estava antes, agora extraído para função separada.
 */
function rmbz_licensing_render_new_registration_form( $telemovel, $reg, $price, $balance ) {
    global $wpdb;

    // Pré-preencher com dados da carteira
    $wallet_data = $wpdb->get_row( $wpdb->prepare(
        "SELECT user_nome, user_email FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel = %s",
        $telemovel
    ) );
    $default_email = $wallet_data ? $wallet_data->user_email : '';
    $default_nome = $wallet_data ? $wallet_data->user_nome : '';

    $is_resubmit = ( $reg && $reg->status === 'returned' );
    $previous_data = $is_resubmit ? ( json_decode( $reg->form_data, true ) ?: [] ) : [];

    $get = function( $key, $default = '' ) use ( $previous_data, $default_email, $default_nome ) {
        if ( isset($previous_data[$key]) && $previous_data[$key] !== '' ) return $previous_data[$key];
        if ( $key === 'email' ) return $default_email;
        if ( $key === 'nome' ) return $default_nome;
        return $default;
    };

    if ( $is_resubmit ) {
        ?>
        <div class="rmbz-licensing-status rmbz-licensing-status--warning">
            <div class="rmbz-licensing-status__icon"><span class="ms" aria-hidden="true">warning</span></div>
            <h3>Correções necessárias</h3>
            <p><strong>Nota do admin:</strong> <?php echo esc_html( $reg->admin_note ?: '(sem detalhes)' ); ?></p>
            <p class="rmbz-licensing-status__note">Corrige os campos abaixo e re-submete (sem custos adicionais).</p>
        </div>
        <?php
    }

    $reg_id = $reg ? $reg->id : 0;
    ?>
    <a href="?distro_action=licensing-somas" class="rmbz-somas-back"><span class="ms" aria-hidden="true">arrow_back</span>Escolher outra opção</a>

    <div class="rmbz-licensing-form-intro">
        <div class="rmbz-somas-intro-heading">
            <span class="rmbz-somas-intro-icon" aria-hidden="true"><span class="ms">assignment</span></span>
            <h3>Registo na SOMAS</h3>
        </div>
        <p>
            Preenche o formulário oficial da Sociedade Moçambicana de Autores.
            Cobra-se uma taxa única de <strong><?php echo number_format($price, 2, ',', '.'); ?> MT</strong>
            (processamento + entrega à SOMAS).
        </p>
        <?php if ( ! $is_resubmit ): ?>
        <div class="rmbz-licensing-balance-row">
            <span>Saldo na carteira:</span>
            <strong><?php echo number_format($balance, 2, ',', '.'); ?> MT</strong>
            <?php if ( $balance < $price ): ?>
                <span class="rmbz-licensing-balance-warn"><span class="ms" aria-hidden="true">error</span>Saldo insuficiente</span>
            <?php endif; ?>
        </div>
        <?php endif; ?>
    </div>

    <form method="post" class="rmbz-somas-form" id="rmbz-somas-form" enctype="multipart/form-data" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>">
        <?php wp_nonce_field( 'rmbz_submit_somas_' . $telemovel, '_rmbz_somas_nonce' ); ?>
        <input type="hidden" name="action" value="rmbz_submit_somas_registration">
        <input type="hidden" name="submission_type" value="new_registration">
        <input type="hidden" name="registration_id" value="<?php echo (int) $reg_id; ?>">

        <fieldset class="rmbz-somas-fieldset">
            <legend><span class="ms" aria-hidden="true">person</span>Dados pessoais</legend>
            <div class="rmbz-somas-grid">
                <label>
                    <span>Apelido *</span>
                    <input type="text" name="apelido" required maxlength="80" data-validate="apelido" value="<?php echo esc_attr($get('apelido')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="apelido"></small>
                </label>
                <label>
                    <span>Nome *</span>
                    <input type="text" name="nome" required maxlength="120" data-validate="nome" value="<?php echo esc_attr($get('nome')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="nome"></small>
                </label>
                <label class="rmbz-somas-grid__full">
                    <span>Morada *</span>
                    <input type="text" name="morada" required maxlength="200" data-validate="morada" value="<?php echo esc_attr($get('morada')); ?>" placeholder="Ex: Av. Eduardo Mondlane, Bairro Polana, n° 123">
                    <small class="rmbz-field-warn" data-warn-for="morada"></small>
                </label>
                <label>
                    <span>Localidade *</span>
                    <input type="text" name="localidade" required maxlength="80" data-validate="localidade" value="<?php echo esc_attr($get('localidade')); ?>" placeholder="Ex: Maputo">
                    <small class="rmbz-field-warn" data-warn-for="localidade"></small>
                </label>
                <label>
                    <span>Nacionalidade *</span>
                    <input type="text" name="nacionalidade" required maxlength="50" value="<?php echo esc_attr($get('nacionalidade', 'Moçambicana')); ?>">
                </label>
                <label>
                    <span>Telefone</span>
                    <input type="text" name="telefone" maxlength="30" data-validate="telefone" value="<?php echo esc_attr($get('telefone')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="telefone"></small>
                </label>
                <label>
                    <span>Telemóvel *</span>
                    <input type="text" name="telemovel_contacto" required maxlength="30" data-validate="telemovel_contacto" value="<?php echo esc_attr($get('telemovel_contacto', $telemovel)); ?>">
                    <small class="rmbz-field-warn" data-warn-for="telemovel_contacto"></small>
                </label>
                <label>
                    <span>Caixa Postal</span>
                    <input type="text" name="caixa_postal" maxlength="30" value="<?php echo esc_attr($get('caixa_postal')); ?>">
                </label>
                <label>
                    <span>Email *</span>
                    <input type="email" name="email" required data-validate="email" value="<?php echo esc_attr($get('email')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="email"></small>
                </label>
                <label>
                    <span>Data de nascimento *</span>
                    <input type="date" name="data_nascimento" required data-validate="data_nascimento" value="<?php echo esc_attr($get('data_nascimento')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="data_nascimento"></small>
                </label>
            </div>
        </fieldset>

        <fieldset class="rmbz-somas-fieldset">
            <legend><span class="ms" aria-hidden="true">fingerprint</span>Identificação</legend>
            <div class="rmbz-somas-grid">
                <label>
                    <span>Nº BI / Passaporte *</span>
                    <input type="text" name="bi_passaporte" required maxlength="30" data-validate="bi_passaporte" value="<?php echo esc_attr($get('bi_passaporte')); ?>" placeholder="Ex: 110100123456A">
                    <small class="rmbz-field-warn" data-warn-for="bi_passaporte"></small>
                </label>
                <label>
                    <span>Local de emissão *</span>
                    <input type="text" name="local_emissao" required maxlength="80" value="<?php echo esc_attr($get('local_emissao')); ?>">
                </label>
                <label>
                    <span>Data de emissão *</span>
                    <input type="date" name="data_emissao" required data-validate="data_emissao" value="<?php echo esc_attr($get('data_emissao')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="data_emissao"></small>
                </label>
            </div>
        </fieldset>

        <fieldset class="rmbz-somas-fieldset">
            <legend><span class="ms" aria-hidden="true">id_card</span>Cópia do BI ou Passaporte *</legend>
            <p class="rmbz-somas-bi-help">
                Anexa uma foto clara ou scan do teu BI/Passaporte (frente onde aparece o nome).
                Será usado para verificar que os dados acima coincidem com o documento.
                <strong>Aceites:</strong> JPG, PNG ou PDF · <strong>Máximo:</strong> 10 MB.
            </p>
            <?php
            $previous_bi_url = ( $reg && ! empty($reg->bi_file_url) ) ? $reg->bi_file_url : '';
            $is_resubmit_with_bi = ( $is_resubmit && $previous_bi_url );
            ?>
            <?php if ( $is_resubmit_with_bi ): ?>
                <div class="rmbz-somas-bi-current">
                    <span class="rmbz-somas-bi-current__label">BI submetido anteriormente:</span>
                    <a href="<?php echo esc_url($previous_bi_url); ?>" target="_blank" rel="noopener" class="rmbz-somas-bi-current__link">
                        Ver ficheiro actual ↗
                    </a>
                    <p class="rmbz-somas-bi-current__hint">
                        Se o motivo da devolução foi o BI, anexa um novo abaixo.
                        Caso contrário, podes deixar o campo vazio para manter o ficheiro actual.
                    </p>
                </div>
            <?php endif; ?>
            <input type="file" name="bi_file" accept="image/jpeg,image/png,application/pdf"
                   class="rmbz-somas-bi-input"
                   <?php if ( ! $is_resubmit_with_bi ): ?>required<?php endif; ?>>
        </fieldset>

        <fieldset class="rmbz-somas-fieldset">
            <legend><span class="ms" aria-hidden="true">music_note</span>Identidade artística</legend>
            <div class="rmbz-somas-grid">
                <label>
                    <span>Abreviaturas / Pseudónimos</span>
                    <input type="text" name="pseudonimo" maxlength="120" value="<?php echo esc_attr($get('pseudonimo')); ?>">
                </label>
                <label>
                    <span>Nome a incluir no cartão *</span>
                    <input type="text" name="nome_cartao" required maxlength="120" data-validate="nome_cartao" value="<?php echo esc_attr($get('nome_cartao')); ?>">
                    <small class="rmbz-field-warn" data-warn-for="nome_cartao"></small>
                </label>
                <label class="rmbz-somas-grid__full">
                    <span>NIB (banco)</span>
                    <input type="text" name="nib" maxlength="30" value="<?php echo esc_attr($get('nib')); ?>">
                </label>
            </div>
        </fieldset>

        <fieldset class="rmbz-somas-fieldset">
            <legend><span class="ms" aria-hidden="true">groups</span>Outras sociedades de autores</legend>
            <div class="rmbz-somas-grid">
                <label>
                    <span>É membro de outra sociedade?</span>
                    <select name="outra_sociedade">
                        <option value="nao" <?php selected($get('outra_sociedade'), 'nao'); ?>>Não</option>
                        <option value="sim" <?php selected($get('outra_sociedade'), 'sim'); ?>>Sim</option>
                    </select>
                </label>
                <label>
                    <span>Qual? (se sim)</span>
                    <input type="text" name="outra_sociedade_qual" maxlength="100" value="<?php echo esc_attr($get('outra_sociedade_qual')); ?>">
                </label>
            </div>
        </fieldset>

        <fieldset class="rmbz-somas-fieldset">
            <legend><span class="ms" aria-hidden="true">notes</span>Observações</legend>
            <textarea name="observacoes" rows="3" maxlength="500"><?php echo esc_textarea($get('observacoes')); ?></textarea>
        </fieldset>

        <div class="rmbz-somas-actions">
            <button type="submit" class="rmbz-btn rmbz-btn--primary rmbz-btn--lg"
                <?php if ( ! $is_resubmit && $balance < $price ): ?>disabled<?php endif; ?>>
                <span class="ms" aria-hidden="true">send</span>
                <?php if ( $is_resubmit ): ?>
                    Re-submeter pedido
                <?php else: ?>
                    Submeter e pagar <?php echo number_format($price, 2, ',', '.'); ?> MT
                <?php endif; ?>
            </button>
            <p class="rmbz-somas-disclaimer"><span class="ms" aria-hidden="true">info</span><span>Ao submeter, autorizas a SOMAS a representar-te no exercício e defesa dos teus direitos autorais, conforme os estatutos. Cobra-se a quantia da tua carteira após confirmação.</span></p>
        </div>
    </form>

    <?php rmbz_licensing_render_validation_js( $telemovel ); ?>
    <?php
}

/**
 * Renderiza o JS de validação inteligente em tempo real.
 * Cada campo com data-validate dispara AJAX para o servidor onblur,
 * e mostra o aviso amarelo abaixo se houver.
 */
function rmbz_licensing_render_validation_js( $telemovel ) {
    ?>
    <style>
    .rmbz-field-warn {
        display: block;
        color: var(--rmbz-brand, #f1c40f);
        font-size: 12px;
        margin-top: 4px;
        line-height: 1.4;
        min-height: 0;
        opacity: 0;
        max-height: 0;
        overflow: hidden;
        transition: opacity .2s ease, max-height .2s ease;
    }
    .rmbz-field-warn.has-warn {
        opacity: 1;
        max-height: 100px;
        margin-top: 6px;
    }
    .rmbz-somas-grid input.has-warn,
    .rmbz-somas-grid select.has-warn {
        border-color: var(--rmbz-brand, #f1c40f) !important;
    }
    </style>
    <script>
    (function(){
        var ajaxUrl = '<?php echo esc_url( admin_url('admin-ajax.php') ); ?>';
        var inputs = document.querySelectorAll('[data-validate]');
        if (!inputs.length) return;

        function getContext(form) {
            // Recolhe outros campos do form para validação cruzada (data emissão vs nascimento, nome vs cartão)
            var ctx = {};
            form.querySelectorAll('input[name], select[name]').forEach(function(el) {
                if (el.type !== 'file' && el.type !== 'submit' && el.type !== 'hidden') {
                    ctx[el.name] = el.value;
                }
            });
            return ctx;
        }

        function showWarnings(input, warnings) {
            var slot = document.querySelector('[data-warn-for="' + input.dataset.validate + '"]');
            if (!slot) return;
            if (!warnings || !warnings.length) {
                slot.classList.remove('has-warn');
                slot.innerHTML = '';
                input.classList.remove('has-warn');
                return;
            }
            slot.innerHTML = warnings.map(function(w) {
                return w.replace(/</g, '&lt;');
            }).join('<br>');
            slot.classList.add('has-warn');
            input.classList.add('has-warn');
        }

        var debounceTimer = null;
        function validate(input) {
            clearTimeout(debounceTimer);
            debounceTimer = setTimeout(function() {
                var form = input.closest('form');
                var ctx = form ? getContext(form) : {};
                var fd = new FormData();
                fd.append('action', 'rmbz_validate_somas_field');
                fd.append('field', input.dataset.validate);
                fd.append('value', input.value);
                Object.keys(ctx).forEach(function(k) { fd.append('context[' + k + ']', ctx[k]); });

                fetch(ajaxUrl, { method:'POST', body:fd, credentials:'same-origin' })
                    .then(function(r) { return r.json(); })
                    .then(function(res) {
                        if (res.success) showWarnings(input, res.data.warnings || []);
                    })
                    .catch(function() {});
            }, 350);
        }

        inputs.forEach(function(input) {
            input.addEventListener('blur', function() { validate(input); });
            input.addEventListener('input', function() {
                // Clear warning while typing (validate again on blur)
                var slot = document.querySelector('[data-warn-for="' + input.dataset.validate + '"]');
                if (slot && slot.classList.contains('has-warn')) {
                    slot.classList.remove('has-warn');
                    input.classList.remove('has-warn');
                }
            });
        });
    })();
    </script>
    <?php
}


/* ============================================================================
 * 10. HANDLERS — POST do formulário SOMAS
 * ============================================================================ */

/**
 * Processa POST do formulário SOMAS submetido pelo artista (frontend).
 * Hook: admin_post_rmbz_submit_somas_registration + nopriv para utilizadores
 * que estão logged-in via auth próprio (não WP user).
 */
function rmbz_licensing_handle_somas_submission() {
    // Identificar artista (auth próprio do plugin)
    if ( ! function_exists('rmbz_get_current_user_telemovel') ) {
        wp_die('Erro de auth.');
    }
    $telemovel = rmbz_get_current_user_telemovel();
    if ( empty($telemovel) ) {
        wp_die('Sessão expirada — faz login novamente.');
    }
    $access_error = function_exists( 'rmbz_distro_artist_access_error' )
        ? rmbz_distro_artist_access_error( $telemovel, true )
        : '';
    if ( $access_error !== '' ) wp_die( esc_html( $access_error ), 'Distribuição indisponível', [ 'response' => 403 ] );
    $return_url = rmbz_licensing_somas_return_url();

    // Validar nonce
    if ( ! isset($_POST['_rmbz_somas_nonce']) ||
         ! wp_verify_nonce( $_POST['_rmbz_somas_nonce'], 'rmbz_submit_somas_' . $telemovel ) ) {
        wp_die('Nonce inválido.');
    }

    // [DS 1.5.83] Determinar tipo de submissão
    $submission_type = isset($_POST['submission_type']) ? sanitize_key($_POST['submission_type']) : 'new_registration';
    if ( ! in_array( $submission_type, ['new_registration', 'existing_member'], true ) ) {
        $submission_type = 'new_registration';
    }

    // Sanitizar dados (campos comuns + específicos de cada caminho)
    $form_data = [
        'apelido'              => sanitize_text_field( $_POST['apelido'] ?? '' ),
        'nome'                 => sanitize_text_field( $_POST['nome'] ?? '' ),
        'email'                => sanitize_email( $_POST['email'] ?? '' ),
        'submission_type'      => $submission_type,
    ];

    if ( $submission_type === 'new_registration' ) {
        // Caminho A: registo novo — todos os campos do formulário SOMAS oficial
        $form_data = array_merge( $form_data, [
            'morada'               => sanitize_text_field( $_POST['morada'] ?? '' ),
            'localidade'           => sanitize_text_field( $_POST['localidade'] ?? '' ),
            'nacionalidade'        => sanitize_text_field( $_POST['nacionalidade'] ?? '' ),
            'telefone'             => sanitize_text_field( $_POST['telefone'] ?? '' ),
            'telemovel_contacto'   => sanitize_text_field( $_POST['telemovel_contacto'] ?? '' ),
            'caixa_postal'         => sanitize_text_field( $_POST['caixa_postal'] ?? '' ),
            'data_nascimento'      => sanitize_text_field( $_POST['data_nascimento'] ?? '' ),
            'bi_passaporte'        => sanitize_text_field( $_POST['bi_passaporte'] ?? '' ),
            'local_emissao'        => sanitize_text_field( $_POST['local_emissao'] ?? '' ),
            'data_emissao'         => sanitize_text_field( $_POST['data_emissao'] ?? '' ),
            'pseudonimo'           => sanitize_text_field( $_POST['pseudonimo'] ?? '' ),
            'nome_cartao'          => sanitize_text_field( $_POST['nome_cartao'] ?? '' ),
            'nib'                  => sanitize_text_field( $_POST['nib'] ?? '' ),
            'outra_sociedade'      => sanitize_text_field( $_POST['outra_sociedade'] ?? 'nao' ),
            'outra_sociedade_qual' => sanitize_text_field( $_POST['outra_sociedade_qual'] ?? '' ),
            'observacoes'          => sanitize_textarea_field( $_POST['observacoes'] ?? '' ),
        ]);
    } else {
        // Caminho B: membro existente — só nº SOMAS + dados básicos
        $form_data['somas_number'] = sanitize_text_field( $_POST['somas_number'] ?? '' );
    }

    // Caso de re-submissão de pedido devolvido — actualiza em vez de criar novo
    $registration_id = isset($_POST['registration_id']) ? (int) $_POST['registration_id'] : 0;
    if ( $registration_id > 0 ) {
        global $wpdb;
        $table = $wpdb->prefix . 'rmbz_somas_registrations';
        $existing = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$table} WHERE id = %d AND artist_telemovel = %s",
            $registration_id, $telemovel
        ) );

        if ( $existing && $existing->status === 'returned' ) {
            // Re-submissão — opcionalmente troca BI/comprovante (artista pode manter os anteriores).
            $update_data = [
                'form_data'  => wp_json_encode( $form_data ),
                'status'     => 'pending',
                'admin_note' => null,
                'updated_at' => current_time('mysql'),
            ];
            $update_format = [ '%s','%s','%s','%s' ];

            // Se for membro existente, actualizar tb o nº SOMAS na coluna dedicada
            if ( $existing->submission_type === 'existing_member' && ! empty($form_data['somas_number']) ) {
                $update_data['somas_number'] = $form_data['somas_number'];
                $update_format[] = '%s';
            }

            // Se artista anexou novo BI, validar e substituir
            if ( ! empty($_FILES['bi_file']['tmp_name']) ) {
                $bi_validation = rmbz_licensing_validate_bi_upload( $_FILES['bi_file'] );
                if ( ! $bi_validation['valid'] ) {
                    wp_safe_redirect( add_query_arg( [ 'somas_status' => 'error', 'msg' => 'BI: ' . $bi_validation['error'] ], $return_url ) );
                    exit;
                }
                $bi_upload = rmbz_licensing_handle_bi_upload( $_FILES['bi_file'], $telemovel );
                if ( $bi_upload['success'] ) {
                    if ( ! empty($existing->bi_file_path) && file_exists($existing->bi_file_path) ) {
                        @unlink($existing->bi_file_path);
                    }
                    $update_data['bi_file_url']  = $bi_upload['url'];
                    $update_data['bi_file_path'] = $bi_upload['path'];
                    $update_format[] = '%s';
                    $update_format[] = '%s';
                }
            }

            // [DS 1.5.83] Se for re-submissão de membro existente, pode também
            // anexar um novo comprovante SOMAS
            if ( $existing->submission_type === 'existing_member' && ! empty($_FILES['somas_card_file']['tmp_name']) ) {
                $card_validation = rmbz_licensing_validate_bi_upload( $_FILES['somas_card_file'] );
                if ( ! $card_validation['valid'] ) {
                    wp_safe_redirect( add_query_arg( [ 'somas_status' => 'error', 'msg' => 'Comprovante: ' . $card_validation['error'] ], $return_url ) );
                    exit;
                }
                $card_upload = rmbz_licensing_handle_bi_upload( $_FILES['somas_card_file'], $telemovel . '_card' );
                if ( $card_upload['success'] ) {
                    if ( ! empty($existing->somas_card_file_path) && file_exists($existing->somas_card_file_path) ) {
                        @unlink($existing->somas_card_file_path);
                    }
                    $update_data['somas_card_file_url']  = $card_upload['url'];
                    $update_data['somas_card_file_path'] = $card_upload['path'];
                    $update_format[] = '%s';
                    $update_format[] = '%s';
                }
            }

            $wpdb->update( $table, $update_data, [ 'id' => $registration_id ], $update_format, [ '%d' ] );
            wp_safe_redirect( add_query_arg( 'somas_status', 'resubmitted', $return_url ) );
            exit;
        }
    }

    // Submissão nova — bifurcação para a função certa
    $bi_file = isset($_FILES['bi_file']) ? $_FILES['bi_file'] : null;

    if ( $submission_type === 'existing_member' ) {
        $somas_card_file = isset($_FILES['somas_card_file']) ? $_FILES['somas_card_file'] : null;
        $result = rmbz_licensing_submit_existing_member( $telemovel, $form_data, $bi_file, $somas_card_file );
    } else {
        $result = rmbz_licensing_submit_somas_registration( $telemovel, $form_data, $bi_file );
    }

    if ( $result['success'] ) {
        wp_safe_redirect( add_query_arg( [ 'somas_status' => 'submitted', 'id' => $result['registration_id'] ], $return_url ) );
    } else {
        wp_safe_redirect( add_query_arg( [ 'somas_status' => 'error', 'msg' => $result['error'] ], $return_url ) );
    }
    exit;
}
add_action( 'admin_post_rmbz_submit_somas_registration', 'rmbz_licensing_handle_somas_submission' );
add_action( 'admin_post_nopriv_rmbz_submit_somas_registration', 'rmbz_licensing_handle_somas_submission' );


/**
 * AJAX: artista submete pedido de licenciamento durante o wizard de envio.
 */
function rmbz_licensing_ajax_submit_license() {
    if ( ! function_exists('rmbz_get_current_user_telemovel') ) {
        wp_send_json_error( ['msg' => 'Erro de auth.'], 401 );
    }
    $telemovel = rmbz_get_current_user_telemovel();
    if ( empty($telemovel) ) {
        wp_send_json_error( ['msg' => 'Sessão expirada.'], 401 );
    }

    if ( ! isset($_POST['_nonce']) || ! wp_verify_nonce( $_POST['_nonce'], 'rmbz_license_' . $telemovel ) ) {
        wp_send_json_error( ['msg' => 'Nonce inválido.'], 403 );
    }

    $release_id = isset($_POST['release_id']) ? (int) $_POST['release_id'] : 0;
    $coupon_code = isset($_POST['coupon_code']) ? sanitize_text_field( $_POST['coupon_code'] ) : '';
    global $wpdb;
    $owns_release = $wpdb->get_var( $wpdb->prepare(
        "SELECT id FROM {$wpdb->prefix}rmbz_distro_releases WHERE id = %d AND artist_telemovel = %s",
        $release_id,
        $telemovel
    ) );
    if ( ! $owns_release ) wp_send_json_error( [ 'msg' => 'Lançamento não encontrado.' ], 404 );

    $result = rmbz_licensing_submit_release_license( $telemovel, $release_id, $coupon_code );

    if ( $result['success'] ) {
        wp_send_json_success( [
            'license_id' => $result['license_id'],
            'amount_charged' => $result['amount_charged'],
            'discount' => $result['discount'],
        ] );
    } else {
        wp_send_json_error( [ 'msg' => $result['error'] ], 400 );
    }
}
add_action( 'wp_ajax_rmbz_submit_license', 'rmbz_licensing_ajax_submit_license' );
add_action( 'wp_ajax_nopriv_rmbz_submit_license', 'rmbz_licensing_ajax_submit_license' );

/**
 * AJAX: validar cupão em tempo real (preview do desconto antes de submeter).
 */
function rmbz_licensing_ajax_validate_coupon() {
    if ( ! function_exists('rmbz_get_current_user_telemovel') ) {
        wp_send_json_error( ['msg' => 'Erro de auth.'], 401 );
    }
    $telemovel = rmbz_get_current_user_telemovel();
    if ( empty($telemovel) ) {
        wp_send_json_error( ['msg' => 'Sessão expirada.'], 401 );
    }

    if ( ! isset($_POST['_nonce']) || ! wp_verify_nonce( $_POST['_nonce'], 'rmbz_license_' . $telemovel ) ) {
        wp_send_json_error( [ 'msg' => 'Nonce inválido.' ], 403 );
    }

    $code = sanitize_text_field( $_POST['code'] ?? '' );
    $release_id = isset($_POST['release_id']) ? (int) $_POST['release_id'] : 0;
    global $wpdb;
    $owns_release = $wpdb->get_var( $wpdb->prepare(
        "SELECT id FROM {$wpdb->prefix}rmbz_distro_releases WHERE id = %d AND artist_telemovel = %s",
        $release_id,
        $telemovel
    ) );
    if ( ! $owns_release ) wp_send_json_error( [ 'msg' => 'Lançamento não encontrado.' ], 404 );

    $track_count = rmbz_licensing_count_release_tracks( $release_id );
    $unit_price = rmbz_licensing_get_per_track_price();

    $check = rmbz_licensing_validate_coupon( $code, $telemovel, $track_count, $unit_price );
    wp_send_json_success( $check );
}
add_action( 'wp_ajax_rmbz_validate_licensing_coupon', 'rmbz_licensing_ajax_validate_coupon' );
add_action( 'wp_ajax_nopriv_rmbz_validate_licensing_coupon', 'rmbz_licensing_ajax_validate_coupon' );


/* ============================================================================
 * 11. INTEGRAÇÃO NO WIZARD — passo de licenciamento (após capa)
 * ============================================================================
 *
 * Renderizado pelo wizard via filter hook. Aparece só se:
 *   - Feature está activada
 *   - Release tem capa (passo 4 done)
 *   - Release tem pelo menos 1 faixa
 *
 * UI varia consoante o estado SOMAS do artista:
 *   - sem registo / rejeitado → mostra link para criar registo
 *   - pending → mostra mensagem "aguarda aprovação"
 *   - approved → mostra preço + cupão + botão de licenciar
 *   - já tem licença para este release → mostra estado da licença
 */
function rmbz_licensing_render_wizard_step( $release_id, $telemovel ) {
    if ( ! rmbz_licensing_is_enabled() ) return;

    $release_id = (int) $release_id;
    if ( $release_id <= 0 ) return;

    $somas_reg = rmbz_licensing_get_artist_somas_registration( $telemovel );
    $existing_license = rmbz_licensing_get_release_license( $release_id );
    $track_count = rmbz_licensing_count_release_tracks( $release_id );
    $unit_price = rmbz_licensing_get_per_track_price();
    $reg_price = rmbz_licensing_get_registration_price();
    $base_total = $unit_price * $track_count;
    $balance = rmbz_get_wallet_balance_by_phone( $telemovel );

    ?>
    <div class="rmbz-license-step">
        <h3 class="rmbz-license-step__title">🎼 Licenciamento musical (opcional)</h3>
        <p class="rmbz-license-step__intro">
            Se quiseres registar este lançamento na SOMAS para começar a receber direitos autorais
            por cada utilização pública das tuas músicas (rádio, TV, eventos), podes pedir o
            licenciamento agora.
        </p>

        <?php if ( $existing_license ): ?>
            <?php
            $status_label = [
                'pending'    => 'Pedido enviado, em análise',
                'processing' => 'Em processamento na SOMAS',
                'approved'   => 'Licenciado com sucesso',
            ];
            $label = $status_label[ $existing_license->status ] ?? $existing_license->status;
            ?>
            <div class="rmbz-license-existing">
                <span class="rmbz-license-existing__icon">✓</span>
                <div>
                    <strong><?php echo esc_html($label); ?></strong>
                    <p class="rmbz-license-existing__detail">
                        <?php echo $existing_license->track_count; ?> faixas •
                        <?php echo number_format((float)$existing_license->amount_charged, 2, ',', '.'); ?> MT
                        <?php if ( $existing_license->coupon_id ): ?>
                            • cupão aplicado (-<?php echo number_format((float)$existing_license->coupon_discount, 2, ',', '.'); ?> MT)
                        <?php endif; ?>
                    </p>
                </div>
            </div>
            <?php return; ?>
        <?php endif; ?>

        <?php if ( ! $somas_reg || in_array($somas_reg->status, ['rejected'], true) ): ?>
            <!-- Sem registo SOMAS — explicar que precisa de se registar primeiro -->
            <div class="rmbz-license-need-somas">
                <p>
                    Para licenciar precisas primeiro de ter um registo aprovado na SOMAS.
                    Custa <strong><?php echo number_format($reg_price, 2, ',', '.'); ?> MT</strong>
                    (taxa única, processamos por ti).
                </p>
                <a href="?distro_action=licensing-somas" class="rmbz-btn rmbz-btn--primary">
                    Criar registo SOMAS
                </a>
                <p class="rmbz-license-need-somas__skip">
                    Podes saltar este passo e licenciar mais tarde quando quiseres.
                </p>
            </div>

        <?php elseif ( $somas_reg->status === 'pending' ): ?>
            <div class="rmbz-license-need-somas rmbz-license-need-somas--pending">
                <p>
                    O teu registo SOMAS está em análise. Quando for aprovado vais conseguir licenciar
                    este lançamento por <?php echo number_format($unit_price, 2, ',', '.'); ?> MT por faixa.
                </p>
                <p class="rmbz-license-need-somas__skip">
                    Continua a publicar este lançamento sem licenciar — podes voltar depois.
                </p>
            </div>

        <?php elseif ( $somas_reg->status === 'returned' ): ?>
            <div class="rmbz-license-need-somas rmbz-license-need-somas--warning">
                <p>O teu pedido SOMAS precisa de correções.</p>
                <a href="?distro_action=licensing-somas" class="rmbz-btn rmbz-btn--secondary">Corrigir pedido</a>
            </div>

        <?php else: /* approved */ ?>
            <!-- Pode licenciar -->
            <div class="rmbz-license-pricing">
                <div class="rmbz-license-pricing__row">
                    <span><?php echo $track_count; ?> faixa<?php echo $track_count !== 1 ? 's' : ''; ?> × <?php echo number_format($unit_price, 2, ',', '.'); ?> MT</span>
                    <strong id="rmbz-lic-base"><?php echo number_format($base_total, 2, ',', '.'); ?> MT</strong>
                </div>
                <div class="rmbz-license-pricing__row" id="rmbz-lic-discount-row" style="display:none;">
                    <span>Desconto cupão</span>
                    <strong id="rmbz-lic-discount" style="color:var(--rmbz-success, #10b981);">−0,00 MT</strong>
                </div>
                <div class="rmbz-license-pricing__row rmbz-license-pricing__total">
                    <span>Total</span>
                    <strong id="rmbz-lic-total"><?php echo number_format($base_total, 2, ',', '.'); ?> MT</strong>
                </div>
                <p class="rmbz-license-pricing__balance">
                    Saldo na carteira: <strong><?php echo number_format($balance, 2, ',', '.'); ?> MT</strong>
                </p>
            </div>

            <div class="rmbz-license-coupon">
                <label for="rmbz-lic-coupon-input">Tens cupão de desconto?</label>
                <div class="rmbz-license-coupon__row">
                    <input type="text" id="rmbz-lic-coupon-input" placeholder="CÓDIGO" maxlength="50" style="text-transform:uppercase;">
                    <button type="button" id="rmbz-lic-coupon-apply" class="rmbz-btn rmbz-btn--secondary">Aplicar</button>
                </div>
                <p class="rmbz-license-coupon__msg" id="rmbz-lic-coupon-msg"></p>
            </div>

            <div class="rmbz-license-actions">
                <button type="button" id="rmbz-lic-submit-btn" class="rmbz-btn rmbz-btn--primary rmbz-btn--lg"
                    data-release-id="<?php echo $release_id; ?>"
                    data-nonce="<?php echo wp_create_nonce('rmbz_license_' . $telemovel); ?>"
                    <?php if ( $balance < $base_total ): ?>disabled<?php endif; ?>>
                    Licenciar este lançamento
                </button>
                <button type="button" class="rmbz-btn rmbz-btn--ghost" id="rmbz-lic-skip-btn">
                    Saltar (não licenciar agora)
                </button>
            </div>
        <?php endif; ?>
    </div>

    <script>
    (function() {
        var applyBtn = document.getElementById('rmbz-lic-coupon-apply');
        var submitBtn = document.getElementById('rmbz-lic-submit-btn');
        var skipBtn = document.getElementById('rmbz-lic-skip-btn');
        if (!submitBtn) return;

        var releaseId = submitBtn.getAttribute('data-release-id');
        var nonce = submitBtn.getAttribute('data-nonce');
        var ajaxUrl = '<?php echo esc_url( admin_url('admin-ajax.php') ); ?>';
        var appliedCouponCode = '';

        function fmtMT(v) { return v.toFixed(2).replace('.',',') + ' MT'; }

        // Validar cupão
        if (applyBtn) {
            applyBtn.addEventListener('click', function() {
                var input = document.getElementById('rmbz-lic-coupon-input');
                var msg = document.getElementById('rmbz-lic-coupon-msg');
                var code = (input.value || '').trim().toUpperCase();
                if (!code) { msg.textContent = 'Insere o código.'; msg.style.color = '#e67e22'; return; }
                msg.textContent = 'A validar...'; msg.style.color = '#aaa';

                var fd = new FormData();
                fd.append('action', 'rmbz_validate_licensing_coupon');
                fd.append('_nonce', nonce);
                fd.append('code', code);
                fd.append('release_id', releaseId);

                fetch(ajaxUrl, { method:'POST', body:fd, credentials:'same-origin' })
                    .then(function(r) { return r.json(); })
                    .then(function(res) {
                        if (res.success && res.data && res.data.valid) {
                            appliedCouponCode = code;
                            msg.textContent = '✓ Cupão aplicado: -' + fmtMT(res.data.discount);
                            msg.style.color = '#2ecc71';
                            document.getElementById('rmbz-lic-discount-row').style.display = '';
                            document.getElementById('rmbz-lic-discount').textContent = '−' + fmtMT(res.data.discount);
                            document.getElementById('rmbz-lic-total').textContent = fmtMT(res.data.final_total);
                        } else {
                            appliedCouponCode = '';
                            msg.textContent = '✕ ' + ((res.data && res.data.error) || 'Cupão inválido');
                            msg.style.color = '#e74c3c';
                        }
                    })
                    .catch(function() { msg.textContent = 'Erro de rede.'; msg.style.color = '#e74c3c'; });
            });
        }

        // Submeter licença
        submitBtn.addEventListener('click', function() {
            if (!confirm('Confirmas o pedido de licenciamento? Vamos cobrar da tua carteira.')) return;
            submitBtn.disabled = true;
            submitBtn.textContent = 'A processar...';

            var fd = new FormData();
            fd.append('action', 'rmbz_submit_license');
            fd.append('_nonce', nonce);
            fd.append('release_id', releaseId);
            fd.append('coupon_code', appliedCouponCode);

            fetch(ajaxUrl, { method:'POST', body:fd, credentials:'same-origin' })
                .then(function(r) { return r.json(); })
                .then(function(res) {
                    if (res.success) {
                        alert('✓ Pedido de licenciamento submetido! Vais ser notificado quando processado.');
                        window.location.reload();
                    } else {
                        alert('Erro: ' + ((res.data && res.data.msg) || 'desconhecido'));
                        submitBtn.disabled = false;
                        submitBtn.textContent = 'Licenciar este lançamento';
                    }
                })
                .catch(function() {
                    alert('Erro de rede.');
                    submitBtn.disabled = false;
                });
        });

        if (skipBtn) {
            skipBtn.addEventListener('click', function() {
                document.querySelector('.rmbz-license-step').style.opacity = '0.5';
                skipBtn.disabled = true;
                skipBtn.textContent = '✓ Saltado';
            });
        }
    })();
    </script>

    <style>
    /* [DS 1.5.81] Estilos do passo de licenciamento dentro do wizard.
     * Inline aqui (em vez de em ficheiro CSS separado) porque este passo
     * é renderizado condicionalmente e precisamos garantir que o CSS
     * sempre acompanha o markup, em qualquer rota onde a função for
     * chamada (wizard, my-account, etc). */
    .rmbz-license-step {
        background: var(--rmbz-bg-surface, #1a1a1a);
        border: 1px solid #2a2a2a;
        border-radius: 12px;
        padding: 28px;
        margin-top: 24px;
        color: var(--rmbz-text-primary, #fff);
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    }
    .rmbz-license-step__title {
        margin: 0 0 12px 0;
        color: var(--rmbz-brand, #f0b90b);
        font-size: 20px;
        font-weight: 700;
        display: flex;
        align-items: center;
        gap: 10px;
    }
    .rmbz-license-step__intro {
        color: var(--rmbz-text-secondary, #ccc);
        margin: 0 0 24px 0;
        font-size: 14px;
        line-height: 1.6;
    }
    .rmbz-license-existing {
        padding: 18px;
        background: rgba(46,204,113,0.08);
        border: 1px solid rgba(46,204,113,0.25);
        border-radius: 8px;
        display: flex;
        gap: 14px;
        align-items: center;
    }
    .rmbz-license-existing__icon {
        font-size: 28px;
        color: var(--rmbz-success, #10b981);
        flex-shrink: 0;
    }
    .rmbz-license-existing strong { color: var(--rmbz-text-primary, #fff); font-size: 15px; display: block; }
    .rmbz-license-existing__detail { color: var(--rmbz-text-muted, #aaa); font-size: 13px; margin: 4px 0 0; }
    .rmbz-license-need-somas {
        padding: 20px;
        background: var(--rmbz-bg-elevated, #0e0e0e);
        border: 1px solid #2a2a2a;
        border-radius: 8px;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 14px;
    }
    .rmbz-license-need-somas p { margin: 0; color: var(--rmbz-text-secondary, #ccc); font-size: 14px; line-height: 1.6; }
    .rmbz-license-need-somas--pending { background: rgba(241,196,15,0.05); border-color: rgba(241,196,15,0.25); }
    .rmbz-license-need-somas--warning { background: rgba(230,126,34,0.05); border-color: rgba(230,126,34,0.25); }
    .rmbz-license-need-somas .rmbz-btn {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        background: var(--rmbz-brand, #f0b90b);
        color: #000;
        text-decoration: none;
        padding: 10px 20px;
        border-radius: 6px;
        font-weight: 600;
        font-size: 14px;
        border: none;
        cursor: pointer;
        transition: background 0.15s ease;
    }
    .rmbz-license-need-somas .rmbz-btn:hover { background: var(--rmbz-brand-strong, #fcc524); }
    .rmbz-license-need-somas .rmbz-btn--secondary { background: var(--rmbz-bg-elevated, #2a2a2a); color: var(--rmbz-text-primary, #fff); }
    .rmbz-license-need-somas .rmbz-btn--secondary:hover { background: var(--rmbz-bg-elevated, #3a3a3a); }
    .rmbz-license-need-somas__skip {
        color: var(--rmbz-text-faint, #777) !important;
        font-size: 12px !important;
        font-style: italic;
    }

    .rmbz-license-pricing {
        background: var(--rmbz-bg-elevated, #0e0e0e);
        border: 1px solid #2a2a2a;
        padding: 18px;
        border-radius: 8px;
        margin-bottom: 18px;
    }
    .rmbz-license-pricing__row {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 8px 0;
        color: var(--rmbz-text-secondary, #ccc);
        font-size: 14px;
    }
    .rmbz-license-pricing__row strong { color: var(--rmbz-text-primary, #fff); }
    .rmbz-license-pricing__total {
        border-top: 1px solid #333;
        padding-top: 12px;
        margin-top: 8px;
        font-size: 17px;
    }
    .rmbz-license-pricing__total strong { color: var(--rmbz-brand, #f0b90b); font-size: 19px; }
    .rmbz-license-pricing__balance {
        color: var(--rmbz-text-muted, #aaa);
        font-size: 12px;
        margin: 12px 0 0;
        padding-top: 12px;
        border-top: 1px dashed #2a2a2a;
        text-align: center;
    }
    .rmbz-license-pricing__balance strong { color: var(--rmbz-brand, #f0b90b); }

    .rmbz-license-coupon { margin-bottom: 22px; }
    .rmbz-license-coupon label {
        display: block;
        color: var(--rmbz-text-secondary, #ccc);
        font-size: 13px;
        margin-bottom: 8px;
    }
    .rmbz-license-coupon__row {
        display: flex;
        gap: 8px;
    }
    .rmbz-license-coupon__row input {
        flex: 1;
        background: var(--rmbz-bg-elevated, #0e0e0e);
        border: 1px solid #333;
        color: var(--rmbz-text-primary, #fff);
        padding: 11px 14px;
        border-radius: 6px;
        font: inherit;
        font-size: 14px;
        text-transform: uppercase;
        box-sizing: border-box;
    }
    .rmbz-license-coupon__row input:focus { outline: none; border-color: var(--rmbz-brand, #f0b90b); }
    .rmbz-license-coupon__row .rmbz-btn {
        background: var(--rmbz-bg-elevated, #2a2a2a);
        color: var(--rmbz-text-primary, #fff);
        border: 1px solid #3a3a3a;
        padding: 11px 18px;
        border-radius: 6px;
        font: inherit;
        font-size: 13px;
        font-weight: 600;
        cursor: pointer;
    }
    .rmbz-license-coupon__row .rmbz-btn:hover { background: var(--rmbz-bg-elevated, #3a3a3a); border-color: var(--rmbz-brand, #f0b90b); }
    .rmbz-license-coupon__msg {
        font-size: 13px;
        margin: 8px 0 0;
        min-height: 18px;
    }

    .rmbz-license-actions {
        display: flex;
        gap: 12px;
        flex-wrap: wrap;
    }
    .rmbz-license-actions .rmbz-btn {
        padding: 13px 24px;
        border-radius: 6px;
        font: inherit;
        font-size: 14px;
        font-weight: 700;
        border: none;
        cursor: pointer;
        transition: background 0.15s ease, opacity 0.15s ease;
    }
    .rmbz-license-actions .rmbz-btn--primary {
        background: var(--rmbz-brand, #f0b90b);
        color: #000;
        flex: 2;
        min-width: 220px;
    }
    .rmbz-license-actions .rmbz-btn--primary:hover:not(:disabled) { background: var(--rmbz-brand-strong, #fcc524); }
    .rmbz-license-actions .rmbz-btn--primary:disabled {
        opacity: 0.5;
        cursor: not-allowed;
    }
    .rmbz-license-actions .rmbz-btn--lg { padding: 15px 28px; font-size: 15px; }
    .rmbz-license-actions .rmbz-btn--ghost {
        background: transparent;
        color: var(--rmbz-text-muted, #aaa);
        border: 1px solid #3a3a3a;
        flex: 1;
        min-width: 140px;
    }
    .rmbz-license-actions .rmbz-btn--ghost:hover { color: var(--rmbz-text-primary, #fff); border-color: var(--rmbz-border-strong, #555); }

    @media (max-width: 600px) {
        .rmbz-license-step { padding: 20px; }
        .rmbz-license-actions .rmbz-btn--primary,
        .rmbz-license-actions .rmbz-btn--ghost {
            flex: 1 1 100%;
            min-width: 0;
        }
    }
    </style>
    <?php
}


/* ============================================================================
 * 12. PAINEL ADMIN — gestão de registos SOMAS e licenças
 * ============================================================================ */

/**
 * Renderiza o painel admin de Licenciamento.
 * 2 tabs: 'somas' (registos pendentes) e 'licenses' (licenças por release).
 */
function rmbz_licensing_admin_page() {
    if ( ! current_user_can('manage_options') ) wp_die('Sem permissão.');

    global $wpdb;
    $tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'somas';
    $detail_id = isset($_GET['id']) ? (int) $_GET['id'] : 0;

    ?>
    <div class="wrap">
        <h1>🎼 Licenciamento Musical</h1>

        <h2 class="nav-tab-wrapper">
            <a href="?page=rmbz-licensing&tab=somas" class="nav-tab <?php echo $tab === 'somas' ? 'nav-tab-active' : ''; ?>">
                Registos SOMAS
                <?php
                $pending_somas = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}rmbz_somas_registrations WHERE status='pending'" );
                if ( $pending_somas > 0 ) echo " <span class=\"awaiting-mod\"><span class=\"pending-count\">{$pending_somas}</span></span>";
                ?>
            </a>
            <a href="?page=rmbz-licensing&tab=licenses" class="nav-tab <?php echo $tab === 'licenses' ? 'nav-tab-active' : ''; ?>">
                Licenças
                <?php
                $pending_lic = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}rmbz_licenses WHERE status='pending'" );
                if ( $pending_lic > 0 ) echo " <span class=\"awaiting-mod\"><span class=\"pending-count\">{$pending_lic}</span></span>";
                ?>
            </a>
            <a href="?page=rmbz-licensing&tab=settings" class="nav-tab <?php echo $tab === 'settings' ? 'nav-tab-active' : ''; ?>">
                Configurações
            </a>
        </h2>

        <?php
        if ( $tab === 'somas' ) {
            if ( $detail_id > 0 ) rmbz_licensing_admin_render_somas_detail( $detail_id );
            else rmbz_licensing_admin_render_somas_list();
        } elseif ( $tab === 'licenses' ) {
            if ( $detail_id > 0 ) rmbz_licensing_admin_render_license_detail( $detail_id );
            else rmbz_licensing_admin_render_license_list();
        } elseif ( $tab === 'settings' ) {
            rmbz_licensing_admin_render_settings();
        }
        ?>
    </div>

    <style>
    .rmbz-lic-table { width:100%; border-collapse: collapse; margin-top:15px; }
    .rmbz-lic-table th, .rmbz-lic-table td { padding:10px; border-bottom:1px solid #eee; text-align:left; }
    .rmbz-lic-table th { background:#f6f7f7; font-weight:600; }
    .rmbz-lic-status { padding:3px 8px; border-radius:3px; font-size:11px; font-weight:600; text-transform:uppercase; }
    .rmbz-lic-status--pending { background:#fff3cd; color:#856404; }
    .rmbz-lic-status--approved { background:#d4edda; color:#155724; }
    .rmbz-lic-status--returned { background:#cce5ff; color:#004085; }
    .rmbz-lic-status--rejected, .rmbz-lic-status--refunded { background:#f8d7da; color:#721c24; }
    .rmbz-lic-detail-card { background:var(--rmbz-bg-card, #fff); padding:20px; border:1px solid #ddd; margin-top:20px; }
    .rmbz-lic-detail-card dl { display:grid; grid-template-columns: 200px 1fr; gap:8px 16px; }
    .rmbz-lic-detail-card dt { font-weight:600; color:var(--rmbz-text-secondary, #555); }
    </style>
    <?php
}

function rmbz_licensing_admin_render_somas_list() {
    global $wpdb;
    $rows = $wpdb->get_results(
        "SELECT * FROM {$wpdb->prefix}rmbz_somas_registrations
         ORDER BY FIELD(status,'pending','returned','approved','rejected'), created_at DESC"
    );
    ?>
    <table class="rmbz-lic-table">
        <thead><tr>
            <th>ID</th><th>Tipo</th><th>Artista</th><th>Telemóvel</th><th>Status</th><th>Cobrado</th>
            <th>Data</th><th>Nº SOMAS</th><th>Ações</th>
        </tr></thead>
        <tbody>
        <?php foreach ($rows as $r):
            $data = json_decode( $r->form_data, true ) ?: [];
            $name = trim( ($data['nome'] ?? '') . ' ' . ($data['apelido'] ?? '') );
            $type_label = ( $r->submission_type === 'existing_member' ) ? '🎫 Membro existente' : '📝 Registo novo';
            $type_color = ( $r->submission_type === 'existing_member' ) ? '#0073aa' : '#666';
        ?>
            <tr>
                <td>#<?php echo $r->id; ?></td>
                <td><span style="font-size:11px; color:<?php echo $type_color; ?>; font-weight:600;"><?php echo esc_html($type_label); ?></span></td>
                <td><?php echo esc_html( $name ?: '—' ); ?></td>
                <td><?php echo esc_html( $r->artist_telemovel ); ?></td>
                <td><span class="rmbz-lic-status rmbz-lic-status--<?php echo esc_attr($r->status); ?>"><?php echo esc_html($r->status); ?></span></td>
                <td><?php echo number_format((float)$r->amount_charged, 2, ',', '.'); ?> MT</td>
                <td><?php echo esc_html( date_i18n('d/m/Y H:i', strtotime($r->created_at)) ); ?></td>
                <td><?php echo $r->somas_number ? esc_html($r->somas_number) : '—'; ?></td>
                <td><a class="button" href="?page=rmbz-licensing&tab=somas&id=<?php echo $r->id; ?>">Ver</a></td>
            </tr>
        <?php endforeach; ?>
        <?php if ( empty($rows) ): ?>
            <tr><td colspan="9" style="text-align:center; color:var(--rmbz-text-faint, #888); padding:30px;">Sem registos SOMAS.</td></tr>
        <?php endif; ?>
        </tbody>
    </table>
    <?php
}

function rmbz_licensing_admin_render_somas_detail( $id ) {
    global $wpdb;
    $r = $wpdb->get_row( $wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}rmbz_somas_registrations WHERE id = %d", $id
    ) );
    if ( ! $r ) { echo '<p>Registo não encontrado.</p>'; return; }

    $data = json_decode( $r->form_data, true ) ?: [];
    $back = '?page=rmbz-licensing&tab=somas';
    ?>
    <p><a href="<?php echo $back; ?>">&larr; Voltar à lista</a></p>

    <div class="rmbz-lic-detail-card">
        <h2>Registo SOMAS #<?php echo $r->id; ?>
            <span class="rmbz-lic-status rmbz-lic-status--<?php echo esc_attr($r->status); ?>"><?php echo esc_html($r->status); ?></span>
            <?php
            // [DS 1.5.83] Badge do tipo de submissão (registo novo vs membro existente)
            $type_label = ( $r->submission_type === 'existing_member' ) ? '🎫 Membro existente' : '📝 Registo novo';
            $type_bg = ( $r->submission_type === 'existing_member' ) ? '#cce5ff' : '#e2e3e5';
            $type_color = ( $r->submission_type === 'existing_member' ) ? '#004085' : '#41464b';
            ?>
            <span style="background:<?php echo $type_bg; ?>; color:<?php echo $type_color; ?>; padding:3px 10px; border-radius:4px; font-size:11px; font-weight:600; margin-left:8px;">
                <?php echo esc_html($type_label); ?>
            </span>
        </h2>
        <dl>
            <dt>Artista (telemóvel)</dt><dd><?php echo esc_html($r->artist_telemovel); ?></dd>
            <dt>Submetido em</dt><dd><?php echo esc_html( date_i18n('d/m/Y H:i', strtotime($r->created_at)) ); ?></dd>
            <dt>Cobrado da carteira</dt><dd><?php echo number_format((float)$r->amount_charged, 2, ',', '.'); ?> MT</dd>
            <?php if ( $r->submission_type === 'existing_member' && $r->somas_number ): ?>
                <dt>Nº SOMAS declarado</dt>
                <dd>
                    <strong><?php echo esc_html($r->somas_number); ?></strong>
                    <?php if ( $r->status !== 'approved' ): ?>
                        <em style="color:#856404; font-size:12px;"> (a verificar com o comprovante)</em>
                    <?php endif; ?>
                </dd>
            <?php elseif ( $r->somas_number ): ?>
                <dt>Nº SOMAS aprovado</dt><dd><strong><?php echo esc_html($r->somas_number); ?></strong></dd>
            <?php endif; ?>
            <?php if ( $r->admin_note ): ?>
                <dt>Nota admin</dt><dd><?php echo esc_html($r->admin_note); ?></dd>
            <?php endif; ?>
        </dl>
        <?php if ( $r->submission_type === 'existing_member' ): ?>
            <p style="background:#e7f3ff; border-left:4px solid #0073aa; padding:10px 15px; margin-top:12px; font-size:13px;">
                ℹ️ Este artista afirma já ser membro da SOMAS. Verifica o comprovante abaixo
                para confirmar que o nº de registo é genuíno e bate com a identidade no BI.
            </p>
        <?php endif; ?>
    </div>

    <div class="rmbz-lic-detail-card">
        <h3>Dados do formulário SOMAS</h3>
        <dl>
            <?php
            $labels = [
                'apelido' => 'Apelido', 'nome' => 'Nome', 'morada' => 'Morada',
                'localidade' => 'Localidade', 'nacionalidade' => 'Nacionalidade',
                'telefone' => 'Telefone', 'telemovel_contacto' => 'Telemóvel',
                'caixa_postal' => 'Caixa Postal', 'email' => 'Email',
                'data_nascimento' => 'Data nasc.', 'bi_passaporte' => 'BI/Passaporte',
                'local_emissao' => 'Local emissão', 'data_emissao' => 'Data emissão',
                'pseudonimo' => 'Pseudónimo', 'nome_cartao' => 'Nome no cartão',
                'nib' => 'NIB', 'outra_sociedade' => 'Outra sociedade?',
                'outra_sociedade_qual' => 'Qual?', 'observacoes' => 'Observações',
            ];
            foreach ($labels as $k => $label):
                $v = $data[$k] ?? '';
                if ( $v === '' ) continue;
            ?>
                <dt><?php echo esc_html($label); ?></dt>
                <dd><?php echo esc_html($v); ?></dd>
            <?php endforeach; ?>
        </dl>
    </div>

    <?php // Card do BI/Passaporte submetido — VITAL para admin validar identidade ?>
    <?php if ( ! empty($r->bi_file_url) ): ?>
        <div class="rmbz-lic-detail-card">
            <h3>📎 BI/Passaporte submetido</h3>
            <p style="color:var(--rmbz-text-muted, #666); margin-bottom:15px;">
                Compara este documento com os dados acima (nome, nº BI, data emissão).
                Se não bater, devolve o pedido com o motivo específico.
            </p>
            <?php
            $bi_url = $r->bi_file_url;
            $is_pdf = ( strtolower( pathinfo($bi_url, PATHINFO_EXTENSION) ) === 'pdf' );
            ?>
            <?php if ( $is_pdf ): ?>
                <p>
                    <a href="<?php echo esc_url($bi_url); ?>" target="_blank" rel="noopener"
                       class="button button-primary">
                       📄 Abrir PDF do BI/Passaporte ↗
                    </a>
                </p>
                <p style="color:var(--rmbz-text-faint, #888); font-size:13px;">Ficheiro PDF — abre numa nova aba.</p>
            <?php else: ?>
                <a href="<?php echo esc_url($bi_url); ?>" target="_blank" rel="noopener" style="display:inline-block;">
                    <img src="<?php echo esc_url($bi_url); ?>" alt="BI submetido"
                         style="max-width:100%; max-height:500px; border:2px solid #ddd; border-radius:6px; cursor:zoom-in;">
                </a>
                <p style="color:var(--rmbz-text-faint, #888); font-size:13px; margin-top:10px;">Clica na imagem para ver em tamanho real.</p>
            <?php endif; ?>
        </div>
    <?php else: ?>
        <div class="rmbz-lic-detail-card" style="border-left:4px solid #d63638;">
            <h3>⚠ BI/Passaporte em falta</h3>
            <p>Este registo foi submetido sem ficheiro do BI (registo antigo, antes de 1.5.82).
               Não é possível validar a identidade.</p>
        </div>
    <?php endif; ?>

    <?php // [DS 1.5.83] Card do comprovante SOMAS — só para membros existentes ?>
    <?php if ( $r->submission_type === 'existing_member' ): ?>
        <?php if ( ! empty($r->somas_card_file_url) ): ?>
            <div class="rmbz-lic-detail-card" style="border-left:4px solid #0073aa;">
                <h3>🎫 Comprovante SOMAS submetido</h3>
                <p style="color:var(--rmbz-text-muted, #666); margin-bottom:15px;">
                    Documento que o artista diz ter recebido da SOMAS confirmando o seu registo.
                    Verifica que o nº de registo (<strong><?php echo esc_html($r->somas_number ?: '—'); ?></strong>)
                    aparece neste documento e que coincide com a identidade no BI.
                </p>
                <?php
                $card_url = $r->somas_card_file_url;
                $card_is_pdf = ( strtolower( pathinfo($card_url, PATHINFO_EXTENSION) ) === 'pdf' );
                ?>
                <?php if ( $card_is_pdf ): ?>
                    <p>
                        <a href="<?php echo esc_url($card_url); ?>" target="_blank" rel="noopener" class="button button-primary">
                           📄 Abrir comprovante SOMAS ↗
                        </a>
                    </p>
                <?php else: ?>
                    <a href="<?php echo esc_url($card_url); ?>" target="_blank" rel="noopener" style="display:inline-block;">
                        <img src="<?php echo esc_url($card_url); ?>" alt="Comprovante SOMAS"
                             style="max-width:100%; max-height:500px; border:2px solid #ddd; border-radius:6px; cursor:zoom-in;">
                    </a>
                    <p style="color:var(--rmbz-text-faint, #888); font-size:13px; margin-top:10px;">Clica na imagem para ver em tamanho real.</p>
                <?php endif; ?>
            </div>
        <?php else: ?>
            <div class="rmbz-lic-detail-card" style="border-left:4px solid #d63638;">
                <h3>⚠ Comprovante SOMAS em falta</h3>
                <p>Este pedido afirma ser membro existente mas não tem comprovante anexado.</p>
            </div>
        <?php endif; ?>
    <?php endif; ?>

    <?php if ( in_array( $r->status, ['pending', 'returned'], true ) ): ?>
        <div class="rmbz-lic-detail-card">
            <h3>Acções</h3>

            <h4>✓ Aprovar (atribuir nº SOMAS)</h4>
            <form method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>">
                <?php wp_nonce_field( 'rmbz_admin_approve_somas_' . $r->id, '_rmbz_nonce' ); ?>
                <input type="hidden" name="action" value="rmbz_admin_approve_somas">
                <input type="hidden" name="id" value="<?php echo $r->id; ?>">
                <p>
                    <label>Nº SOMAS atribuído pela SOMAS:</label><br>
                    <input type="text" name="somas_number" required style="width:300px;" placeholder="ex: MZ-2026-12345">
                </p>
                <p>
                    <label>Nota interna (opcional):</label><br>
                    <textarea name="admin_note" rows="2" style="width:100%;"></textarea>
                </p>
                <button type="submit" class="button button-primary">Aprovar</button>
            </form>

            <hr style="margin:25px 0;">

            <h4>↻ Devolver para correcção</h4>
            <form method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>">
                <?php wp_nonce_field( 'rmbz_admin_return_somas_' . $r->id, '_rmbz_nonce' ); ?>
                <input type="hidden" name="action" value="rmbz_admin_return_somas">
                <input type="hidden" name="id" value="<?php echo $r->id; ?>">
                <p>
                    <label>Motivo (visível ao artista):</label><br>
                    <textarea name="reason" rows="3" required style="width:100%;"></textarea>
                </p>
                <button type="submit" class="button">Devolver para edição</button>
            </form>

            <hr style="margin:25px 0;">

            <h4 style="color:var(--rmbz-danger-strong, #aa0000);">✕ Rejeitar (devolve <?php echo number_format((float)$r->amount_charged, 2, ',', '.'); ?> MT à carteira)</h4>
            <form method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>"
                  onsubmit="return confirm('Tens a certeza? O artista será reembolsado.');">
                <?php wp_nonce_field( 'rmbz_admin_reject_somas_' . $r->id, '_rmbz_nonce' ); ?>
                <input type="hidden" name="action" value="rmbz_admin_reject_somas">
                <input type="hidden" name="id" value="<?php echo $r->id; ?>">
                <p>
                    <label>Motivo da rejeição (visível ao artista):</label><br>
                    <textarea name="reason" rows="3" required style="width:100%;"></textarea>
                </p>
                <button type="submit" class="button button-link-delete">Rejeitar e reembolsar</button>
            </form>
        </div>
    <?php endif; ?>
    <?php
}

function rmbz_licensing_admin_render_license_list() {
    global $wpdb;
    $rows = $wpdb->get_results(
        "SELECT l.*, r.title AS release_title FROM {$wpdb->prefix}rmbz_licenses l
         LEFT JOIN {$wpdb->prefix}rmbz_distro_releases r ON r.id = l.release_id
         ORDER BY FIELD(l.status,'pending','processing','approved','refunded','rejected'), l.created_at DESC"
    );
    ?>
    <table class="rmbz-lic-table">
        <thead><tr>
            <th>ID</th><th>Release</th><th>Artista</th><th>Nº SOMAS</th><th>Faixas</th>
            <th>Cobrado</th><th>Status</th><th>Data</th><th>Ações</th>
        </tr></thead>
        <tbody>
        <?php foreach ($rows as $l): ?>
            <tr>
                <td>#<?php echo $l->id; ?></td>
                <td><?php echo esc_html($l->release_title ?: '(removido)'); ?></td>
                <td><?php echo esc_html($l->artist_telemovel); ?></td>
                <td><?php echo esc_html($l->somas_number); ?></td>
                <td><?php echo (int) $l->track_count; ?></td>
                <td><?php echo number_format((float)$l->amount_charged, 2, ',', '.'); ?> MT</td>
                <td><span class="rmbz-lic-status rmbz-lic-status--<?php echo esc_attr($l->status); ?>"><?php echo esc_html($l->status); ?></span></td>
                <td><?php echo esc_html( date_i18n('d/m/Y', strtotime($l->created_at)) ); ?></td>
                <td><a class="button" href="?page=rmbz-licensing&tab=licenses&id=<?php echo $l->id; ?>">Ver</a></td>
            </tr>
        <?php endforeach; ?>
        <?php if ( empty($rows) ): ?>
            <tr><td colspan="9" style="text-align:center; color:var(--rmbz-text-faint, #888); padding:30px;">Sem licenças.</td></tr>
        <?php endif; ?>
        </tbody>
    </table>
    <?php
}

function rmbz_licensing_admin_render_license_detail( $id ) {
    global $wpdb;
    $l = $wpdb->get_row( $wpdb->prepare(
        "SELECT l.*, r.title AS release_title FROM {$wpdb->prefix}rmbz_licenses l
         LEFT JOIN {$wpdb->prefix}rmbz_distro_releases r ON r.id = l.release_id
         WHERE l.id = %d", $id
    ) );
    if ( ! $l ) { echo '<p>Licença não encontrada.</p>'; return; }
    ?>
    <p><a href="?page=rmbz-licensing&tab=licenses">&larr; Voltar à lista</a></p>

    <div class="rmbz-lic-detail-card">
        <h2>Licença #<?php echo $l->id; ?>
            <span class="rmbz-lic-status rmbz-lic-status--<?php echo esc_attr($l->status); ?>"><?php echo esc_html($l->status); ?></span>
        </h2>
        <dl>
            <dt>Release</dt><dd><?php echo esc_html($l->release_title ?: '(removido)'); ?> (#<?php echo (int)$l->release_id; ?>)</dd>
            <dt>Artista</dt><dd><?php echo esc_html($l->artist_telemovel); ?></dd>
            <dt>Nº SOMAS</dt><dd><?php echo esc_html($l->somas_number); ?></dd>
            <dt>Nº faixas</dt><dd><?php echo (int) $l->track_count; ?></dd>
            <dt>Preço unitário</dt><dd><?php echo number_format((float)$l->unit_price, 2, ',', '.'); ?> MT</dd>
            <dt>Subtotal</dt><dd><?php echo number_format((float)$l->total_price, 2, ',', '.'); ?> MT</dd>
            <?php if ( $l->coupon_id ): ?>
                <dt>Desconto cupão</dt><dd>−<?php echo number_format((float)$l->coupon_discount, 2, ',', '.'); ?> MT</dd>
            <?php endif; ?>
            <dt>Cobrado</dt><dd><strong><?php echo number_format((float)$l->amount_charged, 2, ',', '.'); ?> MT</strong></dd>
            <dt>Submetido em</dt><dd><?php echo esc_html( date_i18n('d/m/Y H:i', strtotime($l->created_at)) ); ?></dd>
            <?php if ( $l->completed_at ): ?>
                <dt>Concluído em</dt><dd><?php echo esc_html( date_i18n('d/m/Y H:i', strtotime($l->completed_at)) ); ?></dd>
            <?php endif; ?>
            <?php if ( $l->admin_note ): ?>
                <dt>Nota admin</dt><dd><?php echo esc_html($l->admin_note); ?></dd>
            <?php endif; ?>
        </dl>
    </div>

    <?php if ( in_array( $l->status, ['pending','processing'], true ) ): ?>
        <div class="rmbz-lic-detail-card">
            <h3>Acções</h3>

            <h4>✓ Aprovar (marcar como processado na SOMAS)</h4>
            <form method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>">
                <?php wp_nonce_field( 'rmbz_admin_approve_license_' . $l->id, '_rmbz_nonce' ); ?>
                <input type="hidden" name="action" value="rmbz_admin_approve_license">
                <input type="hidden" name="id" value="<?php echo $l->id; ?>">
                <p>
                    <label>Nota interna (opcional):</label><br>
                    <textarea name="admin_note" rows="2" style="width:100%;"></textarea>
                </p>
                <button type="submit" class="button button-primary">Marcar como aprovado</button>
            </form>

            <hr style="margin:25px 0;">

            <h4 style="color:var(--rmbz-danger-strong, #aa0000);">✕ Rejeitar (devolve <?php echo number_format((float)$l->amount_charged, 2, ',', '.'); ?> MT à carteira)</h4>
            <form method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>"
                  onsubmit="return confirm('Tens a certeza? O artista será reembolsado automaticamente.');">
                <?php wp_nonce_field( 'rmbz_admin_reject_license_' . $l->id, '_rmbz_nonce' ); ?>
                <input type="hidden" name="action" value="rmbz_admin_reject_license">
                <input type="hidden" name="id" value="<?php echo $l->id; ?>">
                <p>
                    <label>Motivo (visível ao artista):</label><br>
                    <textarea name="reason" rows="3" required style="width:100%;"></textarea>
                </p>
                <button type="submit" class="button button-link-delete">Rejeitar e reembolsar</button>
            </form>
        </div>
    <?php endif; ?>
    <?php
}

function rmbz_licensing_admin_render_settings() {
    if ( isset($_POST['_rmbz_settings_nonce']) && wp_verify_nonce($_POST['_rmbz_settings_nonce'], 'rmbz_lic_settings') ) {
        update_option( 'rmbz_licensing_enabled', isset($_POST['enabled']) ? '1' : '0' );
        update_option( 'rmbz_licensing_price_registration', max(0, (float) $_POST['price_registration']) );
        update_option( 'rmbz_licensing_price_per_track', max(0, (float) $_POST['price_per_track']) );
        // [DS 1.5.83] Novo: preço para validação de membros SOMAS existentes
        update_option( 'rmbz_licensing_price_existing_member', max(0, (float) ($_POST['price_existing_member'] ?? 0)) );
        echo '<div class="notice notice-success"><p>Configurações guardadas.</p></div>';
    }
    ?>
    <form method="post">
        <?php wp_nonce_field( 'rmbz_lic_settings', '_rmbz_settings_nonce' ); ?>
        <table class="form-table">
            <tr>
                <th>Activar serviço</th>
                <td><label>
                    <input type="checkbox" name="enabled" value="1" <?php checked( rmbz_licensing_is_enabled() ); ?>>
                    Permitir aos artistas usar o licenciamento
                </label></td>
            </tr>
            <tr>
                <th>📝 Preço — registo SOMAS NOVO (MT)</th>
                <td>
                    <input type="number" step="0.01" name="price_registration" value="<?php echo esc_attr( rmbz_licensing_get_registration_price() ); ?>" min="0" required>
                    <p class="description">Cobrado a artistas que ainda NÃO são membros da SOMAS. Cobre o trabalho de processar e enviar a inscrição à SOMAS.</p>
                </td>
            </tr>
            <tr>
                <th>🎫 Preço — validação de membro EXISTENTE (MT)</th>
                <td>
                    <input type="number" step="0.01" name="price_existing_member" value="<?php echo esc_attr( rmbz_licensing_get_existing_member_price() ); ?>" min="0" required>
                    <p class="description">
                        Cobrado a artistas que JÁ são membros da SOMAS e só precisam validar o nº de registo.
                        Define <strong>0</strong> para tornar grátis, ou um valor pequeno (ex: 50 MT) para cobrir o tempo de validação manual.
                    </p>
                </td>
            </tr>
            <tr>
                <th>🎼 Preço por faixa licenciada (MT)</th>
                <td>
                    <input type="number" step="0.01" name="price_per_track" value="<?php echo esc_attr( rmbz_licensing_get_per_track_price() ); ?>" min="0" required>
                    <p class="description">Cobrado por cada faixa quando o artista licencia um lançamento (single = 1 faixa, álbum = 7+).</p>
                </td>
            </tr>
        </table>
        <p><button type="submit" class="button button-primary">Guardar</button></p>
    </form>

    <hr>
    <h3>Cupões para licenciamento</h3>
    <p>
        Cria cupões na <a href="<?php echo admin_url('admin.php?page=rmbz-cupoes'); ?>">página de Cupões</a>
        e usa um destes <em>reward types</em>:
    </p>
    <ul style="list-style:disc; padding-left:30px;">
        <li><code>licensing_discount_percent</code> — desconto percentual (reward_value = % ex: 20)</li>
        <li><code>licensing_discount_fixed</code> — desconto fixo em MT (reward_value = MT)</li>
        <li><code>licensing_free_tracks</code> — N faixas grátis (reward_value = nº de faixas)</li>
    </ul>
    <?php
}


/* ============================================================================
 * 13. HANDLERS — POST de ações admin
 * ============================================================================ */

function rmbz_licensing_handle_admin_approve_somas() {
    if ( ! current_user_can('manage_options') ) wp_die('Sem permissão.');
    $id = (int) ($_POST['id'] ?? 0);
    if ( ! wp_verify_nonce($_POST['_rmbz_nonce'] ?? '', 'rmbz_admin_approve_somas_' . $id) ) wp_die('Nonce inválido.');

    $somas_number = sanitize_text_field( $_POST['somas_number'] ?? '' );
    $admin_note = sanitize_textarea_field( $_POST['admin_note'] ?? '' );
    $result = rmbz_licensing_admin_approve_somas( $id, $somas_number, $admin_note );

    $url = admin_url('admin.php?page=rmbz-licensing&tab=somas&id=' . $id);
    if ( ! $result['success'] ) $url .= '&error=' . urlencode($result['error']);
    wp_redirect($url); exit;
}
add_action('admin_post_rmbz_admin_approve_somas', 'rmbz_licensing_handle_admin_approve_somas');

function rmbz_licensing_handle_admin_return_somas() {
    if ( ! current_user_can('manage_options') ) wp_die('Sem permissão.');
    $id = (int) ($_POST['id'] ?? 0);
    if ( ! wp_verify_nonce($_POST['_rmbz_nonce'] ?? '', 'rmbz_admin_return_somas_' . $id) ) wp_die('Nonce inválido.');

    $reason = sanitize_textarea_field( $_POST['reason'] ?? '' );
    rmbz_licensing_admin_return_somas( $id, $reason );
    wp_redirect( admin_url('admin.php?page=rmbz-licensing&tab=somas') ); exit;
}
add_action('admin_post_rmbz_admin_return_somas', 'rmbz_licensing_handle_admin_return_somas');

function rmbz_licensing_handle_admin_reject_somas() {
    if ( ! current_user_can('manage_options') ) wp_die('Sem permissão.');
    $id = (int) ($_POST['id'] ?? 0);
    if ( ! wp_verify_nonce($_POST['_rmbz_nonce'] ?? '', 'rmbz_admin_reject_somas_' . $id) ) wp_die('Nonce inválido.');

    $reason = sanitize_textarea_field( $_POST['reason'] ?? '' );
    rmbz_licensing_admin_reject_somas( $id, $reason );
    wp_redirect( admin_url('admin.php?page=rmbz-licensing&tab=somas') ); exit;
}
add_action('admin_post_rmbz_admin_reject_somas', 'rmbz_licensing_handle_admin_reject_somas');

function rmbz_licensing_handle_admin_approve_license() {
    if ( ! current_user_can('manage_options') ) wp_die('Sem permissão.');
    $id = (int) ($_POST['id'] ?? 0);
    if ( ! wp_verify_nonce($_POST['_rmbz_nonce'] ?? '', 'rmbz_admin_approve_license_' . $id) ) wp_die('Nonce inválido.');

    $admin_note = sanitize_textarea_field( $_POST['admin_note'] ?? '' );
    rmbz_licensing_admin_approve_license( $id, $admin_note );
    wp_redirect( admin_url('admin.php?page=rmbz-licensing&tab=licenses&id=' . $id) ); exit;
}
add_action('admin_post_rmbz_admin_approve_license', 'rmbz_licensing_handle_admin_approve_license');

function rmbz_licensing_handle_admin_reject_license() {
    if ( ! current_user_can('manage_options') ) wp_die('Sem permissão.');
    $id = (int) ($_POST['id'] ?? 0);
    if ( ! wp_verify_nonce($_POST['_rmbz_nonce'] ?? '', 'rmbz_admin_reject_license_' . $id) ) wp_die('Nonce inválido.');

    $reason = sanitize_textarea_field( $_POST['reason'] ?? '' );
    rmbz_licensing_admin_reject_license( $id, $reason );
    wp_redirect( admin_url('admin.php?page=rmbz-licensing&tab=licenses') ); exit;
}
add_action('admin_post_rmbz_admin_reject_license', 'rmbz_licensing_handle_admin_reject_license');


/* ============================================================================
 * 14. REGISTO NO MENU ADMIN E INIT
 * ============================================================================ */

add_action( 'admin_menu', function() {
    add_submenu_page(
        'rmbz-dashboard',
        'Licenciamento Musical',
        'Licenciamento 🎼',
        'manage_options',
        'rmbz-licensing',
        'rmbz_licensing_admin_page'
    );
}, 11 );

// Garantir que as tabelas existem ao carregar (idempotente)
add_action( 'plugins_loaded', 'rmbz_licensing_maybe_install_tables', 5 );


/* ============================================================================
 * 15. INTEGRAÇÃO COM ROUTER DE DISTRIBUIÇÃO (frontend)
 * ============================================================================ */

/**
 * Hook para o router da distribuição reconhecer ?distro_action=licensing-somas.
 * Renderiza o formulário SOMAS dentro do contexto da distribuição.
 */
add_action( 'rmbz_distro_route_licensing-somas', function( $telemovel ) {
    ?>
    <div class="distro-licensing-container rmbz-fullbleed">
        <div class="distro-header">
            <h1>Registo SOMAS</h1>
            <a href="?distro_action=dashboard" class="back-link">&larr; Voltar</a>
        </div>
        <?php rmbz_licensing_render_somas_form( $telemovel ); ?>
    </div>
    <style>
    .distro-licensing-container { color:var(--rmbz-text-primary, #fff); padding:30px; }
    .distro-licensing-container .distro-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:30px; }
    .distro-licensing-container .back-link { color:var(--rmbz-text-muted, #aaa); text-decoration:none; }
    .rmbz-licensing-status { padding:20px; border-radius:8px; margin-bottom:25px; display:flex; gap:15px; align-items:flex-start; }
    .rmbz-licensing-status__icon { font-size:32px; flex-shrink:0; }
    .rmbz-licensing-status h3 { margin:0 0 8px 0; }
    .rmbz-licensing-status p { margin:0 0 5px 0; }
    .rmbz-licensing-status__note { color:rgba(255,255,255,0.7); font-size:13px; }
    .rmbz-licensing-status--ok { background:rgba(46,204,113,0.1); border:1px solid rgba(46,204,113,0.3); }
    .rmbz-licensing-status--pending { background:rgba(241,196,15,0.1); border:1px solid rgba(241,196,15,0.3); }
    .rmbz-licensing-status--warning { background:rgba(230,126,34,0.1); border:1px solid rgba(230,126,34,0.3); }
    .rmbz-licensing-status--danger { background:rgba(231,76,60,0.1); border:1px solid rgba(231,76,60,0.3); }
    .rmbz-licensing-form-intro { background:var(--rmbz-bg-surface, #1a1a1a); padding:20px; border-radius:8px; margin-bottom:25px; }
    .rmbz-licensing-form-intro h3 { margin:0 0 10px 0; }
    .rmbz-licensing-balance-row { display:flex; gap:10px; align-items:center; margin-top:15px; padding:10px; background:var(--rmbz-bg-elevated, #0e0e0e); border-radius:5px; }
    .rmbz-licensing-balance-warn { color:var(--rmbz-warning, #f59e0b); font-size:13px; }
    .rmbz-somas-form { background:var(--rmbz-bg-surface, #1a1a1a); padding:25px; border-radius:8px; }
    .rmbz-somas-fieldset { border:1px solid #333; padding:20px; margin-bottom:20px; border-radius:6px; }
    .rmbz-somas-fieldset legend { padding:0 10px; color:var(--rmbz-brand, #f0b90b); font-weight:bold; }
    .rmbz-somas-grid { display:grid; grid-template-columns:1fr 1fr; gap:15px; }
    .rmbz-somas-grid__full { grid-column:1 / -1; }
    .rmbz-somas-grid label { display:flex; flex-direction:column; gap:5px; font-size:13px; color:var(--rmbz-text-secondary, #ccc); }
    .rmbz-somas-grid input, .rmbz-somas-grid select, .rmbz-somas-fieldset textarea {
        background:var(--rmbz-bg-elevated, #0e0e0e); border:1px solid #333; color:var(--rmbz-text-primary, #fff); padding:10px; border-radius:4px; font:inherit;
    }
    .rmbz-somas-grid input:focus, .rmbz-somas-grid select:focus, .rmbz-somas-fieldset textarea:focus {
        outline:none; border-color:var(--rmbz-brand, #f0b90b);
    }
    .rmbz-somas-fieldset textarea { width:100%; box-sizing:border-box; }
    .rmbz-somas-actions { text-align:center; padding-top:10px; }
    .rmbz-somas-disclaimer { font-size:12px; color:var(--rmbz-text-faint, #888); margin-top:15px; max-width:600px; margin-left:auto; margin-right:auto; }
    @media (max-width:600px) { .rmbz-somas-grid { grid-template-columns:1fr; } }

    .rmbz-license-step { background:var(--rmbz-bg-surface, #1a1a1a); padding:25px; border-radius:8px; margin-top:20px; }
    .rmbz-license-step__title { margin:0 0 10px 0; color:var(--rmbz-brand, #f0b90b); }
    .rmbz-license-step__intro { color:var(--rmbz-text-secondary, #ccc); margin-bottom:20px; }
    .rmbz-license-existing, .rmbz-license-need-somas {
        padding:20px; background:var(--rmbz-bg-elevated, #0e0e0e); border-radius:6px; display:flex; gap:15px; align-items:center;
    }
    .rmbz-license-existing__icon { font-size:24px; color:var(--rmbz-success, #10b981); }
    .rmbz-license-existing__detail { color:var(--rmbz-text-muted, #aaa); font-size:13px; margin:5px 0 0; }
    .rmbz-license-need-somas { flex-direction:column; align-items:flex-start; }
    .rmbz-license-need-somas--pending { background:rgba(241,196,15,0.05); }
    .rmbz-license-need-somas--warning { background:rgba(230,126,34,0.05); }
    .rmbz-license-need-somas__skip { color:var(--rmbz-text-faint, #777); font-size:12px; }
    .rmbz-license-pricing { background:var(--rmbz-bg-elevated, #0e0e0e); padding:15px; border-radius:6px; margin-bottom:20px; }
    .rmbz-license-pricing__row { display:flex; justify-content:space-between; padding:6px 0; }
    .rmbz-license-pricing__total { border-top:1px solid #333; padding-top:10px; margin-top:5px; font-size:16px; }
    .rmbz-license-pricing__balance { color:var(--rmbz-text-muted, #aaa); font-size:13px; margin-top:10px; padding-top:10px; border-top:1px solid #333; }
    .rmbz-license-coupon { margin-bottom:20px; }
    .rmbz-license-coupon__row { display:flex; gap:10px; margin-top:8px; }
    .rmbz-license-coupon__row input { flex:1; background:var(--rmbz-bg-elevated, #0e0e0e); border:1px solid #333; color:var(--rmbz-text-primary, #fff); padding:10px; border-radius:4px; }
    .rmbz-license-coupon__msg { font-size:13px; margin-top:8px; min-height:18px; }
    .rmbz-license-actions { display:flex; gap:10px; flex-wrap:wrap; }
    @media (max-width:600px) { .rmbz-license-actions .rmbz-btn { flex:1; min-width:140px; } }
    </style>
    <?php
});


/* ============================================================================
 * 16. ALERTA NA DISTRIBUIÇÃO + PÁGINA "DADOS DO ARTISTA"
 * ============================================================================ */

/**
 * [DS 1.5.82] Renderiza um banner/alerta de pendência SOMAS, e devolve TRUE
 * se o conteúdo da página deve ser BLOQUEADO (artista tem pedido pending ou
 * returned que precisa de resolver primeiro).
 *
 * Comportamento por estado:
 *   - approved → não mostra banner, devolve false (página normal)
 *   - pending  → mostra banner azul "em análise" + bloqueia página
 *   - returned → mostra banner laranja "corrige" + bloqueia página
 *   - rejected → mostra banner cinza informativo, NÃO bloqueia (artista pode
 *                continuar a usar a distribuição; só não tem licenciamento)
 *   - sem registo → não mostra nada (artista pode usar distribuição
 *                normalmente; só verá o convite no wizard quando relevante)
 *
 * @param string $telemovel
 * @return bool  TRUE se deve bloquear o resto da página
 */
function rmbz_licensing_render_pending_alert( $telemovel ) {
    $reg = rmbz_licensing_get_artist_somas_registration( $telemovel );

    if ( ! $reg ) return false; // sem registo = sem alerta
    if ( $reg->status === 'approved' ) return false; // tudo ok
    if ( $reg->status === 'rejected' ) return false; // sem bloqueio (info opcional)

    $is_returned = ( $reg->status === 'returned' );
    $variant = $is_returned ? 'returned' : 'pending';
    $form_data = json_decode( $reg->form_data, true ) ?: [];

    ?>
    <div class="rmbz-somas-alert rmbz-somas-alert--<?php echo esc_attr($variant); ?>">
        <div class="rmbz-somas-alert__icon">
            <?php if ( $is_returned ): ?>⚠<?php else: ?>⏳<?php endif; ?>
        </div>
        <div class="rmbz-somas-alert__body">
            <?php if ( $is_returned ): ?>
                <h3 class="rmbz-somas-alert__title">Pedido SOMAS devolvido — precisa da tua atenção</h3>
                <p class="rmbz-somas-alert__msg">
                    <strong>Motivo do admin:</strong>
                    <?php echo esc_html( $reg->admin_note ?: 'Sem detalhes — contacta-nos.' ); ?>
                </p>
                <p class="rmbz-somas-alert__msg">
                    A distribuição fica indisponível até resolveres este pedido.
                    Vai ao formulário, corrige o que está errado, e re-submete.
                </p>
                <a href="?distro_action=licensing-somas" class="rmbz-somas-alert__cta">
                    Corrigir pedido SOMAS &rarr;
                </a>
            <?php else: ?>
                <h3 class="rmbz-somas-alert__title">Pedido SOMAS em análise</h3>
                <p class="rmbz-somas-alert__msg">
                    Estamos a analisar o teu pedido de registo na SOMAS submetido em
                    <?php echo esc_html( date_i18n('d/m/Y', strtotime($reg->created_at)) ); ?>.
                </p>
                <p class="rmbz-somas-alert__msg">
                    <strong>A distribuição fica indisponível até este processo terminar.</strong>
                    Vais receber um email assim que o registo for aprovado.
                </p>
                <p class="rmbz-somas-alert__msg" style="opacity:.8; font-size:13px;">
                    Cobrámos <?php echo number_format( (float)$reg->amount_charged, 2, ',', '.' ); ?> MT da carteira.
                    Se o pedido for rejeitado, o valor é devolvido automaticamente.
                </p>
            <?php endif; ?>
        </div>
    </div>

    <style>
    .rmbz-somas-alert {
        display: flex;
        gap: 18px;
        padding: 24px;
        border-radius: 12px;
        margin: 20px 0 30px;
        align-items: flex-start;
    }
    .rmbz-somas-alert--pending {
        background: linear-gradient(135deg, rgba(59,130,246,0.12), rgba(59,130,246,0.04));
        border: 1px solid rgba(59,130,246,0.3);
    }
    .rmbz-somas-alert--returned {
        background: linear-gradient(135deg, rgba(241,196,15,0.12), rgba(241,196,15,0.04));
        border: 1px solid rgba(241,196,15,0.4);
    }
    .rmbz-somas-alert__icon {
        font-size: 32px;
        flex-shrink: 0;
        line-height: 1;
    }
    .rmbz-somas-alert--pending  .rmbz-somas-alert__icon { color: var(--rmbz-info, #3b82f6); }
    .rmbz-somas-alert--returned .rmbz-somas-alert__icon { color: var(--rmbz-brand, #f1c40f); }
    .rmbz-somas-alert__body { flex: 1; min-width: 0; }
    .rmbz-somas-alert__title { margin: 0 0 8px; color: var(--rmbz-text-primary, #fff); font-size: 18px; font-weight: 700; }
    .rmbz-somas-alert__msg { margin: 0 0 8px; color: var(--rmbz-text-secondary, #ccc); font-size: 14px; line-height: 1.6; }
    .rmbz-somas-alert__msg:last-child { margin-bottom: 0; }
    .rmbz-somas-alert__cta {
        display: inline-block;
        margin-top: 12px;
        padding: 10px 20px;
        background: var(--rmbz-brand, #f0b90b);
        color: #000;
        text-decoration: none;
        border-radius: 6px;
        font-weight: 700;
        font-size: 14px;
    }
    .rmbz-somas-alert__cta:hover { background: var(--rmbz-brand-strong, #fcc524); }
    @media (max-width: 600px) {
        .rmbz-somas-alert { flex-direction: column; gap: 12px; padding: 20px; }
    }
    </style>
    <?php
    return true; // bloqueia o resto da página
}

/**
 * Hook na renderização do dashboard de distribuição.
 * Quando o artista tem pendência SOMAS, abortamos o rendering normal:
 * mostramos só o banner + uma mensagem amigável + botão para resolver.
 */
add_action( 'rmbz_distro_dashboard_before_render', function( $telemovel ) {
    $blocking = rmbz_licensing_render_pending_alert( $telemovel );
    if ( $blocking ) {
        // Não chama exit aqui — o caller decide. O caller verifica o
        // valor de retorno via outra função abaixo.
    }
}, 10, 1 );

/**
 * Helper para o router de distribuição saber se deve bloquear renderização
 * de uma rota específica (dashboard, list, wizard, profiles, etc).
 *
 * O alerta + bloqueio aplica-se a TODAS as rotas excepto:
 *   - licensing-somas (a própria rota onde o artista resolve)
 *   - artist-data (pode sempre ver os seus dados)
 */
function rmbz_licensing_should_block_route( $telemovel, $action ) {
    if ( in_array( $action, ['licensing-somas', 'artist-data'], true ) ) return false;

    // [DS 1.5.84] Se serviço está desactivado, não bloqueia ninguém —
    // artista pode usar a distribuição normalmente. Quando o serviço
    // for reactivado, o bloqueio volta a aplicar-se.
    if ( ! rmbz_licensing_is_enabled() ) return false;

    $reg = rmbz_licensing_get_artist_somas_registration( $telemovel );
    if ( ! $reg ) return false;
    return in_array( $reg->status, ['pending', 'returned'], true );
}


/* ============================================================================
 * 17. PÁGINA "DADOS DO ARTISTA" — sumário pessoal + estado SOMAS
 * ============================================================================ */

add_action( 'rmbz_distro_route_artist-data', function( $telemovel ) {
    rmbz_licensing_render_artist_data_page( $telemovel );
});

function rmbz_licensing_render_artist_data_page( $telemovel ) {
    global $wpdb;

    $reg = rmbz_licensing_get_artist_somas_registration( $telemovel );
    $wallet = $wpdb->get_row( $wpdb->prepare(
        "SELECT user_nome, user_email, user_provincia FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel = %s",
        $telemovel
    ) );

    // Stats: nº de licenças aprovadas
    $licenses_approved = (int) $wpdb->get_var( $wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->prefix}rmbz_licenses WHERE artist_telemovel = %s AND status='approved'",
        $telemovel
    ) );
    $tracks_licensed = (int) $wpdb->get_var( $wpdb->prepare(
        "SELECT COALESCE(SUM(track_count), 0) FROM {$wpdb->prefix}rmbz_licenses WHERE artist_telemovel = %s AND status='approved'",
        $telemovel
    ) );

    ?>
    <div class="distro-artist-data rmbz-fullbleed">
        <div class="distro-header">
            <h1>Dados do Artista</h1>
            <a href="?distro_action=dashboard" class="back-link">&larr; Voltar</a>
        </div>

        <?php
        // Mesmo nesta página queremos mostrar o alerta SOMAS se houver pendência
        // (mas não bloqueamos — esta é uma das páginas seguras).
        rmbz_licensing_render_pending_alert( $telemovel );
        ?>

        <div class="rmbz-artist-data-grid">

            <!-- CARD: Identificação básica -->
            <div class="rmbz-artist-data-card">
                <h3 class="rmbz-artist-data-card__title">👤 Identificação</h3>
                <dl class="rmbz-artist-data-dl">
                    <dt>Nome</dt><dd><?php echo esc_html( $wallet->user_nome ?? '—' ); ?></dd>
                    <dt>Email</dt><dd><?php echo esc_html( $wallet->user_email ?? '—' ); ?></dd>
                    <dt>Telemóvel</dt><dd><?php echo esc_html( $telemovel ); ?></dd>
                    <dt>Província</dt><dd><?php echo esc_html( $wallet->user_provincia ?? '—' ); ?></dd>
                </dl>
            </div>

            <?php
            // [DS 1.5.84] Card SOMAS — esconde se serviço está desactivado E
            // o artista NUNCA submeteu pedido. Se já tem registo (mesmo
            // pendente/aprovado), mantém visível porque é dado histórico
            // importante (não pode desaparecer só porque admin desactivou).
            $licensing_active = rmbz_licensing_is_enabled();
            $show_somas_card = $licensing_active || ! empty($reg);
            ?>
            <?php if ( $show_somas_card ): ?>
            <!-- CARD: Estado SOMAS -->
            <div class="rmbz-artist-data-card rmbz-artist-data-card--<?php echo $reg ? esc_attr($reg->status) : 'none'; ?>">
                <h3 class="rmbz-artist-data-card__title">🎼 Registo SOMAS</h3>

                <?php if ( ! $licensing_active && $reg ): ?>
                    <p style="background:rgba(231,76,60,0.08); border:1px solid rgba(231,76,60,0.3); padding:8px 12px; border-radius:5px; color:var(--rmbz-danger, #ef4444); font-size:12px; margin:0 0 14px;">
                        ⓘ Serviço de licenciamento temporariamente desactivado — os teus dados estão preservados.
                    </p>
                <?php endif; ?>

                <?php if ( ! $reg ): ?>
                    <p class="rmbz-artist-data-status">
                        <span class="rmbz-artist-data-badge rmbz-artist-data-badge--none">Não registado</span>
                    </p>
                    <p class="rmbz-artist-data-card__desc">
                        Regista-te na SOMAS para começar a receber direitos autorais
                        cada vez que as tuas músicas são tocadas.
                    </p>
                    <a href="?distro_action=licensing-somas" class="rmbz-artist-data-cta">
                        Criar registo SOMAS
                    </a>

                <?php elseif ( $reg->status === 'approved' ): ?>
                    <p class="rmbz-artist-data-status">
                        <span class="rmbz-artist-data-badge rmbz-artist-data-badge--ok">✓ Registado</span>
                    </p>
                    <dl class="rmbz-artist-data-dl">
                        <dt>Nº SOMAS</dt>
                        <dd><strong style="color:var(--rmbz-brand, #f0b90b); font-size:16px;"><?php echo esc_html($reg->somas_number); ?></strong></dd>
                        <dt>Aprovado em</dt>
                        <dd><?php echo esc_html( date_i18n('d/m/Y', strtotime($reg->approved_at ?: $reg->updated_at)) ); ?></dd>
                        <dt>Licenças aprovadas</dt>
                        <dd><?php echo $licenses_approved; ?> (<?php echo $tracks_licensed; ?> faixas)</dd>
                    </dl>

                <?php elseif ( $reg->status === 'pending' ): ?>
                    <p class="rmbz-artist-data-status">
                        <span class="rmbz-artist-data-badge rmbz-artist-data-badge--pending">⏳ Em análise</span>
                    </p>
                    <p class="rmbz-artist-data-card__desc">
                        Submetido em <?php echo esc_html( date_i18n('d/m/Y', strtotime($reg->created_at)) ); ?>.
                        Estamos a processar — vais receber um email quando estiver aprovado.
                    </p>

                <?php elseif ( $reg->status === 'returned' ): ?>
                    <p class="rmbz-artist-data-status">
                        <span class="rmbz-artist-data-badge rmbz-artist-data-badge--warn">⚠ Devolvido para correcção</span>
                    </p>
                    <p class="rmbz-artist-data-card__desc">
                        <strong>Motivo:</strong>
                        <?php echo esc_html( $reg->admin_note ?: '(sem detalhes)' ); ?>
                    </p>
                    <a href="?distro_action=licensing-somas" class="rmbz-artist-data-cta">
                        Corrigir e re-submeter
                    </a>

                <?php else: /* rejected */ ?>
                    <p class="rmbz-artist-data-status">
                        <span class="rmbz-artist-data-badge rmbz-artist-data-badge--rejected">✕ Rejeitado</span>
                    </p>
                    <p class="rmbz-artist-data-card__desc">
                        <strong>Motivo:</strong>
                        <?php echo esc_html( $reg->admin_note ?: '(sem detalhes)' ); ?><br>
                        A quantia paga foi devolvida à carteira.
                    </p>
                    <a href="?distro_action=licensing-somas" class="rmbz-artist-data-cta">
                        Submeter novo pedido
                    </a>
                <?php endif; ?>
            </div>
            <?php endif; /* show_somas_card */ ?>

        </div>
    </div>

    <style>
    .distro-artist-data { color:var(--rmbz-text-primary, #fff); padding:30px; }
    .distro-artist-data .distro-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:24px; }
    .distro-artist-data .back-link { color:var(--rmbz-text-muted, #aaa); text-decoration:none; font-size:14px; }
    .distro-artist-data .back-link:hover { color:var(--rmbz-brand, #f0b90b); }

    .rmbz-artist-data-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
        gap: 20px;
    }
    .rmbz-artist-data-card {
        background: var(--rmbz-bg-surface, #1a1a1a);
        border: 1px solid #2a2a2a;
        border-radius: 12px;
        padding: 24px;
    }
    .rmbz-artist-data-card--approved { border-color: rgba(46,204,113,0.4); }
    .rmbz-artist-data-card--pending  { border-color: rgba(59,130,246,0.4); }
    .rmbz-artist-data-card--returned { border-color: rgba(241,196,15,0.5); }
    .rmbz-artist-data-card--rejected { border-color: rgba(231,76,60,0.4); }
    .rmbz-artist-data-card__title {
        margin: 0 0 16px;
        font-size: 17px;
        font-weight: 700;
        color: var(--rmbz-text-primary, #fff);
        padding-bottom: 12px;
        border-bottom: 1px solid #2a2a2a;
    }
    .rmbz-artist-data-status { margin: 0 0 14px; }
    .rmbz-artist-data-badge {
        display: inline-block;
        padding: 5px 12px;
        border-radius: 20px;
        font-size: 12px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.5px;
    }
    .rmbz-artist-data-badge--ok       { background: rgba(46,204,113,0.15); color: var(--rmbz-success, #10b981); border:1px solid rgba(46,204,113,0.4); }
    .rmbz-artist-data-badge--pending  { background: rgba(59,130,246,0.15); color: var(--rmbz-info, #3b82f6); border:1px solid rgba(59,130,246,0.4); }
    .rmbz-artist-data-badge--warn     { background: rgba(241,196,15,0.15); color: var(--rmbz-brand, #f1c40f); border:1px solid rgba(241,196,15,0.4); }
    .rmbz-artist-data-badge--rejected { background: rgba(231,76,60,0.15); color: var(--rmbz-danger, #ef4444); border:1px solid rgba(231,76,60,0.4); }
    .rmbz-artist-data-badge--none     { background: var(--rmbz-bg-elevated, #2a2a2a); color: var(--rmbz-text-faint, #888); border:1px solid #333; }
    .rmbz-artist-data-card__desc { color: var(--rmbz-text-secondary, #ccc); font-size: 14px; line-height: 1.6; margin: 0 0 16px; }
    .rmbz-artist-data-cta {
        display: inline-block;
        background: var(--rmbz-brand, #f0b90b);
        color: #000;
        padding: 10px 20px;
        border-radius: 6px;
        text-decoration: none;
        font-weight: 700;
        font-size: 14px;
    }
    .rmbz-artist-data-cta:hover { background: var(--rmbz-brand-strong, #fcc524); }

    .rmbz-artist-data-dl {
        display: grid;
        grid-template-columns: 130px 1fr;
        gap: 8px 16px;
        margin: 0;
    }
    .rmbz-artist-data-dl dt { color: var(--rmbz-text-faint, #888); font-size: 13px; }
    .rmbz-artist-data-dl dd { color: var(--rmbz-text-primary, #fff); margin: 0; font-size: 14px; }

    @media (max-width: 600px) {
        .distro-artist-data { padding: 20px 15px; }
        .rmbz-artist-data-dl { grid-template-columns: 1fr; gap: 4px; }
        .rmbz-artist-data-dl dt { color: var(--rmbz-text-faint, #888); font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; margin-top: 8px; }
    }
    </style>
    <?php
}


/* ============================================================================
 * 18. CSS extra (formulário SOMAS — campo BI)
 * ============================================================================ */
add_action( 'wp_head', function() {
    if ( ! is_admin() ): ?>
    <style>
    .rmbz-somas-bi-help { color: var(--rmbz-text-muted, #aaa); font-size: 13px; line-height: 1.6; margin: 0 0 14px; }
    .rmbz-somas-bi-current {
        background: rgba(46,204,113,0.08);
        border: 1px solid rgba(46,204,113,0.3);
        padding: 12px 16px;
        border-radius: 6px;
        margin-bottom: 14px;
    }
    .rmbz-somas-bi-current__label { color: var(--rmbz-text-secondary, #ccc); font-size: 13px; margin-right: 8px; }
    .rmbz-somas-bi-current__link { color: var(--rmbz-success, #10b981); text-decoration: underline; font-size: 14px; font-weight: 600; }
    .rmbz-somas-bi-current__hint { color: var(--rmbz-text-faint, #888); font-size: 12px; margin: 8px 0 0; }
    .rmbz-somas-bi-input {
        background: var(--rmbz-bg-elevated, #0e0e0e) !important;
        border: 1px dashed #444 !important;
        color: var(--rmbz-text-secondary, #ccc) !important;
        padding: 14px !important;
        border-radius: 6px !important;
        width: 100%;
        box-sizing: border-box;
        cursor: pointer;
    }
    .rmbz-somas-bi-input::file-selector-button {
        background: var(--rmbz-brand, #f0b90b);
        color: #000;
        border: none;
        padding: 8px 16px;
        border-radius: 4px;
        font-weight: 700;
        margin-right: 12px;
        cursor: pointer;
    }
    .rmbz-somas-bi-input::file-selector-button:hover { background: var(--rmbz-brand-strong, #fcc524); }
    </style>
    <?php endif;
});
