<?php

namespace PloverCRM\Common;

/**
 * Base Log Viewer
 * 
 * Base class for all module log viewers with common functionality
 */
abstract class BaseLogViewer
{
    /**
     * @var string Log directory path
     */
    protected $logDir;

    /**
     * @var string Log file prefix
     */
    protected $logFilePrefix;

    /**
     * Constructor
     * 
     * @param string $moduleName Module name for log directory
     * @param string $logFilePrefix Log file prefix
     */
    public function __construct(string $moduleName, string $logFilePrefix)
    {
        $upload_dir = wp_upload_dir();
        $this->logDir = $upload_dir['basedir'] . '/plover-crm-logs/' . $moduleName;
        $this->logFilePrefix = $logFilePrefix;
    }

    /**
     * Get recent logs (last 7 days)
     * 
     * @return array
     */
    public function getRecentLogs(): array
    {
        if (!is_dir($this->logDir)) {
            return [];
        }

        $logs = [];
        $files = glob($this->logDir . '/*.log');

        if (empty($files)) {
            return [];
        }

        // Sort files by filename (which contains date) - newest first
        usort($files, function ($a, $b) {
            return strcmp(basename($b), basename($a));
        });

        $sevenDaysAgo = strtotime('-7 days');

        foreach ($files as $file) {
            if (filemtime($file) < $sevenDaysAgo) {
                continue;
            }

            $content = file_get_contents($file);
            $lines = explode("\n", trim($content));

            $tasks = [];
            foreach ($lines as $line) {
                if (empty($line)) {
                    continue;
                }

                // Parse JSON format from Monolog JsonFormatter
                $logEntry = json_decode($line, true);

                if (!$logEntry || !is_array($logEntry)) {
                    continue;
                }

                // Extract data from JSON
                $datetime = $logEntry['datetime'] ?? '';
                $time = date('H:i:s', strtotime($datetime));
                $level = $logEntry['level_name'] ?? 'INFO';
                $message = $logEntry['message'] ?? '';

                // Get task_id from extra
                $taskId = $logEntry['extra']['task_id'] ?? 'unknown';

                // Get context data (excluding task_id)
                $context = $logEntry['context'] ?? [];

                if (!isset($tasks[$taskId])) {
                    $tasks[$taskId] = [];
                }

                $tasks[$taskId][] = [
                    'time' => $time,
                    'level' => $level,
                    'message' => $message,
                    'context' => $context,
                ];
            }

            // Reverse tasks array so latest task shows first
            $tasks = array_reverse($tasks, true);

            $logs[] = [
                'filename' => basename($file),
                'date' => date('F j, Y', filemtime($file)),
                'tasks' => $tasks,
            ];
        }

        return $logs;
    }

    /**
     * Download all logs as ZIP
     * 
     * @return void
     */
    public function downloadLogsAsZip(): void
    {
        if (!is_dir($this->logDir)) {
            wp_die('No logs directory found');
        }

        $files = glob($this->logDir . '/*.log');

        if (empty($files)) {
            wp_die('No log files found');
        }

        $zipFile = tempnam(sys_get_temp_dir(), $this->logFilePrefix . '-logs-') . '.zip';
        $zip = new \ZipArchive();

        if ($zip->open($zipFile, \ZipArchive::CREATE) !== true) {
            wp_die('Failed to create ZIP file');
        }

        foreach ($files as $file) {
            $zip->addFile($file, basename($file));
        }

        $zip->close();

        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; filename="' . $this->logFilePrefix . '-logs-' . date('Y-m-d-His') . '.zip"');
        header('Content-Length: ' . filesize($zipFile));

        readfile($zipFile);
        unlink($zipFile);
        exit;
    }

    /**
     * Register centralized download handler
     * 
     * @param string $moduleName Module name for the action hook
     * @return void
     */
    public static function registerDownloadHandler(string $moduleName): void
    {
        add_action('wp_ajax_plover_crm_download_logs', [__CLASS__, 'handleDownloadRequest']);
    }

    /**
     * Handle centralized download request
     * 
     * @return void
     */
    public static function handleDownloadRequest(): void
    {
        if (!current_user_can('manage_options')) {
            wp_die('Unauthorized');
        }

        if (!isset($_GET['nonce']) || !wp_verify_nonce($_GET['nonce'], 'plover_crm_download_logs')) {
            wp_die('Invalid nonce');
        }

        $module = isset($_GET['module']) ? sanitize_text_field($_GET['module']) : '';

        if (empty($module)) {
            wp_die('Module not specified');
        }

        // Map module names to their LogViewer classes
        $moduleMap = [
            'push-notifications' => '\PloverCRM\Modules\PushNotifications\Helpers\LogViewer',
            'plover-crm' => '\PloverCRM\Modules\NativeCRM\Helpers\LogViewer',
            'fluent-crm' => '\PloverCRM\Modules\FluentCRM\Helpers\LogViewer',
            'api' => '\PloverCRM\Core\Api\Helpers\LogViewer',
            'system' => '\PloverCRM\Core\Helpers\LogViewer',
            'data-sources/forms' => '\PloverCRM\Modules\Integrations\Helpers\FormsLogViewer',
            'data-sources/ads' => '\PloverCRM\Modules\Integrations\Helpers\AdsLogViewer',
            'data-sources/webhooks' => '\PloverCRM\Modules\Integrations\Helpers\WebhooksLogViewer',
            'integrations-automations' => '\PloverCRM\Modules\Integrations\Helpers\AutomationsLogViewer',
        ];

        if (!isset($moduleMap[$module])) {
            wp_die('Invalid module');
        }

        $logViewerClass = $moduleMap[$module];
        $logViewer = new $logViewerClass();
        $logViewer->downloadLogsAsZip();
    }

