<?php

namespace core;

// Prevent direct access to the file
if (!defined('ABSPATH')) {
    exit;
}


/**
 * Convert a string representation of a currency value to a float.
 *
 * @param string $value The currency value as a string, e.g., "$1,234.56".
 * @return float The numeric value as a float.
 */
function to_float($value)
{
    // Remove dollar sign and any other non-numeric characters (except decimal)
    $cleaned = preg_replace('/[^\d.-]/', '', $value);
    return floatval($cleaned); // Convert to float
}
;


/**
 * Format a currency amount for display.
 *
 * @param float|string $amount The amount to format, can be a float or a string.
 * @return string The formatted currency string.
 */
function format_currency($amount): string
{

    // check if $amount is string
    if (is_string($amount)) {
        $amount = to_float($amount);
    }

    if (empty($amount) || $amount == 0) {
        return '-';
    } else if ($amount < 0) {
        return '($' . number_format(abs($amount), 2) . ')'; // Wrap in parentheses
    } else {
        return '$' . number_format($amount, 2);
    }
}


/****************************************************************************************************************
 * Lightweight Logger for LucidPen / EnigTech projects.
 *
 * Usage:
 *   use core\Logger;
 *   Logger::info('Plugin activated');
 *   Logger::debug(['request' => $_POST]);
 *
 ***************************************************************************************************************/
class Logger
{
    protected const ENABLED = false;
    protected const PREFIX = 'DefaultPrefix';

    // ---------------------------------------------------------------------
    // Public logging methods
    // ---------------------------------------------------------------------

    public static function info($message): void
    {
        self::write('INFO', $message);
    }

    public static function warning($message): void
    {
        self::write('WARNING', $message);
    }

    public static function error($message): void
    {
        self::write('ERROR', $message);
    }

    public static function debug($message): void
    {
        self::write('DEBUG', $message);
    }

    // ---------------------------------------------------------------------
    // Internal write method
    // ---------------------------------------------------------------------

    private static function write(string $level, $message): void
    {
        // Check if logging is enabled
        if (!static::ENABLED) {
            return;
        }

        // Respect WP_DEBUG setting
        if (!defined('WP_DEBUG') || !WP_DEBUG) {
            return;
        }

        // Normalize message
        if (is_array($message) || is_object($message)) {
            $message = print_r($message, true);
        }

        $timestamp = date('Y-m-d H:i:s');
        $prefix = static::PREFIX;

        error_log(sprintf('[%s] [%s] [%s] %s', $prefix, $timestamp, $level, $message));
    }
}



/**************************************************************************************************************
 *
 * SingletonTrait
 *
 * Trait to implement the Singleton design pattern.
 *
 * This trait ensures that a class can only have one instance and provides a global point of access to it.
 * It prevents external instantiation, cloning, and unserialization.
 *
 **************************************************************************************************************/
trait SingletonTrait
{
    private static $instances = [];

    public static function get_instance()
    {
        $cls = static::class; // Get the name of the called class
        if (!isset(self::$instances[$cls])) {
            self::$instances[$cls] = new static();
        }
        return self::$instances[$cls];
    }

    // Prevent external instantiation, cloning, and unserialization
    private function __construct()
    {
    }
    private function __clone()
    {
    }
}

/***************************************************************************************************************
 * Interface PluginEventListener
 *
 * This interface defines methods that should be implemented by any class that wants to listen to plugin events.
 * It includes methods for handling plugin load, activation, and deactivation events.
 **************************************************************************************************************/
interface PluginEventListener
{
    public function on_plugin_load(): void;
    public function on_plugin_activate(): void;
    public function on_plugin_deactivate(): void;
}


/**************************************************************************************************************
 *
 * Result Class
 *
 * Represents the result of an operation, typically used for AJAX responses.
 *
 **************************************************************************************************************/

class Result
{
    public bool $success;
    public string $message;
    public mixed $value;
    public array $extra;

    public function __construct(bool $success = true, string $message = '', mixed $value = null, array $extra = [])
    {
        $this->success = $success;
        $this->message = $message;
        $this->value = $value;
        $this->extra = $extra;
    }

    public function toArray(): array
    {
        return [
            'success' => $this->success,
            'message' => $this->message,
            'value' => $this->value,
            'extra' => $this->extra,
        ];
    }

    public static function true(): self
    {
        static $instance = null;
        if ($instance === null) {
            $instance = new self(true, 'Success');
        }
        return $instance;
    }

    public static function success(string $message = 'Success', mixed $value = null, array $extra = []): self
    {
        return new self(true, $message, $value, $extra);
    }

    public static function failure(string $message = 'Failure', mixed $value = null, array $extra = []): self
    {
        return new self(false, $message, $value, $extra);
    }
}

