<?php
/**
 * 1MZ For Artists — Royalties (USD) Endpoints
 *
 * Adiciona endpoints para a app gerir o saldo USD em royalties e
 * convertê-lo para MT na carteira:
 *
 *   GET  /wallet/royalties           — saldo USD + taxa actual + equivalente MT
 *   POST /wallet/royalties/transfer  — converte USD→MT (atómico)
 *
 * Reutiliza 100% da lógica existente:
 *   - rmbz_secure_transfer_usd_to_mt() — função atómica em
 *     distribution-financial.php
 *   - rmbz_get_exchange_rate() — taxa actual em admin-settings.php
 *
 * FLUXO IGUAL AO SITE:
 *   Para levantar de royalties, a app primeiro CONVERTE USD→MT (este
 *   endpoint), depois usa o endpoint normal de criar withdrawal a partir
 *   da carteira. São 2 passos separados — exactamente como o site faz.
 *
 * Não toca nos controllers existentes — só regista 2 rotas novas.
 *
 * @package 1MZ_For_Artists
 * @since 1.6.18
 */

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

if ( ! defined( 'RMBZ_API_ROYALTIES_VERSION' ) ) {
    define( 'RMBZ_API_ROYALTIES_VERSION', '1.6.24.1' );
}

add_action( 'rest_api_init', 'rmbz_api_register_royalties_routes' );

function rmbz_api_register_royalties_routes() {
    register_rest_route( RMBZ_API_NAMESPACE, '/wallet/royalties', [
        'methods'             => 'GET',
        'callback'            => 'rmbz_api_handle_get_royalties',
        'permission_callback' => 'rmbz_api_require_auth',
    ] );

    register_rest_route( RMBZ_API_NAMESPACE, '/wallet/royalties/transfer', [
        'methods'             => 'POST',
        'callback'            => 'rmbz_api_handle_transfer_royalties',
        'permission_callback' => 'rmbz_api_require_auth',
        'args' => [
            'amount_usd' => [
                'required' => true,
                'type'     => 'number',
            ],
        ],
    ] );
}


/* ============================================================================
 * HELPERS
 * ============================================================================ */

/**
 * Lê o saldo USD em royalties (rmbz_distro_stats.total_earnings).
 * Devolve 0.0 se não houver linha (artista ainda não distribuiu).
 */
function rmbz_api_get_royalties_balance_usd( $telemovel ) {
    global $wpdb;
    $table_stats = $wpdb->prefix . 'rmbz_distro_stats';

    if ( $wpdb->get_var( "SHOW TABLES LIKE '$table_stats'" ) !== $table_stats ) {
        return 0.0;
    }

    $row = $wpdb->get_row( $wpdb->prepare(
        "SELECT total_earnings, last_updated FROM $table_stats WHERE artist_telemovel = %s",
        $telemovel
    ) );

    return $row ? (float) $row->total_earnings : 0.0;
}

/**
 * Lê o timestamp da última actualização de royalties.
 */
function rmbz_api_get_royalties_last_updated( $telemovel ) {
    global $wpdb;
    $table_stats = $wpdb->prefix . 'rmbz_distro_stats';

    if ( $wpdb->get_var( "SHOW TABLES LIKE '$table_stats'" ) !== $table_stats ) {
        return null;
    }

    $row = $wpdb->get_row( $wpdb->prepare(
        "SELECT last_updated FROM $table_stats WHERE artist_telemovel = %s",
        $telemovel
    ) );

    return $row && $row->last_updated ? mysql_to_rfc3339( $row->last_updated ) : null;
}


/* ============================================================================
 * GET /wallet/royalties
 * ============================================================================ */
function rmbz_api_handle_get_royalties( WP_REST_Request $request ) {
    $tel = (string) $request->get_param( 'rmbz_telemovel' );

    $balance_usd = rmbz_api_get_royalties_balance_usd( $tel );
    $rate        = function_exists( 'rmbz_get_exchange_rate' )
        ? (float) rmbz_get_exchange_rate()
        : 63.50;
    $equivalent_mt = round( $balance_usd * $rate, 2 );

    return rmbz_api_ok( [
        '_api_version'    => RMBZ_API_ROYALTIES_VERSION,
        'balance_usd'     => round( $balance_usd, 4 ),
        'exchange_rate'   => round( $rate, 4 ),
        'equivalent_mt'   => $equivalent_mt,
        'currency_usd'    => 'USD',
        'currency_mt'     => 'MZN',
        'last_updated'    => rmbz_api_get_royalties_last_updated( $tel ),
    ] );
}


