<?php
/**
 * Télécommande de test API (diagnostics GBP + DataForSEO).
 * Déclenchée par URL : ?avi_run_api_test=<secret> (défaut : secret_run, surclassable via AVISION_API_DIAGNOSTICS_SECRET).
 *
 * -------------------------------------------------------------------------
 * DataForSEO — où configurer les clés (évite le message « No DataForSEO keys found »)
 * -------------------------------------------------------------------------
 * Le cœur AVI ne lit pas les clés DFS via get_option(). Résolution identique à
 * Avision_Database::fetch_dataforseo_maps_sector() et Avision_Scan_Engine::get_dataforseo_credentials() :
 *
 * 1) Filtre WordPress `avision_dataforseo_credentials` : retourner un tableau avec
 *    `login` et `password` (identifiants API DataForSEO, Basic Auth).
 *
 * 2) À défaut : constantes `AVISION_DATAFORSEO_LOGIN` et `AVISION_DATAFORSEO_PASSWORD`
 *    dans wp-config.php (ou avant le chargement du plugin).
 *
 * 3) Pont runtime : `avision_get_dataforseo_credentials_resolved()` lit aussi getenv()/$_ENV
 *    pour login : AVISION_DATAFORSEO_LOGIN, DATAFORSEO_LOGIN, DFS_LOGIN ; password :
 *    AVISION_DATAFORSEO_PASSWORD, DATAFORSEO_PASSWORD, DFS_PASSWORD, DATAFORSEO_PWD,
 *    DFS_PWD, DATAFORSEO_API_KEY, DFS_API_KEY (voir includes/avision-dataforseo-credentials.php).
 *
 * Sur ce dépôt, wp-config charge souvent la racine `/.env` puis fait des define()
 * à partir de getenv() pour AVISION_DATAFORSEO_* — remplir ces variables dans `.env`
 * ou définir les deux constantes explicitement dans wp-config.
 *
 * @package Avision
 */

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

/**
 * Secret attendu dans $_GET['avi_run_api_test'].
 *
 * @return string
 */
function avision_api_diagnostics_get_secret(): string {
	if ( defined( 'AVISION_API_DIAGNOSTICS_SECRET' ) && is_string( AVISION_API_DIAGNOSTICS_SECRET ) && AVISION_API_DIAGNOSTICS_SECRET !== '' ) {
		return AVISION_API_DIAGNOSTICS_SECRET;
	}
	$filtered = apply_filters( 'avision_api_diagnostics_secret', 'secret_run' );
	return is_string( $filtered ) && $filtered !== '' ? $filtered : 'secret_run';
}

/**
 * Accès autorisé : administrateur (manage_options) ou rôle / méta agence.
 *
 * @return bool
 */
function avision_api_diagnostics_user_can_run(): bool {
	if ( ! function_exists( 'is_user_logged_in' ) || ! is_user_logged_in() ) {
		return false;
	}
	if ( function_exists( 'current_user_can' ) && current_user_can( 'manage_options' ) ) {
		return true;
	}
	$user = wp_get_current_user();
	if ( ! $user || ! $user->exists() ) {
		return false;
	}
	$roles = (array) $user->roles;
	if ( in_array( 'avi_agency', $roles, true ) ) {
		return true;
	}
	if ( function_exists( 'avi_agency_user_is_master' ) && avi_agency_user_is_master( (int) $user->ID ) ) {
		return true;
	}
	return false;
}

/**
 * Résout la ligne profil pour l’utilisateur WP courant (session active, wp_user_id, ou user_id = WP id).
 *
 * @param int $wp_user_id ID WordPress.
 * @return array<string, mixed>|null
 */
