<?php
/**
 * Tools / Status page for NewsSync.
 *
 * @package NewsSync
 */

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

/* --------------------------------------------------------------------- */
/* Helper functions for enhanced Tools page                              */
/* --------------------------------------------------------------------- */

/**
 * Get table statistics (row count, size, indexes).
 *
 * @return array|null Table stats or null if table doesn't exist.
 */
if ( ! function_exists( 'newssync_get_table_stats' ) ) {
	function newssync_get_table_stats() {
		global $wpdb;

		if ( ! function_exists( 'newssync_table_exists' ) || ! newssync_table_exists() ) {
			return null;
		}

		$table = newssync_get_item_map_table_name();
		$stats = array(
			'rows'          => 0,
			'size_mb'       => 0,
			'index_size_mb' => 0,
			'created_at'    => '',
			'indexes'       => array(),
		);

		// Row count - table name is safely generated by newssync_get_item_map_table_name()
		// @phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		// @phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter
		$stats['rows'] = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$table}`" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		// @phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		// @phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter

		// Table size and index size.
		$size_query = $wpdb->prepare(
			"SELECT
				ROUND(((data_length + index_length) / 1024 / 1024), 2) AS size_mb,
				ROUND((index_length / 1024 / 1024), 2) AS index_size_mb,
				create_time
			FROM information_schema. TABLES
			WHERE table_schema = %s
			AND table_name = %s",
			DB_NAME,
			$table
		);

		// Suppress errors in case information_schema is restricted.
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Query is prepared above, reading table metadata from information_schema for admin tools
		$size_data = $wpdb->get_row( $size_query );
		if ( $size_data ) {
			$stats['size_mb']       = (float) $size_data->size_mb;
			$stats['index_size_mb'] = (float) $size_data->index_size_mb;
			$stats['created_at']    = isset( $size_data->create_time ) ? $size_data->create_time : '';
		}

		// List indexes - table name is safely generated by newssync_get_item_map_table_name()
		// @phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		// @phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter
		$indexes = $wpdb->get_results( "SHOW INDEX FROM `{$table}`" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		// @phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		// @phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter
		if ( $indexes ) {
			foreach ( $indexes as $idx ) {
				if ( !  isset( $stats['indexes'][ $idx->Key_name ] ) ) {
					$stats['indexes'][ $idx->Key_name ] = array(
						'columns' => array(),
						'unique'  => 0 === (int) $idx->Non_unique,
					);
				}
				$stats['indexes'][ $idx->Key_name ]['columns'][] = $idx->Column_name;
			}
		}

		return $stats;
	}
}

/**
 * Get postmeta count for comparison.
 *
 * @return int Number of postmeta records.
 */
if ( !  function_exists( 'newssync_get_postmeta_count' ) ) {
	function newssync_get_postmeta_count() {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Admin tools, counting postmeta entries for statistics
		$count = (int) $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = %s",
				'_newssync_guid'
			)
		);

		return $count;
	}
}

/**
 * Clear all NewsSync caches (transients + object cache).
 *
 * @return array Cleared stats.
 */
if ( !  function_exists( 'newssync_clear_all_caches' ) ) {
	function newssync_clear_all_caches() {
		global $wpdb;

		$cleared = array(
			'transients'   => 0,
			'object_cache' => 0,
		);

		// Clear transients.
		$patterns = array(
			'_transient_newssync_%',
			'_transient_timeout_newssync_%',
		);

		foreach ( $patterns as $pattern ) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Admin tools, cache cleanup operation
			$options = $wpdb->get_col(
				$wpdb->prepare(
					"SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s",
					$pattern
				)
			);

			if ( ! empty( $options ) ) {
				foreach ( $options as $option ) {
					delete_option( $option );
					$cleared['transients']++;
				}
			}
		}

		// Clear object cache (group 'newssync').
		if ( function_exists( 'wp_cache_flush_group' ) ) {
			wp_cache_flush_group( 'newssync' );
			$cleared['object_cache'] = 1;
		}

		// Clear specific known cache keys.
		$cache_keys = array(
			'newssync_table_exists_check',
		);

		foreach ( $cache_keys as $key ) {
			wp_cache_delete( $key, 'newssync' );
		}

		// Clear WordPress SimplePie feed cache for DaazSync-registered feeds.
		// fetch_feed() stores its own transients as '_transient_feed_{md5(url)}'
		// which DaazSync's own cache wipe does not touch — this causes stale/
		// corrupted data to persist even after the feed URL starts returning 404.
		$ns_feeds = (array) get_option( 'newssync_feeds', [] );
		foreach ( $ns_feeds as $ns_feed ) {
			if ( ! empty( $ns_feed['url'] ) ) {
				$sp_key = 'feed_' . md5( $ns_feed['url'] );
				delete_transient( $sp_key );
				$cleared['transients']++;
			}
		}

		return $cleared;
	}
}

/* --------------------------------------------------------------------- */
/* AJAX handler for clearing cache                                       */
/* --------------------------------------------------------------------- */
if ( !  function_exists( 'newssync_clear_cache_ajax' ) ) {
	add_action( 'wp_ajax_newssync_clear_cache', 'newssync_clear_cache_ajax' );
	/**
	 * AJAX handler to clear cache.
	 */
	function newssync_clear_cache_ajax() {
		if ( !  current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'daazsync' ) ), 403 );
		}

		check_admin_referer( 'newssync_admin_tools', '_wpnonce' );

		$cleared = newssync_clear_all_caches();

		wp_send_json_success(
			array(
				'message' => sprintf(
					/* translators: %d: number of cleared transients */
					__( 'Cache cleared successfully!  Removed %d transients. ', 'daazsync' ),
					$cleared['transients']
				),
				'stats'   => $cleared,
			)
		);
	}
}

/* --------------------------------------------------------------------- */
/* AJAX handler for clearing error log                                   */
/* --------------------------------------------------------------------- */
if ( ! function_exists( 'newssync_clear_error_ajax' ) ) {
	add_action( 'wp_ajax_newssync_clear_error', 'newssync_clear_error_ajax' );
	/**
	 * AJAX handler to clear error log.
	 */
	function newssync_clear_error_ajax() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'daazsync' ) ), 403 );
		}

		check_admin_referer( 'newssync_admin_tools', '_wpnonce' );

		delete_option( 'newssync_last_table_error' );

		wp_send_json_success(
			array(
				'message' => __( 'Error log cleared successfully!', 'daazsync' ),
			)
		);
	}
}

/* --------------------------------------------------------------------- */
/* Helper:  Attempt to create the optimized table                         */
/* --------------------------------------------------------------------- */
if ( ! function_exists( 'newssync_attempt_create_table' ) ) {
	/**
	 * Attempt to create optimized table.
	 *
	 * @return array Result array with success, error, created keys.
	 */
	function newssync_attempt_create_table() {
		global $wpdb;

		$result = array(
			'success' => false,
			'error'   => '',
			'created' => false,
		);

		// Ensure the helper exists.
		if ( ! function_exists( 'newssync_create_item_map_table' ) ) {
			$result['error'] = 'missing_function_newssync_create_item_map_table';
			update_option( 'newssync_last_table_error', $result['error'], false );
			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Debug logging only when WP_DEBUG is enabled
				error_log( '[newssync] attempt_create_table: missing function newssync_create_item_map_table' );
			}
			return $result;
		}

		try {
			// Reset last_error before attempt.
			$wpdb->flush();

			// Call the create helper.
			$create_result = newssync_create_item_map_table();

			if ( is_array( $create_result ) && isset( $create_result['success'] ) ) {
				$result = $create_result;
			} else {
				$created           = (bool) $create_result;
				$result['success'] = $created;
				$result['created'] = $created;
			}

			// If created is false, capture error.
			if ( ! $result['success'] ) {
				$db_err = !  empty( $wpdb->last_error ) ? $wpdb->last_error : '';
				if ( '' !== $db_err ) {
					$result['error'] = $db_err;
				} else {
					$result['error'] = 'unknown_error_creating_table';
				}
			} else {
				// Clear last error option on success.
				delete_option( 'newssync_last_table_error' );
				return $result;
			}
		} catch ( Throwable $t ) {
			$result['error'] = $t->getMessage();
		} catch ( Exception $e ) {
			$result['error'] = $e->getMessage();
		}

		// Persist error for display in Tools page.
		if ( !  empty( $result['error'] ) ) {
			$save_err = substr( sanitize_text_field( $result['error'] ), 0, 2000 );
			update_option( 'newssync_last_table_error', $save_err, false );

			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Debug logging only when WP_DEBUG is enabled
				error_log( '[newssync] attempt_create_table error: ' . $result['error'] );
			}
		}

		return $result;
	}
}

/* --------------------------------------------------------------------- */
/* Admin POST handler to create table                                    */
/* --------------------------------------------------------------------- */
if ( ! function_exists( 'newssync_admin_post_create_table' ) ) {
	add_action( 'admin_post_newssync_create_table', 'newssync_admin_post_create_table' );
	/**
	 * Admin POST handler to create table.
	 */
	function newssync_admin_post_create_table() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Insufficient permissions', 'daazsync' ) );
		}

		// Verify nonce.
		if ( !  isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'newssync_create_table' ) ) {
			wp_die( esc_html__( 'Invalid request. ', 'daazsync' ) );
		}

		$referer = wp_get_referer();
		if ( ! $referer ) {
			$referer = admin_url();
		}

		$res = newssync_attempt_create_table();

		if ( $res['success'] ) {
			wp_safe_redirect( add_query_arg( 'newssync_create_table', 'success', $referer ) );
		} else {
			wp_safe_redirect( add_query_arg( 'newssync_create_table', 'error_create_failed', $referer ) );
		}
		exit;
	}
}

/* --------------------------------------------------------------------- */
/* AJAX endpoint to create table                                         */
/* --------------------------------------------------------------------- */
if ( !  function_exists( 'newssync_try_create_table' ) ) {
	add_action( 'wp_ajax_newssync_try_create_table', 'newssync_try_create_table' );
	/**
	 * AJAX handler to create table.
	 */
	function newssync_try_create_table() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'daazsync' ) ), 403 );
		}

		check_admin_referer( 'newssync_admin_tools', '_wpnonce' );

		$res = newssync_attempt_create_table();

		if ( $res['success'] ) {
			wp_send_json_success( array( 'message' => __( 'Optimized table created successfully. ', 'daazsync' ) ) );
		}

		$last_error = get_option( 'newssync_last_table_error', '' );
		if ( '' === $last_error && !  empty( $res['error'] ) ) {
			$last_error = $res['error'];
		}

		wp_send_json_error(
			array(
				'message' => __( 'Failed to create table. See Tools -> NewsSync Status for details.', 'daazsync' ),
				'detail'  => $last_error,
			),
			500
		);
	}
}

/* --------------------------------------------------------------------- */
/* Dismiss notice handler                                                */
/* --------------------------------------------------------------------- */
if ( ! function_exists( 'newssync_dismiss_table_notice_handler' ) ) {
	add_action( 'admin_post_newssync_dismiss_table_notice', 'newssync_dismiss_table_notice_handler' );
	/**
	 * Handler to dismiss table notice.
	 */
	function newssync_dismiss_table_notice_handler() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Access denied', 'daazsync' ) );
		}

		// Verify nonce.
		if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'newssync_dismiss_table_notice' ) ) {
			wp_die( esc_html__( 'Invalid request', 'daazsync' ) );
		}

		update_user_meta( get_current_user_id(), 'newssync_dismiss_table_notice', 1 );

		$referer = wp_get_referer();
		if ( ! $referer ) {
			$referer = admin_url();
		}

		wp_safe_redirect( $referer );
		exit;
	}
}

/**
 * AJAX handler to dismiss table notice.
 */
if ( ! function_exists( 'newssync_dismiss_table_notice_ajax_handler' ) ) {
	add_action( 'wp_ajax_newssync_dismiss_table_notice', 'newssync_dismiss_table_notice_ajax_handler' );
	function newssync_dismiss_table_notice_ajax_handler() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Access denied', 'daazsync' ) ) );
		}

		// Verify nonce.
		if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'newssync_dismiss_table_notice' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Invalid request', 'daazsync' ) ) );
		}

		update_user_meta( get_current_user_id(), 'newssync_dismiss_table_notice', 1 );

		wp_send_json_success( array( 'message' => esc_html__( 'Notice dismissed successfully', 'daazsync' ) ) );
	}
}

/**
 * Simple Markdown -> HTML renderer.
 *
 * @param string $md Markdown content.
 * @return string HTML output.
 */
if ( ! function_exists( 'newssync_render_markdown_simple' ) ) {
	function newssync_render_markdown_simple( $md ) {
		// Normalize line endings.
		$md = str_replace( array( "\r\n", "\r" ), "\n", $md );

		// Extract code blocks.
		$code_blocks = array();
		$md          = preg_replace_callback(
			'/```(.*?)\n(.*?)```/s',
			function ( $m ) use ( &$code_blocks ) {
				$key  = '%%CODEBLOCK_' . count( $code_blocks ) . '%%';
				$lang = trim( $m[1] );
				$code = htmlspecialchars( $m[2], ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8' );
				$code_blocks[ $key ] = '<pre class="newssync-code"><code' . ( $lang ? ' class="language-' . esc_attr( $lang ) . '"' : '' ) . '>' . $code . '</code></pre>';
				return $key;
			},
			$md
		);

		// Headings.
		$md = preg_replace( '/^###\s*(.+)$/m', '<h3>$1</h3>', $md );
		$md = preg_replace( '/^##\s*(.+)$/m', '<h2>$1</h2>', $md );
		$md = preg_replace( '/^#\s*(. +)$/m', '<h1>$1</h1>', $md );

		// Lists.
		$md = preg_replace_callback(
			'/(^|\n)([ \t]*(-|\*)\s+. +(\n[ \t]*(-|\*)\s+.+)*)/m',
			function ( $m ) {
				$items = preg_split( '/\n/', trim( $m[2] ) );
				$out   = "<ul>\n";
				foreach ( $items as $it ) {
					$it   = preg_replace( '/^([ \t]*(-|\*)\s+)/', '', $it );
					$out .= '<li>' . esc_html( trim( $it ) ) . "</li>\n";
				}
				$out .= "</ul>\n";
				return "\n" . $out;
			},
			$md
		);

		// Inline code.
		$md = preg_replace( '/`([^`]+)`/', '<code class="newssync-inline-code">$1</code>', $md );

		// Links.
		$md = preg_replace_callback(
			'/\[(.*?)\]\((.*?)\)/',
			function ( $m ) {
				$text = esc_html( $m[1] );
				$url  = esc_url( $m[2] );
				return '<a href="' . $url . '" target="_blank" rel="noopener noreferrer">' . $text . '</a>';
			},
			$md
		);

		// Paragraphs.
		$parts = preg_split( "/\n{2,}/", trim( $md ) );
		foreach ( $parts as &$p ) {
			if ( preg_match( '/^\s*<(h[1-6]|ul|pre|blockquote|table|div)/', $p ) ) {
				continue;
			}
			$p = '<p>' . nl2br( esc_html( trim( $p ) ) ) . '</p>';
		}
		$html = implode( "\n\n", $parts );

		// Restore code blocks.
		if ( !  empty( $code_blocks ) ) {
			foreach ( $code_blocks as $key => $newssync_html_block ) {
				$html = str_replace( $key, $newssync_html_block, $html );
			}
		}

		return '<div class="newssync-docs">' . $html . '</div>';
	}
}

/**
 * Enqueue admin scripts and styles for Tools page.
 */
if ( ! function_exists( 'newssync_enqueue_tools_assets' ) ) {
	add_action( 'admin_enqueue_scripts', 'newssync_enqueue_tools_assets' );
	/**
	 * Enqueue scripts for tools page.
	 *
	 * @param string $hook Current admin page hook.
	 */
	function newssync_enqueue_tools_assets( $hook ) {
		// Only load on DaazSync admin pages.
		if ( false === strpos( $hook, 'daazsync' ) ) {
			return;
		}

		$plugin_url = defined( 'NEWSSYNC_PLUGIN_URL' ) ? NEWSSYNC_PLUGIN_URL : plugin_dir_url( dirname( __DIR__, 2 ) . '/daazsync.php' );
		$plugin_dir = defined( 'NEWSSYNC_PLUGIN_DIR' ) ? NEWSSYNC_PLUGIN_DIR : plugin_dir_path( dirname( __DIR__, 2 ) . '/daazsync.php' );

		$js_path  = $plugin_dir . 'includes/assets/js/newssync-tools.js';
		$css_path = $plugin_dir . 'includes/assets/css/newssync-tools.css';
		$version  = file_exists( $js_path ) ? filemtime( $js_path ) : '1.0.0';

		// Enqueue JavaScript.
		wp_enqueue_script(
			'newssync-tools',
			$plugin_url . 'includes/assets/js/newssync-tools.js',
			array(),
			$version,
			true
		);

		// Localize script with nonce and i18n.
		wp_localize_script(
			'newssync-tools',
			'newssyncTools',
			array(
				'ajaxUrl'   => admin_url( 'admin-ajax.php' ),
				'nonce'     => wp_create_nonce( 'newssync_admin_tools' ),
				'i18n'      => array(
					'creatingTable'  => __( 'Creating table…', 'daazsync' ),
					'clearingCache'  => __( 'Clearing cache…', 'daazsync' ),
					'requestFailed'  => __( 'Request failed', 'daazsync' ),
					'confirmClear'   => __( 'Clear all NewsSync caches?', 'daazsync' ),
				),
			)
		);

		// Enqueue CSS.
		$css_version = file_exists( $css_path ) ? filemtime( $css_path ) : '1.0.0';
		wp_enqueue_style(
			'newssync-tools',
			$plugin_url . 'includes/assets/css/newssync-tools.css',
			array(),
			$css_version
		);
	}
}

/**
 * Render Tools / Status page.
 */
if ( ! function_exists( 'newssync_render_tools_status_page' ) ) {
	function newssync_render_tools_status_page() {
		// Force the tools section to be active via global variable
		global $newssync_force_section;
		$newssync_force_section = 'tools';

		// Call main page renderer
		if ( function_exists( 'newssync_render_settings_page' ) ) {
			newssync_render_settings_page();
		}
	}
}
