<?php

class InstitutionalNarrativeService
{
    public static function build(array $context): array
    {
        $symbol = strtoupper((string)($context['symbol'] ?? 'This market'));
        $primary = is_array($context['primary'] ?? null) ? $context['primary'] : [];
        $secondary = is_array($context['secondary'] ?? null) ? $context['secondary'] : [];
        $decision = is_array($context['decision'] ?? null) ? $context['decision'] : [];

        $label = strtoupper((string)($decision['label'] ?? ''));
        $action = strtoupper((string)($decision['action'] ?? ''));

        if (str_contains($label, 'BUY') || $action === 'BUY') {
            $side = 'BUY';
        } elseif (str_contains($label, 'SELL') || $action === 'SELL') {
            $side = 'SELL';
        } else {
            $side = strtoupper((string)($decision['primary_side'] ?? $primary['side'] ?? 'WAIT'));
        }

        $secondarySide = strtoupper((string)($decision['secondary_side'] ?? $secondary['side'] ?? ''));
        $score = is_numeric($decision['score_10'] ?? null) ? (float)$decision['score_10'] : (float)($primary['score_10'] ?? 0);

        $htfBias = strtoupper((string)($context['context_bias'] ?? 'NEUTRAL'));
        $ltfBias = strtoupper((string)($context['execution_bias'] ?? 'NEUTRAL'));
        $confirmationStage = strtoupper((string)($context['confirmation_stage'] ?? 'CONFIRMATION_PENDING'));
        $confirmationCount = (int)($context['confirmation_count'] ?? 0);
        $partialCount = (int)($context['partial_confirmation_count'] ?? 0);
        $newsRisk = strtoupper((string)($context['news_risk'] ?? 'LOW'));
        $geoRisk = strtoupper((string)($context['geo_risk'] ?? 'LOW'));
        $locationLabel = trim((string)($context['location_label'] ?? ''));
        $locationScore = is_numeric($context['location_score'] ?? null) ? (float)$context['location_score'] : null;
        $pdLabel = trim((string)($context['pd_label'] ?? ''));

        $text = self::contextText(
            $symbol, $side, $secondarySide, $score, $htfBias, $ltfBias,
            $confirmationStage, $confirmationCount, $partialCount,
            $newsRisk, $geoRisk, $locationLabel, $locationScore, $pdLabel,
            $primary, $secondary
        );

        return [
            'reason' => $text,
            'full' => $text,
            'market_structure' => $text,
            'headline' => self::headline($side, $score, $confirmationStage),
            'confidence' => self::confidenceLabel($score),
            'key_points' => self::keyPoints($side, $score, $confirmationCount, $partialCount, $newsRisk, $geoRisk, $locationLabel),
        ];
    }

