<?php

declare(strict_types=1);

namespace CloudXM\NFe\Services;

use CloudXM\NFe\Config\Configuration;
use CloudXM\NFe\DTOs\TenantConfigResource;
use CloudXM\SDK\Support\HasLogger;

/**
 * Tenant Config Cache
 * 
 * Handles caching of tenant configuration to reduce API calls
 * Cache TTL: 1 hour (3600 seconds)
 */
class TenantConfigCache
{
    use HasLogger;

    private const CACHE_KEY = 'cloudxm_nfe_tenant_config_v2';
    private const CACHE_TTL = 3600; // 1 hour

    private ?TenantConfigResource $cachedConfig = null;

    public function __construct(
        private Configuration $config,
        private ApiClient $apiClient
    ) {}

    /**
     * Get tenant configuration (cached)
     * 
     * @return TenantConfigResource
     * @throws \RuntimeException if unable to fetch config
     */
    public function get(): TenantConfigResource
    {
        // Check memory cache first
        if ($this->cachedConfig !== null) {
            $this->log()->debug('nfe.tenant_config.memory_cache_hit');
            return $this->cachedConfig;
        }

        // Check transient cache
        $cached = get_transient(self::CACHE_KEY);
        
        if ($cached instanceof TenantConfigResource) {
            $this->log()->info('nfe.tenant_config.cache_hit');
            $this->cachedConfig = $cached;
            return $cached;
        }

        // Cache miss - fetch from API
        $this->log()->info('nfe.tenant_config.cache_miss');
        
        try {
            $config = $this->apiClient->getTenantConfigV2();
            
            // Store in both caches
            $this->cachedConfig = $config;
            set_transient(self::CACHE_KEY, $config, self::CACHE_TTL);
            
            $this->log()->info('nfe.tenant_config.fetched_and_cached', [
                'tenant_id' => $config->tenant_id,
                'cache_ttl' => self::CACHE_TTL
            ]);
            
            return $config;
        } catch (\Exception $e) {
            $this->log()->error('nfe.tenant_config.fetch_failed', [
                'error' => $e->getMessage()
            ]);
            throw new \RuntimeException('Failed to fetch tenant configuration: ' . $e->getMessage(), 0, $e);
        }
    }

    /**
     * Clear tenant config cache
     * Should be called when environment changes or settings are updated
     */
    public function clear(): void
    {
        $this->cachedConfig = null;
        delete_transient(self::CACHE_KEY);
        
        $this->log()->info('nfe.tenant_config.cache_cleared');
    }

    /**
     * Refresh tenant config cache
     * Forces a new fetch from API and updates cache
     * 
     * @return TenantConfigResource
     */
    public function refresh(): TenantConfigResource
    {
        $this->clear();
        return $this->get();
    }
}
