<?php
/**
 * Logging functionality for the plugin.
 * 
 * @package WPStaticHTMLPages
 */

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

class WPSH_Logger {

	/**
	 * Log levels
	 */
	const LEVEL_INFO = 'info';
	const LEVEL_SUCCESS = 'success';
	const LEVEL_WARNING = 'warning';
	const LEVEL_ERROR = 'error';
	const LEVEL_DEBUG = 'debug';
	const LEVEL_DELETED = 'deleted';

	/**
	 * Add a log entry
	 *
	 * @param string $level Log level
	 * @param string $message Log message
	 * @param array $context Additional context data
	 * @return bool
	 */
	public static function log( $level, $message, $context = array() ) {
		if ( ! self::should_log() ) {
			return false;
		}

		$logs = get_option( 'wpsh_logs', array() );
		
		// Add debug information
		// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
		$debug_backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 );
		$caller = isset( $debug_backtrace[1] ) ? $debug_backtrace[1] : array();
		
		$entry = array(
			'timestamp'   => current_time( 'mysql' ),
			'level'       => $level,
			'message'     => $message,
			'context'     => $context,
			'user_id'     => get_current_user_id(),
			'ip_address'  => self::get_user_ip(),
			'memory_usage'=> memory_get_usage( true ),
			'time_elapsed'=> microtime( true ),
			'function'    => isset( $caller['function'] ) ? $caller['function'] : 'unknown',
			'line'        => isset( $caller['line'] ) ? $caller['line'] : 'unknown',
			'file'        => isset( $caller['file'] ) ? basename( $caller['file'] ) : 'unknown'
		);

		array_unshift( $logs, $entry );
		
		// Keep only last 1000 entries to prevent database bloat
		$logs = array_slice( $logs, 0, 1000 );
		
