<?php

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}


interface IDiller_Loyalty_Logger {

	public function clear_log();

	public function info( $message, ...$args);

	public function error( $message, ...$args);
}


/**
 * Class responsible for creating logs. Logs reside by default under plugin_dir/logs
 * This class has no dependencies and should be used when Woocommerce is not installed/active.
 */
class Diller_Loyalty_Logger implements IDiller_Loyalty_Logger {

	private $header_log_str;
	private $log_file_name;

	public function __construct() {
		$this->header_log_str = "Diller Loyalty debug log file" . PHP_EOL;
		$this->log_file_name = 'logs' . DIRECTORY_SEPARATOR . '.diller_log_' .gmdate("d-m-Y") . '.log';

		// init log file
		if ( !file_exists( trailingslashit(DILLER_LOYALTY_PATH) . $this->log_file_name ) ) {
			file_put_contents( trailingslashit(DILLER_LOYALTY_PATH) . $this->log_file_name, $this->header_log_str );
		}
	}

	public function clear_log() {
		
	}

	private function log( $category = 'INFO', $message = '', $args = array()) {
		try {
			$overwrite = false;
			if ($overwrite) {
				if ( !empty( $this->log_file_name) && file_exists( trailingslashit(DILLER_LOYALTY_PATH) . $this->log_file_name ) ) {
					unlink( trailingslashit(DILLER_LOYALTY_PATH) . $this->log_file_name );
				}
				file_put_contents( trailingslashit(DILLER_LOYALTY_PATH) . $this->log_file_name, $this->reset_log_str );
			}

			$log_message = '[' . date( 'd-m-Y H:i:s' ) . '] [' . strtoupper($category) . '] ' . $this->format_message($message, $args);

			//Write to the log file
			return file_put_contents( trailingslashit(DILLER_LOYALTY_PATH) . $this->log_file_name, $log_message . PHP_EOL . PHP_EOL, (!$overwrite ? FILE_APPEND : 0) );
		}
		catch ( \Exception $e ) {
			return false;
		}
	}

	protected function format_message($message = "", $args = array()) {
		global $wp_version;

		$admin_user = DillerLoyalty()->is_admin_context() ? wp_get_current_user() : null;

		$log_message  = $message . PHP_EOL;
		$log_message .= sprintf("WP Version: %s | WC Version: %s | PHP Version: %s | Diller Version: %s ", $wp_version, Diller_Loyalty_Helpers::get_wc_version(), phpversion(), DILLER_LOYALTY_VERSION);
		$log_message .= is_multisite() ? PHP_EOL . "Multisite: true | URL: " . get_site_url(): "| Single site: true";

		// Check if a specific Follower instance was provided, otherwise default to current follower logged in
		$follower = current(array_filter($args, function($arg) { return is_a($arg, "Diller_Loyalty_Follower"); }));

		if($follower === false && $admin_user === null){
			$follower = DillerLoyalty()->get_current_follower();
		}

		// Log Follower details. Defaults to current follower
		if ($follower && $follower->get_wp_user_id() > 0 && !empty( $follower->get_full_phone_number() ) ) {
			$log_message .= PHP_EOL . 'Follower: ' . $follower->get_full_name() . ' | Phone: ' . $follower->get_full_phone_number() . ' | WP ID: ' . $follower->get_wp_user_id();
			if( $follower->get_wp_user_id() > 0 && ($user = get_userdata($follower->get_wp_user_id())) ){
				$log_message .= ' | Roles: ' . join(", ", array_values($user->roles));
			}
		}

		// If backoffice or API, log which admin user as performed the action we're logging
		if($admin_user) {
			$log_message .= PHP_EOL . 'Action performed';

			// Check if the current request was made via API.
			$log_message .= (defined('REST_REQUEST') && REST_REQUEST)
				? ' via REST API '
				: ' via Admin Dashboard ';

			$log_message .= 'by admin user: ' . $admin_user->display_name . ' (' . $admin_user->user_email . ') | Roles: ' . join(", ", array_values((array)$admin_user->roles));
		}

		foreach ( $args as $arg ) {
			switch ($arg){
				case is_a($arg, "Diller_Loyalty_Follower"):
					break;
				case is_a($arg, "WP_Error"):
					$log_message .= PHP_EOL . 'ERROR DETAILS: ' . PHP_EOL . print_r($arg, true);
					break;
				case is_a($arg, "WC_Order"):
					$log_message .= PHP_EOL . 'ORDER DETAILS: ' . PHP_EOL . print_r($arg, true);
					break;
				case is_array($arg):
					$log_message .= PHP_EOL . 'DATA: ' . print_r($arg, true);
					break;
				case is_string($arg):
					$log_message .= $arg;
					break;
				default:
					$log_message .= PHP_EOL . 'DATA: ' . var_export($arg, true);
					break;
			}
		}
		$log_message .= PHP_EOL . PHP_EOL;

		return $log_message;
	}

	/**
	 * Logs an info message to the log.
	 *
	 * @param $message  string The message to log
	 * @param mixed $args   Optional multiple argument list relevant for logging purposes
	 *
	 * @return false|int
	 */
	public function info( $message, ...$args) {
		return $this->log('INFO', $message, $args);
	}

	/**
	 * Logs an error to the error log.
	 *
	 * @param $message  The message to log
	 * @param mixed $args   Optional multiple argument list relevant for logging purposes
	 *
	 * @return false|int
	 */
	public function error( $message, ...$args) {
		return $this->log('ERROR', $message, $args);
	}

}

/**
 * Class responsible for creating logs using WC internal logging mechanism, by override parent's default behavior.
 * Logs will be available at https://store_url/wp-admin/admin.php?page=wc-status&tab=logs
 * This class has dependency on Woocommerce being installed/active.
 */
final class Diller_Loyalty_WC_Logger extends Diller_Loyalty_Logger{
	private $wc_logger;

	public function __construct() {
		if(!class_exists( 'woocommerce' )){
			_doing_it_wrong( 'Diller_Loyalty_WC_Logger::__construct', 'You can only Diller_Loyalty_WC_Logger if Woocommerce is installed. Use Diller_Loyalty_Logger class instead', DILLER_LOYALTY_VERSION);
		}

		$this->wc_logger = wc_get_logger();
	}

	/**
	 * Logs an info message to the log.
	 *
	 * @param string $message  The message to log
	 * @param mixed $args   Optional multiple argument list relevant for logging purposes
	 *
	 */
	public function info( $message, ...$args) {
		$message = $this->format_message($message, $args);
		$this->wc_logger->info( $message, array( 'source' => 'diller-loyalty-info' ) );
	}

	/**
	 * Logs an error to the error log.
	 *
	 * @param string $message  The message to log
	 * @param mixed $args   Optional multiple argument list relevant for logging purposes
	 *
	 */
	public function error( $message, ...$args) {
		$message = $this->format_message($message, $args);
		$this->wc_logger->error( $message, array( 'source' => 'diller-loyalty-error' ) );
	}
}