    private static function contextText(
        string $symbol,
        string $side,
        string $secondarySide,
        float $score,
        string $htfBias,
        string $ltfBias,
        string $confirmationStage,
        int $confirmationCount,
        int $partialCount,
        string $newsRisk,
        string $geoRisk,
        string $locationLabel,
        ?float $locationScore,
        string $pdLabel,
        array $primary,
        array $secondary
    ): string {
        $sentences = [];

        if (in_array($side, ['BUY', 'SELL'], true)) {
            $directionWord = $side === 'BUY' ? 'bullish' : 'bearish';
            $participants = $side === 'BUY' ? 'buyers' : 'sellers';

            if ($confirmationStage === 'EXECUTION_CONFIRMED' && $score >= 6.5) {
                $sentences[] = "{$symbol} has a confirmed {$directionWord} institutional setup, with {$participants} in control and execution conditions aligned.";
            } elseif ($score >= 5.5) {
                $sentences[] = "{$symbol} has a valid {$directionWord} institutional bias, but it is not an execution signal yet because confirmation is still incomplete.";
            } else {
                $sentences[] = "{$symbol} has a possible {$directionWord} scenario on watchlist, but institutional confluence is not strong enough yet for execution.";
            }
        } else {
            $sentences[] = "{$symbol} is in a non-executable state. Wait for structure, liquidity, and confirmation to align before treating either side as valid.";
        }

        if (in_array($side, ['BUY', 'SELL'], true)) {
            if ($htfBias === $side && $ltfBias === $side) {
                $sentences[] = "Higher-timeframe and execution-timeframe bias both support the primary {$side} scenario.";
            } elseif ($htfBias === $side) {
                $sentences[] = "Higher-timeframe bias supports {$side}, but the execution timeframe still needs stronger confirmation.";
            } elseif ($ltfBias === $side) {
                $sentences[] = "The execution timeframe supports {$side}, but higher-timeframe alignment is incomplete, so the setup requires stricter confirmation.";
            } else {
                $sentences[] = "Directional alignment is incomplete, so this remains a developing bias rather than a confirmed trade.";
            }
        }

        $hasZone = !empty($primary['zone']) || !empty($primary['entry_low']) || !empty($primary['entry_high']);
        if ($hasZone && in_array($side, ['BUY', 'SELL'], true)) {
            $quality = '';
            if ($locationScore !== null && $locationScore >= 75) {
                $quality = 'high-quality ';
            } elseif ($locationScore !== null && $locationScore >= 55) {
                $quality = 'acceptable ';
            }

            $zoneType = $side === 'BUY' ? 'demand/discount' : 'supply/premium';
            $label = $locationLabel !== '' ? strtolower($locationLabel) : strtolower($pdLabel);
            $sentences[] = trim("Price is interacting with a {$quality}{$zoneType} location" . ($label ? ", classified as {$label}" : '') . '.');
        } else {
            $sentences[] = 'No qualified institutional execution zone is strong enough for immediate execution.';
        }

        if ($confirmationStage === 'EXECUTION_CONFIRMED') {
            $sentences[] = 'Liquidity, displacement, structure validation, and candle confirmation are sufficiently aligned for execution planning.';
        } elseif ($confirmationCount >= 2) {
            $sentences[] = 'Several confirmation conditions are active, but the final execution trigger has not completed.';
        } elseif ($confirmationCount >= 1 || $partialCount > 0) {
            $sentences[] = 'Confirmation is developing, but liquidity sweep, displacement, or candle confirmation still needs to mature.';
        } else {
            $sentences[] = 'Liquidity sweep, displacement, structure validation, and candle confirmation remain pending.';
        }

        if (in_array($newsRisk, ['HIGH', 'CRITICAL', 'EXTREME'], true)) {
            $sentences[] = 'High-impact scheduled news risk is active, so entries should avoid fast candles and use reduced size.';
        } elseif ($newsRisk === 'MEDIUM') {
            $sentences[] = 'Medium-impact scheduled news is present, so confirmation should be stricter than normal.';
        }

        if (in_array($geoRisk, ['HIGH', 'CRITICAL', 'EXTREME'], true)) {
            $sentences[] = 'Geopolitical risk is elevated, increasing headline-driven volatility and requiring conservative execution.';
        } elseif ($geoRisk === 'MEDIUM') {
            $sentences[] = 'Geopolitical conditions are moderately sensitive, so exposure should remain controlled.';
        }

        if (!in_array($newsRisk, ['MEDIUM', 'HIGH', 'CRITICAL', 'EXTREME'], true) && !in_array($geoRisk, ['MEDIUM', 'HIGH', 'CRITICAL', 'EXTREME'], true)) {
            $sentences[] = 'No major macro or geopolitical restriction currently invalidates the setup.';
        }

        if (in_array($side, ['BUY', 'SELL'], true)) {
            if ($confirmationStage === 'EXECUTION_CONFIRMED' && $score >= 6.5) {
                $sentences[] = "{$side} execution is acceptable only if price respects the institutional zone and risk remains controlled.";
            } else {
                $sentences[] = "{$side} remains the preferred bias, but execution should wait for confirmation rather than chasing current price.";
            }
        }

        if (in_array($secondarySide, ['BUY', 'SELL'], true) && $secondarySide !== $side) {
            $sentences[] = "The secondary {$secondarySide} scenario remains an alternative path, but it is lower priority unless confirmation shifts.";
        }

        return implode(' ', array_values(array_filter($sentences)));
    }

    private static function headline(string $side, float $score, string $stage): string
    {
        if (in_array($side, ['BUY', 'SELL'], true) && $stage === 'EXECUTION_CONFIRMED' && $score >= 6.5) {
            return "{$side} CONFIRMED";
        }

        if (in_array($side, ['BUY', 'SELL'], true) && $score >= 5.5) {
            return "{$side} BIAS - WAIT FOR CONFIRMATION";
        }

        return 'WAIT FOR STRONGER CONFLUENCE';
    }

    private static function confidenceLabel(float $score): string
    {
        if ($score >= 8.5) return 'VERY HIGH';
        if ($score >= 7.0) return 'HIGH';
        if ($score >= 5.5) return 'MEDIUM';
        if ($score >= 4.5) return 'LOW';
        return 'VERY LOW';
    }

    private static function keyPoints(string $side, float $score, int $confirmed, int $partial, string $newsRisk, string $geoRisk, string $locationLabel): array
    {
        $points = [];
        if (in_array($side, ['BUY', 'SELL'], true)) {
            $points[] = "Primary bias: {$side}";
        }
        $points[] = 'Execution score: ' . number_format($score, 1) . '/10';
        $points[] = 'Confirmation: ' . $confirmed . ' confirmed' . ($partial > 0 ? ', ' . $partial . ' partial' : '');
        if ($locationLabel !== '') $points[] = 'Location: ' . $locationLabel;
        if (in_array($newsRisk, ['MEDIUM', 'HIGH', 'CRITICAL', 'EXTREME'], true)) $points[] = 'News caution active';
        if (in_array($geoRisk, ['MEDIUM', 'HIGH', 'CRITICAL', 'EXTREME'], true)) $points[] = 'Geopolitical caution active';
        return array_slice($points, 0, 6);
    }
}