function avision_api_diagnostics_resolve_profile_row( int $wp_user_id ): ?array {
	global $wpdb;
	if ( ! isset( $wpdb ) || ! $wpdb || $wp_user_id <= 0 ) {
		return null;
	}

	$table = $wpdb->prefix . 'avi_saas_profiles';
	if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) !== $table ) {
		return null;
	}

	// Forçage admin : ?avi_api_test_profile_id=123
	if ( function_exists( 'current_user_can' ) && current_user_can( 'manage_options' )
		&& isset( $_GET['avi_api_test_profile_id'] ) ) {
		$forced = absint( wp_unslash( $_GET['avi_api_test_profile_id'] ) );
		if ( $forced > 0 ) {
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table validée
			$row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM `{$table}` WHERE id = %d LIMIT 1", $forced ), ARRAY_A );
			return is_array( $row ) ? $row : null;
		}
	}

	$profile_id = 0;
	if ( function_exists( 'avi_get_active_profile' ) ) {
		$maybe = avi_get_active_profile();
		if ( is_numeric( $maybe ) && (int) $maybe > 0 ) {
			$profile_id = (int) $maybe;
		}
	}

	if ( $profile_id > 0 && function_exists( 'avi_current_user_can_access_profile' ) && ! avi_current_user_can_access_profile( $profile_id ) ) {
		$profile_id = 0;
	}

	if ( $profile_id > 0 ) {
		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM `{$table}` WHERE id = %d LIMIT 1", $profile_id ), ARRAY_A );
		if ( is_array( $row ) ) {
			return $row;
		}
	}

	$has_wp_uid_col = $wpdb->get_var( $wpdb->prepare( "SHOW COLUMNS FROM `{$table}` LIKE %s", 'wp_user_id' ) ) === 'wp_user_id';
	if ( $has_wp_uid_col ) {
		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$row = $wpdb->get_row(
			$wpdb->prepare(
				"SELECT * FROM `{$table}` WHERE wp_user_id = %d ORDER BY id DESC LIMIT 1",
				$wp_user_id
			),
			ARRAY_A
		);
		if ( is_array( $row ) ) {
			return $row;
		}
	}

	// Repli B2B / installs où user_id = ID WordPress
	// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
	$row = $wpdb->get_row(
		$wpdb->prepare(
			"SELECT * FROM `{$table}` WHERE user_id = %d ORDER BY id DESC LIMIT 1",
			$wp_user_id
		),
		ARRAY_A
	);

	return is_array( $row ) ? $row : null;
}

/**
 * location_name + code pour le stub keyword_suggestions (aligné pays DFS).
 *
 * @param array<string, mixed> $profile
 * @return array{0: string, 1: int, 2: string}
 */
function avision_api_diagnostics_dfs_location_context( array $profile ): array {
	$country = isset( $profile['country'] ) ? strtoupper( trim( (string) $profile['country'] ) ) : 'FR';
	if ( ! in_array( $country, array( 'FR', 'GB', 'US', 'ES' ), true ) ) {
		$country = 'FR';
	}
	$codes           = array( 'FR' => 2250, 'GB' => 2826, 'US' => 2840, 'ES' => 2724 );
	$location_code   = isset( $codes[ $country ] ) ? $codes[ $country ] : 2250;
	$lang            = ( $country === 'GB' || $country === 'US' ) ? 'en' : ( $country === 'ES' ? 'es' : 'fr' );
	$city            = isset( $profile['city'] ) ? trim( (string) $profile['city'] ) : '';
	$city_lower      = strtolower( $city );
	$defaults        = array( 'FR' => 'France', 'GB' => 'London,England,United Kingdom', 'US' => 'United States', 'ES' => 'Spain' );
	$location_name   = isset( $defaults[ $country ] ) ? $defaults[ $country ] : 'France';

	if ( $country === 'FR' ) {
		$location_name = $city !== '' ? ( $city . ',France' ) : 'France';
	} elseif ( $country === 'ES' ) {
		$location_name = $city !== '' ? ( $city . ',Spain' ) : 'Spain';
	} elseif ( $country === 'GB' ) {
		if ( $city_lower === 'london' || strpos( $city_lower, 'london' ) === 0 ) {
			$location_name = 'London,England,United Kingdom';
		} else {
			$location_name = $city !== '' ? $city : $location_name;
		}
	} elseif ( $country === 'US' ) {
		$location_name = $city !== '' ? $city : $location_name;
	}

	return array( $location_name, $location_code, $lang );
}

/**
 * Hook template_redirect : tir groupé diagnostics API.
 *
 * @return void
 */
