<?php

declare(strict_types=1);

namespace App\Application\Analytics\Service;

use App\Application\Analytics\ValueObject\ActionBreakdown;
use App\Application\Analytics\ValueObject\BrowserBreakdown;
use App\Application\Analytics\ValueObject\BusinessMetricsReport;
use App\Application\Analytics\ValueObject\CountryBreakdown;
use App\Application\Analytics\ValueObject\DeviceBreakdown;
use App\Application\Analytics\ValueObject\UserBehaviorReport;
use App\Framework\Analytics\AnalyticsCategory;
use App\Framework\Analytics\Storage\AnalyticsStorage;

/**
 * Service für Analytics-Reports und Datenexport
 * Verantwortlich für: Report-Generierung, Datenexport, Filterung
 */
final readonly class AnalyticsReportService
{
    public function __construct(
        private AnalyticsStorage $storage
    ) {
    }

    public function getUserBehavior(string $startDate, string $endDate): UserBehaviorReport
    {
        $actions = ActionBreakdown::fromArray($this->getTopActions($startDate, $endDate, 20));
        $devices = DeviceBreakdown::fromArray($this->getDeviceBreakdown($startDate, $endDate));
        $browsers = BrowserBreakdown::fromArray($this->getBrowserBreakdown($startDate, $endDate));
        $countries = CountryBreakdown::fromArray($this->getCountryBreakdown($startDate, $endDate));

        return new UserBehaviorReport($actions, $devices, $browsers, $countries);
    }

    public function getBusinessMetrics(string $startDate, string $endDate): BusinessMetricsReport
    {
        return new BusinessMetricsReport(
            conversions: $this->getConversions($startDate, $endDate),
            revenue: $this->getRevenue($startDate, $endDate),
            goalCompletions: $this->getGoalCompletions($startDate, $endDate),
            funnelData: $this->getFunnelData($startDate, $endDate)
        );
    }

    // Backward compatibility methods (deprecated)

    /**
     * @deprecated Use getUserBehavior() which returns UserBehaviorReport instead
     * @return array<string, array<int|string, mixed>>
     */
    public function getUserBehaviorArray(string $startDate, string $endDate): array
    {
        return $this->getUserBehavior($startDate, $endDate)->toArray();
    }

    /**
     * @deprecated Use getBusinessMetrics() which returns BusinessMetricsReport instead
     * @return array<string, array<int|string, mixed>>
     */
    public function getBusinessMetricsArray(string $startDate, string $endDate): array
    {
        return $this->getBusinessMetrics($startDate, $endDate)->toArray();
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function getEvents(string $startDate, string $endDate, ?AnalyticsCategory $category = null, int $limit = 100, int $offset = 0): array
    {
        // Simuliere Events basierend auf verfügbaren Daten
        $events = [];
        $totalEvents = 50; // Simulation

        for ($i = $offset; $i < min($offset + $limit, $totalEvents); $i++) {
            $events[] = [
                'id' => $i + 1,
                'timestamp' => date('Y-m-d H:i:s', strtotime($startDate) + ($i * 3600)),
                'action' => 'page_view',
                'category' => $category?->value ?? 'page_views',
                'properties' => [
                    'path' => '/',
                    'user_agent' => 'Mozilla/5.0...',
                ],
            ];
        }

        return $events;
    }

    public function getEventsCount(string $startDate, string $endDate, ?AnalyticsCategory $category = null): int
    {
        // Simuliere Event-Count
        return 150;
    }

    /**
     * @return array<string, mixed>
     */
    public function exportData(string $startDate, string $endDate, ?AnalyticsCategory $category = null, string $format = 'json'): array
    {
        $data = [
            'overview' => $this->storage->getAggregated($startDate, $endDate, 'day'),
            'timeseries' => $this->storage->getTimeSeries('page_views', $startDate, $endDate, 'day'),
            'top_pages' => $this->storage->getTopList('page_views', $startDate, $endDate, 20),
        ];

        if ($format === 'csv') {
            // Convert to CSV format
            return $this->convertToCsv($data);
        }

        return $data;
    }

    /**
     * @return array<int, array{action: string, count: int}>
     */
    private function getTopActions(string $startDate, string $endDate, int $limit): array
    {
        return [
            ['action' => 'page_view', 'count' => 1250],
            ['action' => 'button_click', 'count' => 340],
            ['action' => 'form_submit', 'count' => 89],
            ['action' => 'download', 'count' => 45],
        ];
    }

    /**
     * @return array<string, int>
     */
    private function getDeviceBreakdown(string $startDate, string $endDate): array
    {
        return [
            'Desktop' => 60,
            'Mobile' => 35,
            'Tablet' => 5,
        ];
    }

    /**
     * @return array<string, int>
     */
    private function getBrowserBreakdown(string $startDate, string $endDate): array
    {
        return [
            'Chrome' => 65,
            'Firefox' => 20,
            'Safari' => 10,
            'Edge' => 5,
        ];
    }

    /**
     * @return array<string, int>
     */
    private function getCountryBreakdown(string $startDate, string $endDate): array
    {
        return [
            'Germany' => 70,
            'Austria' => 15,
            'Switzerland' => 10,
            'Others' => 5,
        ];
    }

    /**
     * @return array<string, int>
     */
    private function getConversions(string $startDate, string $endDate): array
    {
        return [
            'signup' => 45,
            'purchase' => 12,
            'download' => 89,
            'contact' => 23,
        ];
    }

    /**
     * @return array<string, string|int|float>
     */
    private function getRevenue(string $startDate, string $endDate): array
    {
        return [
            'total' => 2345.67,
            'currency' => 'EUR',
            'transactions' => 12,
            'average_order_value' => 195.47,
        ];
    }

    /**
     * @return array<string, int>
     */
    private function getGoalCompletions(string $startDate, string $endDate): array
    {
        return [
            'newsletter_signup' => 234,
            'contact_form' => 45,
            'product_view' => 1234,
            'checkout_start' => 67,
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private function getFunnelData(string $startDate, string $endDate): array
    {
        return [
            'steps' => [
                ['name' => 'Landing Page', 'visitors' => 1000, 'conversion' => 1.0],
                ['name' => 'Product View', 'visitors' => 650, 'conversion' => 0.65],
                ['name' => 'Add to Cart', 'visitors' => 130, 'conversion' => 0.20],
                ['name' => 'Checkout', 'visitors' => 65, 'conversion' => 0.50],
                ['name' => 'Purchase', 'visitors' => 32, 'conversion' => 0.49],
            ],
            'overall_conversion' => 0.032,
        ];
    }

    /**
     * @param array<string, mixed> $data
     * @return array<string, string>
     */
    private function convertToCsv(array $data): array
    {
        // Vereinfachte CSV-Konvertierung
        return [
            'format' => 'csv',
            'data' => 'Date,Page Views,Unique Visitors\n' .
                     implode('\n', array_map(fn ($date, $views) => "$date,$views,0", array_keys($data['timeseries'] ?? []), array_values($data['timeseries'] ?? []))),
        ];
    }
}