/* ============================================================================
 * POST /wallet/royalties/transfer
 *
 * Body: { "amount_usd": 12.50 }
 *
 * Chama rmbz_secure_transfer_usd_to_mt() — função atómica que:
 *   - Debita USD em rmbz_distro_stats
 *   - Regista no ledger USD (rmbz_distro_ledger)
 *   - Credita MT em rmbz_wallets (à taxa actual)
 *   - Regista no histórico MT (rmbz_wallet_transactions)
 *   - Tudo numa transação SQL — ou tudo OK ou ROLLBACK
 *
 * Não exige PIN — é uma operação interna entre saldos do mesmo utilizador.
 * (A withdrawal subsequente, se aplicável, é que pede PIN.)
 * ============================================================================ */
function rmbz_api_handle_transfer_royalties( WP_REST_Request $request ) {
    $tel        = (string) $request->get_param( 'rmbz_telemovel' );
    $amount_usd = (float) $request->get_param( 'amount_usd' );

    if ( $amount_usd <= 0 ) {
        return rmbz_api_error( 'Valor inválido. Insere um valor positivo em USD.', 400, 'invalid_amount' );
    }

    if ( ! function_exists( 'rmbz_secure_transfer_usd_to_mt' ) ) {
        // Garantir que o módulo está carregado (defensivo)
        $financial = defined( 'RMBZ_PLUGIN_PATH' )
            ? RMBZ_PLUGIN_PATH . 'includes/distribution/distribution-financial.php'
            : null;
        if ( $financial && file_exists( $financial ) ) {
            require_once $financial;
        }
    }

    if ( ! function_exists( 'rmbz_secure_transfer_usd_to_mt' ) ) {
        return rmbz_api_error(
            'Sistema indisponível: módulo financeiro não carregado.',
            500,
            'financial_module_missing'
        );
    }

    // Capturar valores antes da operação para devolver no payload
    $rate_before        = function_exists( 'rmbz_get_exchange_rate' )
        ? (float) rmbz_get_exchange_rate()
        : 63.50;
    $balance_usd_before = rmbz_api_get_royalties_balance_usd( $tel );

    // Executar conversão atómica
    $result = rmbz_secure_transfer_usd_to_mt( $tel, $amount_usd );

    if ( empty( $result['success'] ) ) {
        // Mensagens da função interna são em português e úteis
        $msg = isset( $result['message'] ) ? (string) $result['message'] : 'Falha na conversão.';
        return rmbz_api_error( $msg, 400, 'transfer_failed' );
    }

    // [1.6.24] Carimbar a origem (channel/IP/device/UA/app_version) nas
    // 2 linhas que a função canónica criou (ledger USD + wallet_transactions
    // MT). Isto permite ao Guarda-Costas cruzar canais entre conversão e
    // levantamento subsequente, detectando contas comprometidas.
    // Falha silenciosa: se o módulo não estiver carregado ou o schema
    // ainda não tiver corrido, a conversão segue (já correu com sucesso).
    $stamp_result = null;
    if ( function_exists( 'rmbz_stamp_conversion_origin' ) ) {
        $stamp_result = rmbz_stamp_conversion_origin( $tel );
    }

    $amount_mt          = round( $amount_usd * $rate_before, 2 );
    $balance_usd_after  = round( $balance_usd_before - $amount_usd, 4 );

    // Saldo MT actualizado da carteira
    global $wpdb;
    $balance_mt_after = (float) $wpdb->get_var( $wpdb->prepare(
        "SELECT balance FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel = %s",
        $tel
    ) );

    return rmbz_api_ok( [
        '_api_version'           => RMBZ_API_ROYALTIES_VERSION,
        'success'                => true,
        'message'                => $result['message'],
        'amount_usd_converted'   => round( $amount_usd, 4 ),
        'amount_mt_credited'     => $amount_mt,
        'exchange_rate_used'     => round( $rate_before, 4 ),
        'royalties_balance_usd'  => $balance_usd_after,
        'wallet_balance_mt'      => round( $balance_mt_after, 2 ),
        // [1.6.24] Indicador de auditoria — útil em debug. Não muda UX.
        'origin_stamped'         => $stamp_result['updated'] ?? false,
    ], 200 );
}
