<?php

namespace classes;

use Exception;

class edge_gateway_view_service
{
    public function __construct(private readonly ?edge_gateway_manager $manager = null)
    {
        edge_gateway_schema_bootstrap::ensureTables();
    }

    /**
     * @return array<int,array<string,mixed>>
     * @throws Exception
     */
    public function listGateways(?int $departmentId = null, bool $includeDetail = true): array
    {
        return $this->listGatewaysWithFleetUsage($departmentId, $includeDetail)['gateways'];
    }

    /**
     * @return array{gateways: array<int,array<string,mixed>>, fleet_usage: array<string,mixed>}
     * @throws Exception
     */
    public function listGatewaysWithFleetUsage(?int $departmentId = null, bool $includeDetail = true): array
    {
        $cached = edge_gateway_view_cache::getListPayload($departmentId, $includeDetail);
        if ($cached !== null) {
            return $cached;
        }

        $gateways = $this->manager()->listGateways($departmentId, $includeDetail);
        $payload = [
            'gateways' => $gateways,
            'fleet_usage' => $this->manager()->buildFleetUsageStatistics($departmentId, $gateways),
        ];
        edge_gateway_view_cache::storeListPayload($departmentId, $includeDetail, $payload);

        return $payload;
    }

    /**
     * @param array<int,array<string,mixed>> $gateways
     * @return array<string,mixed>
     * @throws Exception
     */
    public function buildFleetUsageStatistics(?int $departmentId = null, array $gateways = []): array
    {
        if ($gateways === []) {
            return $this->listGatewaysWithFleetUsage($departmentId, false)['fleet_usage'];
        }

        return $this->manager()->buildFleetUsageStatistics($departmentId, $gateways);
    }

    /**
     * @throws Exception
     */
    public function getGateway(int $gatewayId): array
    {
        $cached = edge_gateway_view_cache::getDetailPayload($gatewayId);
        if ($cached !== null) {
            return $cached;
        }

        $gateway = $this->manager()->getGateway($gatewayId);
        edge_gateway_view_cache::storeDetailPayload($gatewayId, $gateway);

        return $gateway;
    }

    private function manager(): edge_gateway_manager
    {
        return $this->manager ?? new edge_gateway_manager();
    }
}
