<?php

namespace Easymailing\App\Core\Log;

use Easymailing\App\Repository\ConfigRepository;

class LogManager
{
	const HOOK = 'hook';
	const ACTION = 'action';
	const BATCH = 'batch';
	const FILTER = 'filter';
	const REQUEST = 'request';
	const ERROR = 'error';
	const MAX_LOGS = 1000;

	private $configRepository;

	public function __construct(ConfigRepository $configRepository)
	{
		$this->configRepository = $configRepository;
	}

	public function createRequestLog(
		string $type,
		?string $message,
		?string $url,
		?string $status,
		?string $body,
		?string $response
	): void
	{

		if(!$this->configRepository->getSynchronizationConfig()->isEnableLogs()){
			return;
		}

		global $wpdb;

		$message = $message ?? '';
		$url = $url ?? '';
		$status = $status ?? 'unknown';

		$wpdb->insert(
			LogDatabase::getTableName(),
			[
				'type'     => $type,
				'message'  => $message,
				'url'      => $url,
				'status'   => $status,
				'body'  => $body,
				'response'  => $response,
				'date'     => current_time('mysql'),
			],
			[
				'%s',
				'%s',
				'%s',
				'%s',
				'%s',
				'%s',
				'%s',
			]
		);

		$this->trimLogsIfNeeded();
	}

	public function createLog(string $type, string $message): void
	{
		if(!$this->configRepository->getSynchronizationConfig()->isEnableLogs()){
			return;
		}

		global $wpdb;

		// Obtén detalles del backtrace
		$trace = debug_backtrace();
		$action = !empty($trace[1]['function']) ? $trace[1]['function'] : '---';

		if (!empty($trace[1]['class'])) {
			$action = $trace[1]['class'] . '::' . $action;
		}

		$hook = '---';
		foreach ($trace as $item) {
			if ($item['function'] === 'do_action' && empty($item['class'])) {
				$hook = $item['args'][0] ?? 'unknown_hook';
				break;
			}
		}

		$extendedMessage = "$message <br> Hook: $hook <br> Action: $action ";

		$wpdb->insert(
			LogDatabase::getTableName(),
			[
				'type'    => $type,
				'message' => $extendedMessage,
				'date'    => current_time('mysql'),
			],
			[
				'%s',
				'%s',
				'%s',
			]
		);

		$this->trimLogsIfNeeded();
	}

	private function trimLogsIfNeeded(): void
	{
		global $wpdb;

		$tableName = LogDatabase::getTableName();
		$totalLogs = (int) $wpdb->get_var("SELECT COUNT(*) FROM {$tableName}");

		if ($totalLogs > self::MAX_LOGS) {
			$offset = self::MAX_LOGS;
			$wpdb->query("
            DELETE FROM {$tableName}
            ORDER BY date ASC
            LIMIT " . ($totalLogs - $offset)
			);
		}
	}


	public function getPaginatedLogs(int $limit, int $offset)
	{
		global $wpdb;

		$query = $wpdb->prepare(
			"SELECT * FROM " . LogDatabase::getTableName() . " ORDER BY id DESC LIMIT %d OFFSET %d",
			$limit,
			$offset
		);

		return $wpdb->get_results($query, ARRAY_A);
	}

	public function getTotalLogCount(): int
	{
		global $wpdb;

		$query = "SELECT COUNT(*) FROM " . LogDatabase::getTableName();
		return (int) $wpdb->get_var($query);
	}

	public function deleteAllLogs(): void
	{
		global $wpdb;

		$tableName = LogDatabase::getTableName();
		$wpdb->query("TRUNCATE TABLE {$tableName}"); // Borra todos los registros de manera eficiente
	}

	public function generateLogFile(): string
	{
		global $wpdb;

		// Obtener los logs
		$logs = $wpdb->get_results("SELECT * FROM " . LogDatabase::getTableName(), ARRAY_A);

		// Crear un directorio temporal
		$tempDir = sys_get_temp_dir(); // Directorio temporal del sistema
		$csvFilePath = $tempDir . '/logs_' . date('Y-m-d_H-i-s') . '.csv';

		// Crear el archivo CSV
		$file = fopen($csvFilePath, 'w');
		if ($file === false) {
			throw new \Exception('No se pudo crear el archivo CSV de logs.');
		}

		// Añadir encabezados
		fputcsv($file, ['ID', 'Type', 'Message', 'URL', 'Status', 'Body', 'Response', 'Date']);

		// Añadir logs al archivo CSV
		foreach ($logs as $log) {
			fputcsv($file, [
				$log['id'],
				$log['type'],
				$log['message'],
				$log['url'] ?? '',
				$log['status'] ?? '',
				$log['body'] ?? '',
				$log['response'] ?? '',
				$log['date'],
			]);
		}
		fclose($file);

		// Devolver la ruta del archivo CSV
		return $csvFilePath;
	}
}
