<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\AdminBundle\Statistics;

use Ferienpass\CoreBundle\Entity\Edition;

/**
 * Self-contained snapshot of everything the Saison-Statistik page renders.
 *
 * One DTO per request. Shape-stable so Twig macros can rely on each key
 * existing (empty arrays for "no data" rather than null where possible).
 *
 * Array shapes are documented inline next to each property; they mirror the
 * data hooks (`data-chart="…"`) in the template so a future Plotly upgrade
 * only swaps the bodies.
 */
final class EditionStats
{
    /**
     * @param list<array{label: string, value: int|float, suffix: string}>                                $kpis
     * @param list<array{date: string, n: int}>                                                           $daily
     * @param array{total: int, segments: list<array{label: string, n: int, tone: string, desc: string}>} $applicationStatus
     * @param list<array{label: string, count: int, tone: string}>                                        $funnel
     * @param list<array{spots: int, n: int}>                                                             $confirmedPerKid
     * @param list<array{count: int, n: int}>                                                             $appliedPerKid
     * @param list<array{h: int, n: int}>                                                                 $registrationHours
     * @param list<array{age: string, n: int}>                                                            $ages
     * @param list<array{label: string, signups: int, slots: int, offers: int}>                           $categories
     * @param array{total: int, segments: list<array{label: string, n: int, tone: string, desc: string}>} $newVsReturning
     * @param list<array{plz: string, label: string, n: int}>                                             $plzDistribution
     * @param list<array{label: string, sub: ?string, signups: int, slots: int}>                          $topOffers
     * @param list<array{label: string, sub: ?string, signups: int, slots: int}>                          $flopOffers
     * @param list<array{bucket: string, n: int, tone: string}>                                           $utilization
     * @param list<array{name: string, offers: int, signups: int, util: int}>                             $topVendors
     * @param list<array{label: string, n: int, tone: string, axisLabel: string, highlight: bool}>        $priceDistribution
     * @param list<array{label: string, n: int, tone: string, axisLabel: string, highlight: bool}>        $paymentTiming
     * @param list<array{label: string, n: int, tone: string, axisLabel: string, highlight: bool}>        $cancellationTiming
     * @param list<Edition>                                                                               $comparableEditions
     * @param array<string, int|float>                                                                    $compareDeltas
     */
    public function __construct(
        public readonly Edition $edition,
        public readonly array $kpis,
        public readonly ?array $appWindow,
        public readonly ?array $eventWindow,
        public readonly array $daily,
        public readonly array $applicationStatus,
        public readonly array $funnel,
        public readonly array $confirmedPerKid,
        public readonly array $appliedPerKid,
        public readonly array $registrationHours,
        public readonly array $ages,
        public readonly array $categories,
        public readonly array $newVsReturning,
        public readonly array $plzDistribution,
        public readonly array $topOffers,
        public readonly array $flopOffers,
        public readonly array $utilization,
        public readonly array $topVendors,
        public readonly array $priceDistribution,
        public readonly array $paymentTiming,
        public readonly array $cancellationTiming,
        public readonly array $comparableEditions,
        public readonly ?Edition $compareEdition,
        public readonly array $compareDeltas,
    ) {
    }

    /** Has the dataset enough rows to be worth rendering? */
    public function isEmpty(): bool
    {
        // Sum of KPI values — if nothing is signed up, page becomes useless.
        $total = 0;
        foreach ($this->kpis as $k) {
            $total += (int) $k['value'];
        }

        return 0 === $total;
    }
}