		return update_option( 'wpsh_logs', $logs );
	}

	/**
	 * Log info message
	 *
	 * @param string $message Log message
	 * @param array $context Additional context data
	 */
	public static function info( $message, $context = array() ) {
		self::log( self::LEVEL_INFO, $message, $context );
	}

	/**
	 * Log success message
	 *
	 * @param string $message Log message
	 * @param array $context Additional context data
	 */
	public static function success( $message, $context = array() ) {
		self::log( self::LEVEL_SUCCESS, $message, $context );
	}

	/**
	 * Log warning message
	 *
	 * @param string $message Log message
	 * @param array $context Additional context data
	 */
	public static function warning( $message, $context = array() ) {
		self::log( self::LEVEL_WARNING, $message, $context );
	}

	/**
	 * Log error message
	 *
	 * @param string $message Log message
	 * @param array $context Additional context data
	 */
	public static function error( $message, $context = array() ) {
		self::log( self::LEVEL_ERROR, $message, $context );
	}

	/**
	 * Log debug message
	 *
	 * @param string $message Log message
	 * @param array $context Additional context data
	 */
	public static function debug( $message, $context = array() ) {
		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			self::log( self::LEVEL_DEBUG, $message, $context );
		}
	}

	/**
	 * Log file deletion message
	 *
	 * @param string $message Log message
	 * @param array $context Additional context data
	 */
	public static function deleted( $message, $context = array() ) {
		self::log( self::LEVEL_DELETED, $message, $context );
	}

	/**
	 * Get all logs with optional filtering
	 *
	 * @param array $args Filter arguments
	 * @return array
	 */
	public static function get_logs( $args = array() ) {
		$defaults = array(
			'level'     => '',
			'search'    => '',
			'date_from' => '',
			'date_to'   => '',
			'limit'     => 100,
			'offset'    => 0
		);

		$args = wp_parse_args( $args, $defaults );
		$logs = get_option( 'wpsh_logs', array() );
		$filtered_logs = array();

		foreach ( $logs as $log ) {
			$include = true;

			// Filter by level
			if ( ! empty( $args['level'] ) && $log['level'] !== $args['level'] ) {
				$include = false;
			}

			// Filter by search term
			if ( ! empty( $args['search'] ) ) {
				$search_term = strtolower( $args['search'] );
				$message = strtolower( $log['message'] );
				$context_str = strtolower( json_encode( $log['context'] ) );
				
				if ( strpos( $message, $search_term ) === false && strpos( $context_str, $search_term ) === false ) {
					$include = false;
				}
			}

			// Filter by date range
			if ( ! empty( $args['date_from'] ) && strtotime( $log['timestamp'] ) < strtotime( $args['date_from'] ) ) {
				$include = false;
			}

			if ( ! empty( $args['date_to'] ) && strtotime( $log['timestamp'] ) > strtotime( $args['date_to'] . ' 23:59:59' ) ) {
				$include = false;
			}

			if ( $include ) {
				$filtered_logs[] = $log;
			}
		}

		// Apply pagination
		$total = count( $filtered_logs );
		$logs_page = array_slice( $filtered_logs, $args['offset'], $args['limit'] );

		return array(
			'logs'  => $logs_page,
			'total' => $total
		);
	}

	/**
	 * Clear all logs
	 *
	 * @return bool
	 */
	public static function clear_logs() {
		return update_option( 'wpsh_logs', array() );
	}

	/**
	 * Export logs to CSV
	 *
	 * @param array $args Filter arguments
	 * @return string CSV content
	 */
	public static function export_logs( $args = array() ) {
		$result = self::get_logs( array_merge( $args, array( 'limit' => 10000 ) ) );
		$logs = $result['logs'];

		$csv = "Timestamp,Level,Message,User,IP Address,Memory Usage,Context\n";

		foreach ( $logs as $log ) {
			$user = $log['user_id'] ? get_userdata( $log['user_id'] )->user_login : 'System';
			$context = ! empty( $log['context'] ) ? json_encode( $log['context'] ) : '';
			
			$csv .= sprintf(
				'"%s","%s","%s","%s","%s","%s","%s"',
				$log['timestamp'],
				$log['level'],
				str_replace( '"', '""', $log['message'] ),
				$user,
				$log['ip_address'],
				size_format( $log['memory_usage'] ),
				str_replace( '"', '""', $context )
			);
			$csv .= "\n";
		}

		return $csv;
	}

	/**
	 * Determine whether logs should be recorded.
	 *
	 * @return bool
	 */
	private static function should_log() {
		if ( function_exists( 'wp_doing_cron' ) ) {
			return wp_doing_cron();
		}

		return defined( 'DOING_CRON' ) && DOING_CRON;
	}

	/**
	 * Get log statistics
	 *
	 * @return array
	 */
	public static function get_stats() {
		$logs = get_option( 'wpsh_logs', array() );
		$stats = array(
			'total'      => count( $logs ),
			'info'       => 0,
			'success'    => 0,
			'warning'    => 0,
			'error'      => 0,
			'debug'      => 0,
			'deleted'    => 0,
			'last_24h'   => 0,
			'last_7d'    => 0
		);

		$now = time();
		$last_24h = $now - ( 24 * 60 * 60 );
		$last_7d = $now - ( 7 * 24 * 60 * 60 );

		foreach ( $logs as $log ) {
			$stats[ $log['level'] ]++;
			
			$timestamp = strtotime( $log['timestamp'] );
			if ( $timestamp > $last_24h ) {
				$stats['last_24h']++;
			}
			if ( $timestamp > $last_7d ) {
				$stats['last_7d']++;
			}
		}

		return $stats;
	}

	/**
	 * Get user IP address
	 *
	 * @return string
	 */
	private static function get_user_ip() {
		if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
			return sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) );
		} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
			return sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) );
		} elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) {
			return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
		}
		return 'unknown';
	}

	/**
	 * Format log level for display
	 *
	 * @param string $level Log level
	 * @return string Formatted level with icon
	 */
	public static function format_level( $level ) {
		switch ( $level ) {
			case self::LEVEL_SUCCESS:
				return '<span class="wpsh-log-level wpsh-log-success"><span class="dashicons dashicons-yes-alt"></span> Success</span>';
			case self::LEVEL_ERROR:
				return '<span class="wpsh-log-level wpsh-log-error"><span class="dashicons dashicons-no-alt"></span> Error</span>';
			case self::LEVEL_WARNING:
				return '<span class="wpsh-log-level wpsh-log-warning"><span class="dashicons dashicons-warning"></span> Warning</span>';
			case self::LEVEL_DEBUG:
				return '<span class="wpsh-log-level wpsh-log-debug"><span class="dashicons dashicons-code-standards"></span> Debug</span>';
			case self::LEVEL_DELETED:
				return '<span class="wpsh-log-level wpsh-log-deleted"><span class="dashicons dashicons-trash"></span> Deleted</span>';
			default:
				return '<span class="wpsh-log-level wpsh-log-info"><span class="dashicons dashicons-info"></span> Info</span>';
		}
	}
}
