<?php
/**
 * 1MZ For Artists — API Origin Tracker
 *
 * Acrescenta tracking de origem (canal/IP/dispositivo) a todas as
 * chamadas da API REST.
 *
 * Como funciona:
 *   - rest_pre_dispatch: hook nativo do WordPress que dispara antes
 *     de qualquer endpoint REST executar
 *   - Intercepta apenas pedidos no namespace 1mz/v1
 *   - Captura metadados via rmbz_origin_capture()
 *   - Quando o pedido é autenticado (via rmbz_api_require_auth), também
 *     regista o dispositivo em rmbz_app_devices (auto-aprende dispositivos)
 *
 * O resultado fica acessível via:
 *   - $request->get_param('rmbz_origin')  — array com canal/IP/etc
 *
 * @package 1MZ_For_Artists
 * @since 1.6.1
 */

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

add_filter( 'rest_pre_dispatch', 'rmbz_api_capture_origin_for_rest', 10, 3 );

function rmbz_api_capture_origin_for_rest( $result, $server, $request ) {
    // Só interferir nos nossos endpoints
    $route = $request->get_route();
    if ( ! is_string( $route ) || strpos( $route, '/1mz/v1/' ) !== 0 ) {
        return $result;
    }

    // Capturar e injectar como parâmetro do request
    $origin = rmbz_origin_capture( 'api' );
    $request->set_param( 'rmbz_origin', $origin );

    return $result; // null deixa o WordPress continuar normalmente
}

/**
 * Hook chamado APÓS um login bem sucedido. Auto-regista dispositivo.
 *
 * O auth-controller dispara `do_action('rmbz_user_logged_in', $telemovel)`
 * — intercepta-mos isso para registar o dispositivo.
 */
add_action( 'rmbz_user_logged_in', 'rmbz_api_record_device_after_login', 10, 1 );

function rmbz_api_record_device_after_login( $telemovel ) {
    $origin = rmbz_origin_capture();

    if ( empty( $origin['device_id'] ) ) {
        return; // login do site web, sem device_id
    }

    // Tentar derivar um label útil do user_agent
    $label = rmbz_api_derive_device_label( $origin['user_agent'] );
    rmbz_origin_record_device( $telemovel, $origin, $label );
}

/**
 * Tenta criar um nome amigável a partir do user agent.
 * Ex: "Mozilla/5.0 (Linux; Android 13; SM-A525F)" → "Samsung SM-A525F (Android 13)"
 */
function rmbz_api_derive_device_label( $user_agent ) {
    if ( empty( $user_agent ) ) return null;

    // Padrão Android
    if ( preg_match( '/Android (\d+(?:\.\d+)?);[^)]*?\b([A-Z]{2,}[\w\-]+)/', $user_agent, $m ) ) {
        return "Android {$m[1]} ({$m[2]})";
    }
    // Padrão iOS
    if ( preg_match( '/iPhone OS (\d+_\d+)|iOS (\d+\.\d+)/', $user_agent, $m ) ) {
        $version = ! empty( $m[1] ) ? str_replace( '_', '.', $m[1] ) : $m[2];
        return "iPhone (iOS {$version})";
    }
    // App label simples (nossa app envia X-1MZ-Channel: app_android)
    return substr( $user_agent, 0, 60 );
}

/**
 * Tabela de "actividade" — regista cada chamada autenticada à API
 * com canal/IP/device. Usado para auditoria geral.
 *
 * NÃO regista o body (sensível) — só metadados.
 */
add_action( 'rest_api_init', 'rmbz_api_register_activity_table', 5 );

function rmbz_api_register_activity_table() {
    // Apenas garantir que a tabela existe (idempotente)
    rmbz_api_install_activity_table();
}

function rmbz_api_install_activity_table() {
    $current = get_option( 'rmbz_api_activity_schema', '0.0.0' );
    if ( $current === '1.0.0' ) return;

    global $wpdb;
    $charset_collate = $wpdb->get_charset_collate();
    require_once ABSPATH . 'wp-admin/includes/upgrade.php';

    $sql = "CREATE TABLE {$wpdb->prefix}rmbz_api_activity (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        user_telemovel varchar(20) DEFAULT NULL,
        endpoint varchar(120) NOT NULL,
        method varchar(10) NOT NULL,
        origin_channel varchar(20) DEFAULT NULL,
        origin_ip varchar(45) DEFAULT NULL,
        origin_device_id varchar(64) DEFAULT NULL,
        origin_app_version varchar(20) DEFAULT NULL,
        status_code smallint(6) DEFAULT NULL,
        created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY idx_user (user_telemovel),
        KEY idx_endpoint (endpoint),
        KEY idx_created (created_at)
    ) {$charset_collate};";

    dbDelta( $sql );
    update_option( 'rmbz_api_activity_schema', '1.0.0' );
}

/**
 * Hook que dispara DEPOIS do endpoint terminar, para registar a actividade.
 */
add_filter( 'rest_post_dispatch', 'rmbz_api_log_activity', 10, 3 );

function rmbz_api_log_activity( $response, $server, $request ) {
    $route = $request->get_route();
    if ( ! is_string( $route ) || strpos( $route, '/1mz/v1/' ) !== 0 ) {
        return $response;
    }

    // Não logar pedidos de health/check para evitar lixo
    if ( strpos( $route, '/health' ) !== false ) {
        return $response;
    }

    global $wpdb;
    $origin = $request->get_param( 'rmbz_origin' ) ?: rmbz_origin_capture( 'api' );
    $telemovel = $request->get_param( 'rmbz_telemovel' );

    // Truncar endpoint a 120 chars
    $endpoint = substr( $route, 0, 120 );

    $wpdb->insert(
        $wpdb->prefix . 'rmbz_api_activity',
        [
            'user_telemovel'     => $telemovel ?: null,
            'endpoint'           => $endpoint,
            'method'             => $request->get_method(),
            'origin_channel'     => $origin['channel'] ?? null,
            'origin_ip'          => $origin['ip'] ?? null,
            'origin_device_id'   => $origin['device_id'] ?? null,
            'origin_app_version' => $origin['app_version'] ?? null,
            'status_code'        => $response instanceof WP_REST_Response ? $response->get_status() : null,
            'created_at'         => current_time( 'mysql', 1 ),
        ],
        [ '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s' ]
    );

    // Manter tabela sob controlo — apagar registos com mais de 90 dias
    // (corre 1% das vezes, para não pesar)
    if ( mt_rand( 1, 100 ) === 1 ) {
        $wpdb->query(
            "DELETE FROM {$wpdb->prefix}rmbz_api_activity
             WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY)"
        );
    }

    return $response;
}
