<?php
/**
 * Logger — file-based + DB audit logger.
 */

declare(strict_types=1);

class Logger
{
    public static function log(string $level, string $message, array $context = []): void
    {
        $line = sprintf(
            "[%s] [%s] %s%s\n",
            date('Y-m-d H:i:s'),
            strtoupper($level),
            $message,
            $context ? ' ' . json_encode($context, JSON_UNESCAPED_SLASHES) : ''
        );
        $file = LOGS_PATH . '/app-' . date('Y-m-d') . '.log';
        @file_put_contents($file, $line, FILE_APPEND | LOCK_EX);
    }

    public static function info(string $message, array $context = []): void
    {
        self::log('info', $message, $context);
    }

    public static function warning(string $message, array $context = []): void
    {
        self::log('warning', $message, $context);
    }

    public static function error(string $message, array $context = []): void
    {
        self::log('error', $message, $context);
    }

    /**
     * Persist an audit-log row.
     * Used for: login, signup, payment, profile update, etc.
     */
    public static function audit(
        ?int $publisher_id,
        string $action,
        ?string $entity_type = null,
        ?int $entity_id = null,
        ?array $meta = null
    ): void {
        try {
            $stmt = db()->prepare("
                INSERT INTO publisher_audit_log
                  (publisher_id, action, entity_type, entity_id, ip_address, user_agent, meta)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            ");
            $stmt->execute([
                $publisher_id,
                $action,
                $entity_type,
                $entity_id,
                self::clientIp(),
                substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255),
                $meta ? json_encode($meta, JSON_UNESCAPED_SLASHES) : null,
            ]);
        } catch (Throwable $e) {
            self::error('Audit log write failed', ['error' => $e->getMessage()]);
        }
    }

    public static function clientIp(): string
    {
        foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'] as $h) {
            if (!empty($_SERVER[$h])) {
                $ip = trim(explode(',', (string)$_SERVER[$h])[0]);
                if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
            }
        }
        return '0.0.0.0';
    }
}
