<?php
/**
 * Logger Class
 *
 * @package    MOMCS_Sync
 * @subpackage MOMCS_Sync/includes/common/utils
 * @author     miniOrange
 * @license    Expat
 * @link       https://miniorange.com
 */

declare( strict_types=1 );

namespace MOMCS_Sync\Includes\Common\Utils;

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

/**
 * Class Logger
 *
 * Handles logging functionality for the plugin
 */
class Logger {

	/**
	 * Log context/identifier
	 *
	 * @var string
	 */
	private $context;

	/**
	 * Log file path
	 *
	 * @var string
	 */
	private $log_file;

	/**
	 * Debug mode
	 *
	 * @var bool
	 */
	private $debug_mode;

	/**
	 * Upload directory
	 *
	 * @var array
	 */
	private $upload_dir;

	/**
	 * Constructor
	 *
	 * @param string $context Context identifier for the log.
	 */
	public function __construct( string $context ) {
		$this->context    = sanitize_file_name( $context );
		$this->upload_dir = wp_upload_dir();
		$this->log_file   = $this->upload_dir['basedir'] . '/multi-channel-for-woocommerce' . DIRECTORY_SEPARATOR . $this->context . '-' . gmdate( 'Y-m-d' ) . '.log';
		$this->init_log_directory();
	}

	/**
	 * Initialize log directory
	 */
	private function init_log_directory() {
		$log_dir = $this->upload_dir['basedir'] . '/multi-channel-for-woocommerce';
		global $wp_filesystem;
		// Adding required file for using WP_Filesystem() fuction which we will require to log functionality specific errors generated by the plugin.
		if ( ! $wp_filesystem ) {
			require_once ABSPATH . 'wp-admin' . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'file.php';
			WP_Filesystem();
		}

		if ( ! $wp_filesystem->exists( $log_dir ) ) {
			$wp_filesystem->mkdir( $log_dir );
			// Create an index.html file in the logs directory to prevent directory browsing.
			$wp_filesystem->put_contents( $log_dir . '/index.html', '' );
		}

		// Make sure the directory is writable.
		if ( ! $wp_filesystem->is_writable( $log_dir ) ) {
			// Try to set permissions.
			$wp_filesystem->chmod( $log_dir, 0755 );
		}
	}

	/**
	 * Log a debug message
	 *
	 * @param string $message The message to log.
	 * @param array  $data    Optional data to log.
	 */
	public function debug( string $message, array $data = array() ) {
		$this->log( 'DEBUG', $message, $data );
	}

	/**
	 * Log an info message
	 *
	 * @param string $message The message to log.
	 * @param array  $data    Optional data to log.
	 */
	public function info( string $message, array $data = array() ) {
		$this->log( 'INFO', $message, $data );
	}

	/**
	 * Log a warning message
	 *
	 * @param string $message The message to log.
	 * @param array  $data    Optional data to log.
	 */
	public function warning( string $message, array $data = array() ) {
		$this->log( 'WARNING', $message, $data );
	}

	/**
	 * Log an error message
	 *
	 * @param string $message The message to log.
	 * @param array  $data    Optional data to log.
	 */
	public function error( string $message, array $data = array() ) {
		$this->log( 'ERROR', $message, $data );
	}

	/**
	 * Log a message
	 *
	 * @param string $level   Log level.
	 * @param string $message The message to log.
	 * @param array  $data    Optional data to log.
	 */
	private function log( string $level, string $message, array $data = array() ) {

		$timestamp = current_time( 'mysql' );
		$log_entry = "[{$timestamp}] [{$level}] [{$this->context}] {$message}";

		if ( ! empty( $data ) ) {
			$data_string = wp_json_encode( $data, JSON_PRETTY_PRINT );
			$log_entry  .= " Data: {$data_string}";
		}

		$log_entry .= PHP_EOL;

		// Write to log file.
		error_log( $log_entry, 3, $this->log_file ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Required to log data for debugging.
	}
}
