<?php

namespace EstatebudConnect\Core;

if (!defined('WPINC')) {
    die();
}

use EstatebudConnect\Configs\App;
use EstatebudConnect\Utilities\Helper;
use EstatebudConnect\Models\Settings;

class Log
{
    public static function write($message, $context = [])
    {
        global $wp_filesystem;

        $settings_data = Settings::instance()->get_data();
        $log_setting = $settings_data['log_level'];

        if ($log_setting !== 'debug') {
            return false;
        }

        if (empty($wp_filesystem)) {
            require_once ABSPATH . '/wp-admin/includes/file.php';
            WP_Filesystem();
        }

        $base_path = wp_upload_dir()['basedir'] . '/' . App::SLUG;
        $logs_path = $base_path . '/logs';
        $index_file = $logs_path . '/index.php';
        $htaccess_file = $logs_path . '/.htaccess';
        $log_name = gmdate('Y-m-d') . '.log';
        $log_file = $logs_path . '/' . $log_name;

        $ip = Helper::get_user_ip();
        $request_time = sanitize_text_field(wp_unslash($_SERVER['REQUEST_TIME'] ?? ''));
        $remote_port = sanitize_text_field(wp_unslash($_SERVER['REMOTE_PORT'] ?? ''));

        $request_id = sprintf('%08x', abs(crc32($ip . $request_time . $remote_port)));
        $datetime = gmdate('Y-m-d H:i:s e');

        $log_line = "[$datetime::$request_id] $message";

        if (!empty($context)) {
            $log_line .= ' (' . json_encode($context, JSON_UNESCAPED_SLASHES) . ')';
        }

        if (!$wp_filesystem->exists($base_path)) {
            $wp_filesystem->mkdir($base_path);
        }

        if (!$wp_filesystem->exists($logs_path)) {
            $wp_filesystem->mkdir($logs_path);
        }

        if (!$wp_filesystem->exists($index_file)) {
            if (!$wp_filesystem->put_contents($index_file, '')) {
                error_log("Could not create logs index file: $index_file");
            }
        }

        if (!$wp_filesystem->exists($htaccess_file)) {
            if (!$wp_filesystem->put_contents($htaccess_file,
                '<FilesMatch "\.(log)$">' . PHP_EOL .
                    '   Require all denied' . PHP_EOL .
                '</FilesMatch>'
            )) {
                error_log("Could not create logs htaccess file: $htaccess_file");
            }
        }

        $existing_content = '';
        if ($wp_filesystem->exists($log_file)) {
            $existing_content = $wp_filesystem->get_contents($log_file);
            if ($existing_content === false) {
                $existing_content = '';
            }
        }
        
        $content = $existing_content . $log_line . PHP_EOL;
        if (!$wp_filesystem->put_contents($log_file, $content, 0600)) {
            error_log("Could not write to custom log: $log_file");
        }
    }

    public static function event($message = '', $context = [])
    {
        $url = sanitize_text_field(wp_unslash($_SERVER['HTTP_REFERER'] ?? 'UNKNOWN'));
        $method = sanitize_text_field(wp_unslash($_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN'));
        $https = sanitize_text_field(wp_unslash($_SERVER['HTTPS'] ?? 'UNKNOWN'));
        $server_port = sanitize_text_field(wp_unslash($_SERVER['SERVER_PORT'] ?? 80));

        $isHttps = (!empty($https) && $https !== 'off') || $server_port == 443;
        $protocol = $isHttps ? 'HTTPS' : 'HTTP';

        $nonce = sanitize_text_field(wp_unslash($_POST['nonce'] ?? $_GET['nonce'] ?? null));

        if (is_null($nonce)) {
            $context['nonce_warning'] = "Nonce not supplied";
        } else if(!wp_verify_nonce($nonce, 'estatebud-nonce')) {
            $context['nonce_warning'] = "Nonce verification failed";
        }

        $payload = [
            'context' => [
                $context,
            ],
            'request' => [
                'get' => $_GET,
                'post' => $_POST,
            ],
        ];

        $parsed = wp_parse_url($url);
        $path = $parsed['path'] ?? '';
        $segments = array_values(array_filter(explode('/', $path)));
        $endpoint = implode('/', $segments);

        $message .= " {$protocol}/{$method}: /{$endpoint}";

        self::write($message, $payload);
    }
}
