<?php // phpcs:disable WordPress.Files.FileName.InvalidClassFileName

if ( ! class_exists( 'QM_Output_Html_DB_Queries' ) || ! class_exists( 'QM_Collectors' ) ) {
	return;
}

/**
 * Override Query Monitor's "QM_Output_Html_DB_Queries" to inject SQLite info.
 */
class SQLite_QM_Output_Html_DB_Queries extends QM_Output_Html_DB_Queries {
	/**
	 * Override the parent method to inject SQLite info.
	 *
	 * Currently, Query Monitor doesn't provide a way to customize the rendered
	 * query HTML. To overcome this limitation, we capture the HTML generated by
	 * the parent method and modify it to inject the SQLite query data.
	 *
	 * @param array<string, mixed> $row  The row data.
	 * @param array<int, string>   $cols The column names.
	 * @return void
	 */
	protected function output_query_row( array $row, array $cols ) {
		// Capture the query row HTML.
		ob_start();
		parent::output_query_row( $row, $cols );
		$data = ob_get_length() > 0 ? ob_get_clean() : '';

		// Get the corresponding SQLite queries.
		global $wpdb;
		static $query_index = 0;
		$sqlite_queries     = $wpdb->queries[ $query_index ]['sqlite_queries'] ?? array();
		$sqlite_query_count = count( $sqlite_queries );
		$query_index       += 1;

		// Build the SQLite info HTML.
		$sqlite_info  = sprintf(
			'<div class="qm-info" style="margin: 15px 0 8px;">Executed %d SQLite %s:</div>',
			$sqlite_query_count,
			1 === $sqlite_query_count ? 'Query' : 'Queries'
		);
		$sqlite_info .= '<ol>';
		foreach ( $sqlite_queries as $query ) {
			$sqlite_info .= '<li class="qm-sqlite-query" style="list-style: decimal !important; margin-left: 20px !important;">';
			$sqlite_info .= '<code>' . str_replace( '<br>', '', self::format_sql( $query['sql'] ) ) . '</code>';
			$sqlite_info .= '</li>';
		}
		$sqlite_info .= '</ol>';

		// Inject toggle button and SQLite info into the query row HTML.
		$toggle_button  = '<button class="qm-toggle sqlite-toggle" data-on="+" data-off="-" aria-expanded="false" aria-label="Toggle SQLite queries" title="Toggle SQLite queries"><span aria-hidden="true">+</span></button>';
		$toggle_content = sprintf( '<div class="qm-toggled" style="display: none;">%s</div>', $sqlite_info );

		$data = str_replace( 'qm-row-sql', 'qm-row-sql qm-has-toggle', $data );
		$data = preg_replace(
			'/(<td class="qm-row-sql.*?">)(.*?)(<\/td>)/s',
			implode(
				array(
					'$1',
					str_replace( '$', '\\$', $toggle_button ),
					'$2',
					str_replace( '$', '\\$', $toggle_content ),
					'$3',
				)
			),
			$data
		);
		echo $data;
	}
}

// Remove the default Query Monitor class and replace it with the custom one.
remove_filter( 'qm/outputter/html', 'register_qm_output_html_db_queries', 20 );

/**
 * Register the custom HTML output class.
 *
 * @param array<string, QM_Output> $output
 * @param QM_Collectors            $collectors
 * @return array<string, QM_Output>
 */
function register_sqlite_qm_output_html_db_queries( array $output, $collectors ) {
	$collector = QM_Collectors::get( 'db_queries' );
	if ( $collector ) {
		$output['db_queries'] = new SQLite_QM_Output_Html_DB_Queries( $collector );
	}
	return $output;
}

add_filter( 'qm/outputter/html', 'register_sqlite_qm_output_html_db_queries', 20, 2 );
