<?php

declare(strict_types=1);

namespace App\Framework\CircuitBreaker\SlidingWindow;

use App\Framework\CircuitBreaker\CircuitBreakerConfig;
use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\SlidingWindow\Aggregator\BooleanResult;
use App\Framework\SlidingWindow\SlidingWindow;

/**
 * Circuit Breaker specific sliding window wrapper
 */
final readonly class CircuitBreakerSlidingWindow
{
    public function __construct(
        private SlidingWindow $slidingWindow,
    ) {
    }

    /**
     * Record a successful operation
     */
    public function recordSuccess(?Timestamp $timestamp = null): void
    {
        $timestamp ??= Timestamp::now();
        $this->slidingWindow->record(true, $timestamp);
    }

    /**
     * Record a failed operation
     */
    public function recordFailure(?Timestamp $timestamp = null): void
    {
        $timestamp ??= Timestamp::now();
        $this->slidingWindow->record(false, $timestamp);
    }

    /**
     * Check if failure threshold is exceeded
     */
    public function isFailureThresholdExceeded(CircuitBreakerConfig $config): bool
    {
        $stats = $this->slidingWindow->getStats();
        $booleanData = $stats->getAggregatedValue('boolean');

        if (! $booleanData instanceof BooleanResult) {
            return false;
        }

        // Check minimum requests threshold
        if (! $booleanData->hasMinimumRequests($config->successThreshold)) {
            return false;
        }

        // Calculate failure threshold as percentage
        $failureThreshold = $config->failureThreshold / 100.0; // Convert to 0.0-1.0 range

        return $booleanData->isFailureRateExceeded($failureThreshold);
    }

    /**
     * Get current failure rate
     */
    public function getFailureRate(): float
    {
        $stats = $this->slidingWindow->getStats();
        $booleanData = $stats->getAggregatedValue('boolean');

        if (! $booleanData instanceof BooleanResult) {
            return 0.0;
        }

        return $booleanData->failureRate;
    }

    /**
     * Get success rate
     */
    public function getSuccessRate(): float
    {
        $stats = $this->slidingWindow->getStats();
        $booleanData = $stats->getAggregatedValue('boolean');

        if (! $booleanData instanceof BooleanResult) {
            return 0.0;
        }

        return $booleanData->successRate;
    }

    /**
     * Get total request count in window
     */
    public function getTotalRequests(): int
    {
        $stats = $this->slidingWindow->getStats();

        return $stats->totalCount;
    }

    /**
     * Clear the sliding window
     */
    public function clear(): void
    {
        $this->slidingWindow->clear();
    }

    /**
     * Get the underlying sliding window
     */
    public function getSlidingWindow(): SlidingWindow
    {
        return $this->slidingWindow;
    }
}