function avision_api_diagnostics_template_redirect(): void {
	if ( ! isset( $_GET['avi_run_api_test'] ) ) {
		return;
	}

	$got = isset( $_GET['avi_run_api_test'] ) ? sanitize_text_field( wp_unslash( $_GET['avi_run_api_test'] ) ) : '';
	if ( $got === '' || ! hash_equals( avision_api_diagnostics_get_secret(), $got ) ) {
		return;
	}

	if ( ! avision_api_diagnostics_user_can_run() ) {
		wp_die( esc_html__( 'Accès refusé', 'avision-dashboard' ), esc_html__( 'API Diagnostics', 'avision-dashboard' ), array( 'response' => 403 ) );
	}

	$wp_user_id = function_exists( 'get_current_user_id' ) ? (int) get_current_user_id() : 0;
	if ( $wp_user_id <= 0 ) {
		wp_die( esc_html__( 'Accès refusé', 'avision-dashboard' ), esc_html__( 'API Diagnostics', 'avision-dashboard' ), array( 'response' => 403 ) );
	}

	$profile_row = avision_api_diagnostics_resolve_profile_row( $wp_user_id );
	if ( ! is_array( $profile_row ) || empty( $profile_row['id'] ) ) {
		wp_send_json_error(
			array(
				'message' => 'Aucun profil SaaS résolu pour cet utilisateur (session / wp_user_id / user_id).',
				'wp_user_id' => $wp_user_id,
			),
			400
		);
	}

	$profile_id   = (int) $profile_row['id'];
	$access_token = isset( $profile_row['google_access_token'] ) ? trim( (string) $profile_row['google_access_token'] ) : '';
	$location_id  = isset( $profile_row['google_location_name'] ) ? trim( (string) $profile_row['google_location_name'] ) : '';

	if ( $access_token === '' || $location_id === '' ) {
		wp_send_json_error(
			array(
				'message'    => 'Jeton Google ou google_location_name manquant sur le profil : impossible de lancer le tir GBP (connecter la fiche ou compléter la ligne SQL).',
				'profile_id' => $profile_id,
				'token_present' => $access_token !== '',
				'location_present' => $location_id !== '',
			),
			400
		);
	}

	$business_name = isset( $profile_row['business_name'] ) ? trim( (string) $profile_row['business_name'] ) : '';
	$category      = isset( $profile_row['category'] ) ? trim( (string) $profile_row['category'] ) : '';
	$city          = isset( $profile_row['city'] ) ? trim( (string) $profile_row['city'] ) : '';
	$country       = isset( $profile_row['country'] ) ? strtoupper( trim( (string) $profile_row['country'] ) ) : 'FR';
	if ( ! in_array( $country, array( 'FR', 'GB', 'US', 'ES' ), true ) ) {
		$country = 'FR';
	}

	$sector_keyword = trim( $category . ' ' . $city );
	if ( $sector_keyword === '' ) {
		$sector_keyword = $category !== '' ? $category : 'service local';
	}

	list( $loc_name_kw, $loc_code_kw, $lang_kw ) = avision_api_diagnostics_dfs_location_context( $profile_row );
	$seed_kw = trim( $category . ' ' . $city );
	if ( $seed_kw === '' ) {
		$seed_kw = $category !== '' ? $category : 'marketing';
	}

	$debug_results = array(
		'meta' => array(
			'wp_user_id'   => $wp_user_id,
			'profile_id'   => $profile_id,
			'location_id'  => $location_id,
			'token_prefix' => strlen( $access_token ) > 12 ? ( substr( $access_token, 0, 8 ) . '…' ) : '(court)',
		),
		'gbp_local_reputation'            => null,
		'gbp_five_performance_stub'       => null,
		'dfs_competitors_leaders'         => null,
		'dfs_keyword_suggestions_stub'    => null,
		'dfs_growth_radar_rows'           => null,
	);

	if ( function_exists( 'avision_gbp_fetch_local_reputation' ) ) {
		$debug_results['gbp_local_reputation'] = avision_gbp_fetch_local_reputation( $access_token, $location_id, $profile_id );
	}

	if ( function_exists( 'avision_gbp_stub_fetch_five_performance_metrics' ) ) {
		$debug_results['gbp_five_performance_stub'] = avision_gbp_stub_fetch_five_performance_metrics( $access_token, $location_id, $profile_id );
	}

	if ( function_exists( 'avision_dfs_kpi_fetch_competitors_leaders' ) && $sector_keyword !== '' && $city !== '' ) {
		$debug_results['dfs_competitors_leaders'] = avision_dfs_kpi_fetch_competitors_leaders(
			$profile_id,
			$sector_keyword,
			$city,
			$country,
			$business_name,
			3
		);
	} else {
		$debug_results['dfs_competitors_leaders'] = array( 'skipped' => true, 'reason' => 'sector_keyword ou city vide' );
	}

	if ( function_exists( 'avision_dfs_kpi_stub_your_search_keyword_suggestions' ) ) {
		$debug_results['dfs_keyword_suggestions_stub'] = avision_dfs_kpi_stub_your_search_keyword_suggestions(
			$seed_kw,
			$loc_name_kw,
			$loc_code_kw,
			$lang_kw,
			$profile_id
		);
	}

	if ( function_exists( 'avision_dfs_kpi_fetch_growth_radar_rows' ) ) {
		$debug_results['dfs_growth_radar_rows'] = avision_dfs_kpi_fetch_growth_radar_rows( $profile_id, 100 );
	}

	nocache_headers();
	wp_send_json_success( $debug_results );
}

if ( function_exists( 'add_action' ) ) {
	add_action( 'template_redirect', 'avision_api_diagnostics_template_redirect', 99 );
}
