<?php

namespace FleekDash\Services;

defined('ABSPATH') || exit;

/**
 * Resolves and validates integration configuration paths and config data.
 */
class IntegrationConfigResolver
{
    private const CONFIG_JSON_PATH = '/config.json';
    private const ERROR_INTEGRATION_NOT_FOUND = 'Integration not found';

    /**
     * Parse and validate source ID format
     *
     * @return array{0: string, 1: string} [integration_id, actual_source_id]
     * @throws ExternalDataSourcesServiceException
     */
    public function parseSourceId(string $sourceId): array
    {
        $parts = explode('_', $sourceId, 2);
        if (count($parts) !== 2) {
            throw new ExternalDataSourcesServiceException('Invalid source ID format');
        }
        [$integrationId, $actualSourceId] = $parts;
        if (!\preg_match('/^[a-zA-Z0-9_-]+$/', $integrationId)) {
            throw new ExternalDataSourcesServiceException('Invalid integration ID format');
        }
        return [$integrationId, $actualSourceId];
    }

    /**
     * Get validated config path for integration
     *
     * @throws ExternalDataSourcesServiceException
     */
    public function getValidatedIntegrationConfigPath(string $integrationId): string
    {
        $integrationsBase = \realpath(FLEEKDASH_PLUGIN_DIR . 'integrations');
        if (!$integrationsBase) {
            throw new ExternalDataSourcesServiceException(self::ERROR_INTEGRATION_NOT_FOUND);
        }
        $configDir = $integrationsBase . \DIRECTORY_SEPARATOR . $integrationId;
        $resolvedPath = \realpath($configDir);
        if (!$resolvedPath || !\str_starts_with($resolvedPath, $integrationsBase)) {
            throw new ExternalDataSourcesServiceException(self::ERROR_INTEGRATION_NOT_FOUND);
        }
        $configPath = $resolvedPath . self::CONFIG_JSON_PATH;
        if (!\file_exists($configPath)) {
            throw new ExternalDataSourcesServiceException(self::ERROR_INTEGRATION_NOT_FOUND);
        }
        return $configPath;
    }

    /**
     * Load and validate integration config
     *
     * @throws ExternalDataSourcesServiceException
     */
    public function loadIntegrationConfig(string $configPath): array
    {
        $config = json_decode(file_get_contents($configPath), true);
        if (!$config) {
            throw new ExternalDataSourcesServiceException('Invalid integration configuration');
        }
        return $config;
    }

    /**
     * Find data source in config
     *
     * @throws ExternalDataSourcesServiceException
     */
    public function findDataSourceInConfig(array $config, string $actualSourceId): array
    {
        foreach ($config['data_sources'] ?? [] as $source) {
            if (($source['id'] ?? '') === $actualSourceId) {
                return $source;
            }
        }
        throw new ExternalDataSourcesServiceException('Data source not found');
    }

    /**
     * Validate metric exists in data source
     *
     * @throws ExternalDataSourcesServiceException
     */
    public function validateMetricExists(array $dataSource, string $metricId): void
    {
        foreach ($dataSource['metrics'] ?? [] as $m) {
            if (($m['id'] ?? '') === $metricId) {
                return;
            }
        }
        throw new ExternalDataSourcesServiceException('Metric not found');
    }
}