    /**
     * Get download button HTML
     * 
     * @param string $moduleName Module name
     * @return string
     */
    public static function getDownloadButton(string $moduleName): string
    {
        $nonce = wp_create_nonce('plover_crm_download_logs');
        $url = admin_url('admin-ajax.php?action=plover_crm_download_logs&module=' . urlencode($moduleName) . '&nonce=' . $nonce);

        return '<a href="' . esc_url($url) . '" class="button button-primary">Download All Logs (ZIP)</a>';
    }

    /**
     * Render log entries with context data
     * 
     * @param array $logs Array of log data
     * @return void
     */
    protected function renderLogEntries(array $logs): void
    {
        if (empty($logs)) {
            echo '<p>No logs found.</p>';
            return;
        }

        echo '<div style="background: #f5f5f5; padding: 15px; border-radius: 4px; max-height: 400px; overflow-y: auto;">';

        foreach ($logs as $log) {
            echo '<div style="margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #ddd;">';
            echo '<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">';
            echo '<strong>' . esc_html($log['filename']) . '</strong>';
            echo '<span style="color: #666; font-size: 12px;">' . esc_html($log['date']) . '</span>';
            echo '</div>';

            if (!empty($log['tasks'])) {
                foreach ($log['tasks'] as $taskId => $entries) {
                    echo '<div style="margin-left: 15px; margin-bottom: 10px;">';
                    echo '<div style="font-weight: 600; color: #28a745; margin-bottom: 5px;">Task ID: ' . esc_html($taskId) . '</div>';

                    foreach ($entries as $entry) {
                        echo '<div style="margin-left: 15px; padding: 8px 0; font-family: monospace; font-size: 12px; border-bottom: 1px solid #eee;">';
                        echo '<div style="margin-bottom: 5px;">';
                        echo '<span style="color: #666;">[' . esc_html($entry['time']) . ']</span> ';
                        $color = $entry['level'] === 'ERROR' ? '#d63638' : '#2271b1';
                        echo '<span style="color: ' . $color . '; font-weight: 600;">' . esc_html($entry['level']) . '</span> ';
                        echo esc_html($entry['message']);
                        echo '</div>';

                        // Display all context data dynamically
                        if (!empty($entry['context'])) {
                            echo '<div style="margin-left: 20px; font-size: 11px; color: #555;">';
                            foreach ($entry['context'] as $key => $value) {
                                $label = ucwords(str_replace('_', ' ', $key));
                                $isError = ($key === 'error');
                                $style = $isError ? 'color: #d63638;' : '';

                                if (is_scalar($value)) {
                                    // Check if value is a JSON string
                                    $decodedJson = null;
                                    if (is_string($value) && strlen($value) > 0) {
                                        $trimmed = trim($value);
                                        if (strlen($trimmed) > 0 && ($trimmed[0] === '{' || $trimmed[0] === '[')) {
                                            $decodedJson = json_decode($trimmed, true);
                                            if (json_last_error() !== JSON_ERROR_NONE) {
                                                $decodedJson = null;
                                            }
                                        }
                                    }

                                    if ($decodedJson !== null && is_array($decodedJson)) {
                                        echo '<div style="' . $style . ' margin-bottom: 8px;">';
                                        echo '<strong>' . esc_html($label) . ':</strong>';
                                        echo '<pre style="white-space: pre-wrap; background: #fff; padding: 8px; border: 1px solid #ddd; border-radius: 3px; margin: 5px 0; overflow-x: auto; font-size: 10px;">';
                                        echo esc_html(json_encode($decodedJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
                                        echo '</pre>';
                                        echo '</div>';
                                    } else {
                                        echo '<div style="' . $style . '">';
                                        echo '<strong>' . esc_html($label) . ':</strong> ';
                                        echo esc_html($value);
                                        echo '</div>';
                                    }
                                } elseif (is_array($value)) {
                                    echo '<div style="margin-bottom: 8px;">';
                                    echo '<strong>' . esc_html($label) . ':</strong>';
                                    echo '<pre style="white-space: pre-wrap; background: #fff; padding: 8px; border: 1px solid #ddd; border-radius: 3px; margin: 5px 0; overflow-x: auto; font-size: 10px;">';
                                    echo esc_html(json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
                                    echo '</pre>';
                                    echo '</div>';
                                }
                            }
                            echo '</div>';
                        }

                        echo '</div>';
                    }
                    echo '</div>';
                }
            }
            echo '</div>';
        }

        echo '</div>';
    }
}
