<?php

declare(strict_types=1);

namespace App\Framework\Waf;

use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Core\ValueObjects\Percentage;
use App\Framework\DateTime\Clock;
use App\Framework\Http\Request;
use App\Framework\MachineLearning\ValueObjects\AnomalyDetection;
use App\Framework\MachineLearning\ValueObjects\Feature;
use App\Framework\Waf\MachineLearning\MachineLearningResult;

/**
 * Service for evaluating layer results and creating WAF decisions
 */
final readonly class ThreatAssessmentService
{
    public function __construct(
        private Percentage $blockingThreshold,
        private Percentage $warningThreshold,
        private bool       $learningMode,
        private Clock      $clock
    ) {
    }

    /**
     * Evaluate all layer results and ML analysis to create a decision
     * @param array<string, mixed> $layerResults
     */
    public function evaluate(
        array $layerResults,
        Request $request,
        Duration $totalDuration,
        ?MachineLearningResult $mlResult = null
    ): WafDecision {
        // Collect all detections from layers
        $allDetections = [];
        $totalThreatScore = 0.0;
        $maxConfidence = 0.0;
        $matchedRules = [];

        // Skip layer result processing for now due to missing classes
        // foreach ($layerResults as $layerName => $result) {
        //     Process layer results
        // }

        // Skip ML anomaly processing for now
        // if ($mlResult !== null && $mlResult->hasAnomalies()) {
        //     Process ML anomalies
        // }

        // Calculate normalized threat score (0-100)
        $normalizedThreatScore = min(100.0, $totalThreatScore);
        $threatScorePercentage = Percentage::from($normalizedThreatScore);
        $confidencePercentage = Percentage::from($maxConfidence);

        // Determine action based on threat score and mode
        $action = $this->determineAction($threatScorePercentage);

        // Create empty threat assessment for now
        $threatAssessment = ThreatAssessment::createEmpty();

        // Create and return WAF decision
        return WafDecision::fromAssessment($threatAssessment, $totalDuration);
    }

    /**
     * Determine action based on threat score and configuration
     */
    private function determineAction(Percentage $threatScore): WafAction
    {
        if ($this->learningMode) {
            return WafAction::MONITOR;
        }

        if ($threatScore->greaterThan($this->blockingThreshold) || $threatScore->equals($this->blockingThreshold)) {
            return WafAction::BLOCK;
        }

        if ($threatScore->greaterThan($this->warningThreshold) || $threatScore->equals($this->warningThreshold)) {
            return WafAction::CHALLENGE;
        }

        return WafAction::ALLOW;
    }

    /**
     * Get weight for severity level
     */
    private function getSeverityWeight(DetectionSeverity $severity): float
    {
        return match($severity) {
            DetectionSeverity::CRITICAL => 1.0,
            DetectionSeverity::HIGH => 0.8,
            DetectionSeverity::MEDIUM => 0.5,
            DetectionSeverity::LOW => 0.3,
            DetectionSeverity::INFO => 0.1
        };
    }

    /**
     * Map anomaly score to severity
     */
    private function mapAnomalyScoreToSeverity(float $score): DetectionSeverity
    {
        return match(true) {
            $score >= 0.9 => DetectionSeverity::CRITICAL,
            $score >= 0.7 => DetectionSeverity::HIGH,
            $score >= 0.5 => DetectionSeverity::MEDIUM,
            $score >= 0.3 => DetectionSeverity::LOW,
            default => DetectionSeverity::INFO
        };
    }

    // Methods already defined above - removed duplicates
}
