<?php

declare(strict_types=1);

namespace App\Framework\Analytics;

use App\Framework\Queue\Queue;
use App\Framework\Context\ExecutionContext;
use App\Framework\Config\Configuration;

final class AnalyticsService implements AnalyticsInterface
{
    private bool $enabled;
    private array $context = [];

    public function __construct(
        private readonly Queue $queue,
        private readonly ExecutionContext $executionContext,
        private readonly Configuration $config
    ) {
        $this->enabled = $this->config->get('analytics.enabled', false);
        $this->initializeContext();
    }

    public function track(AnalyticsEvent $event): void
    {
        #if (!$this->enabled) {
        #    return;
        #}

        $enrichedEvent = $this->enrichEvent($event);

        // Queue für asynchrone Verarbeitung
        $this->queue->push('analytics', $enrichedEvent->toArray());
    }

    public function trackPageView(string $path, array $context = []): void
    {
        $this->track(AnalyticsEvent::pageView($path, array_merge($this->context, $context)));
    }

    public function trackUserAction(string $action, string $userId, array $data = []): void
    {
        $this->track(AnalyticsEvent::userAction($action, $userId, $data));
    }

    public function trackPerformance(string $metric, float $value, array $context = []): void
    {
        $this->track(AnalyticsEvent::performance($metric, $value, array_merge($this->context, $context)));
    }

    public function flush(): void
    {
        // Queue-basiert - kein explizites Flush nötig
    }

    public function isEnabled(): bool
    {
        return $this->enabled;
    }

    private function enrichEvent(AnalyticsEvent $event): AnalyticsEvent
    {
        $sessionId = $this->executionContext->getSessionId();
        $userId = $this->executionContext->getUserId();

        $enrichedEvent = $event;

        if ($sessionId && !$event->sessionId) {
            $enrichedEvent = $enrichedEvent->withSessionId($sessionId);
        }

        if ($userId && !$event->userId) {
            $enrichedEvent = $enrichedEvent->withUserId($userId);
        }

        return $enrichedEvent;
    }

    private function initializeContext(): void
    {
        $this->context = [
            'environment' => $this->config->get('app.environment', 'production'),
            'version' => $this->config->get('app.version', '1.0.0'),
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
            'ip_address' => $this->getClientIp(),
        ];
    }

    private function getClientIp(): ?string
    {
        $headers = [
            'HTTP_CF_CONNECTING_IP',
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED',
            'HTTP_X_CLUSTER_CLIENT_IP',
            'HTTP_FORWARDED_FOR',
            'HTTP_FORWARDED',
            'REMOTE_ADDR'
        ];

        foreach ($headers as $header) {
            if (!empty($_SERVER[$header])) {
                $ips = explode(',', $_SERVER[$header]);
                return trim($ips[0]);
            }
        }

        return null;
    }
}
