<?php

declare(strict_types=1);

namespace App\Application\LiveComponents\Services;

use App\Application\LiveComponents\ValueObjects\ChartData;
use App\Application\LiveComponents\ValueObjects\ChartType;
use App\Application\LiveComponents\ValueObjects\DataRange;
use App\Framework\LiveComponents\Attributes\DataProvider;

/**
 * DemoChartDataProvider - Demo implementation with generated data
 *
 * Provides demo/fake data for development and testing.
 * No external dependencies - generates data on the fly.
 */
#[DataProvider(name: 'demo')]
final readonly class DemoChartDataProvider implements ChartDataProvider
{
    public function getChartData(ChartType $chartType, DataRange $dataRange): ChartData
    {
        $labels = $this->generateLabels($dataRange);

        return match ($chartType) {
            ChartType::PIE => $this->generatePieChartData(),
            ChartType::BAR => $this->generateBarChartData($labels),
            ChartType::AREA => $this->generateAreaChartData($labels),
            ChartType::LINE => $this->generateLineChartData($labels)
        };
    }

    public function getNewDataPoint(ChartType $chartType): array
    {
        return match ($chartType) {
            ChartType::PIE => [rand(10, 100)],
            ChartType::LINE => [rand(50, 150)],
            ChartType::BAR => [rand(30, 120), rand(40, 100)],
            ChartType::AREA => [rand(60, 140), rand(40, 120)]
        };
    }

    public function getAvailableChartTypes(): array
    {
        return [
            ChartType::LINE,
            ChartType::BAR,
            ChartType::PIE,
            ChartType::AREA,
        ];
    }

    public function getAvailableDataRanges(): array
    {
        return [
            DataRange::ONE_HOUR,
            DataRange::TWENTY_FOUR_HOURS,
            DataRange::SEVEN_DAYS,
            DataRange::THIRTY_DAYS,
        ];
    }

    private function generateLabels(DataRange $dataRange): array
    {
        $labels = [];
        $count = $dataRange->getDataPointsCount();
        $interval = $dataRange->getInterval();
        $format = $dataRange->getDateFormat();
        $now = time();

        for ($i = $count - 1; $i >= 0; $i--) {
            $timestamp = $now - ($i * $interval);
            $labels[] = date($format, $timestamp);
        }

        return $labels;
    }

    private function generateLineChartData(array $labels): ChartData
    {
        $data = [];
        $baseValue = 100;

        foreach ($labels as $label) {
            $baseValue += rand(-10, 15);
            $baseValue = max(50, min(150, $baseValue)); // Keep in range
            $data[] = $baseValue;
        }

        return new ChartData(
            labels: $labels,
            datasets: [
                [
                    'label' => 'Besucher',
                    'data' => $data,
                    'borderColor' => 'rgb(59, 130, 246)',
                    'backgroundColor' => 'rgba(59, 130, 246, 0.1)',
                    'tension' => 0.4,
                ],
            ],
            type: ChartType::LINE
        );
    }

    private function generateBarChartData(array $labels): ChartData
    {
        $data1 = [];
        $data2 = [];

        foreach ($labels as $label) {
            $data1[] = rand(30, 120);
            $data2[] = rand(40, 100);
        }

        return new ChartData(
            labels: $labels,
            datasets: [
                [
                    'label' => 'Verkäufe',
                    'data' => $data1,
                    'backgroundColor' => 'rgba(59, 130, 246, 0.8)',
                ],
                [
                    'label' => 'Retouren',
                    'data' => $data2,
                    'backgroundColor' => 'rgba(239, 68, 68, 0.8)',
                ],
            ],
            type: ChartType::BAR
        );
    }

    private function generatePieChartData(): ChartData
    {
        return new ChartData(
            labels: ['Desktop', 'Mobile', 'Tablet', 'Other'],
            datasets: [
                [
                    'label' => 'Geräte',
                    'data' => [rand(30, 50), rand(25, 45), rand(10, 20), rand(5, 15)],
                    'backgroundColor' => [
                        'rgba(59, 130, 246, 0.8)',
                        'rgba(16, 185, 129, 0.8)',
                        'rgba(245, 158, 11, 0.8)',
                        'rgba(239, 68, 68, 0.8)',
                    ],
                ],
            ],
            type: ChartType::PIE
        );
    }

    private function generateAreaChartData(array $labels): ChartData
    {
        $data1 = [];
        $data2 = [];
        $baseValue1 = 80;
        $baseValue2 = 60;

        foreach ($labels as $label) {
            $baseValue1 += rand(-8, 12);
            $baseValue2 += rand(-6, 10);
            $baseValue1 = max(40, min(140, $baseValue1));
            $baseValue2 = max(30, min(120, $baseValue2));
            $data1[] = $baseValue1;
            $data2[] = $baseValue2;
        }

        return new ChartData(
            labels: $labels,
            datasets: [
                [
                    'label' => 'Revenue',
                    'data' => $data1,
                    'borderColor' => 'rgb(59, 130, 246)',
                    'backgroundColor' => 'rgba(59, 130, 246, 0.3)',
                    'fill' => true,
                    'tension' => 0.4,
                ],
                [
                    'label' => 'Costs',
                    'data' => $data2,
                    'borderColor' => 'rgb(239, 68, 68)',
                    'backgroundColor' => 'rgba(239, 68, 68, 0.3)',
                    'fill' => true,
                    'tension' => 0.4,
                ],
            ],
            type: ChartType::AREA
        );
    }
}
