<?php

require_once __DIR__ . '/../services/CandleService.php';
require_once __DIR__ . '/../services/SmcAnalyzer.php';

class MultiTimeframeService
{
    /*
    |--------------------------------------------------------------------------
    | Higher Timeframe Mapping
    |--------------------------------------------------------------------------
    |
    | Execution timeframe => Context timeframe
    |
    */

    public static function getHigherTimeframe(string $timeframe): string
    {
        return match ($timeframe) {
            
            '1m' => '5m',
            '5m' => '15m',
            '15m' => '1H',
            '30m' => '4H',
            '1H'  => '4H',
            '2H'  => '4H',
            '4H'  => '1D',
            '1D'  => '1W',
            '1W'  => '1MN',

            default => '4H'
        };
    }

    /*
    |--------------------------------------------------------------------------
    | Full HTF Context Analysis
    |--------------------------------------------------------------------------
    */

    public static function getHTFContext(string $symbol, string $timeframe): array
    {
        $htf = self::getHigherTimeframe($timeframe);

        $candles = CandleService::getCandles($symbol, $htf, 200);

        if (empty($candles)) {
            return [
                'timeframe' => $htf,
                'bias' => 'NEUTRAL',
                'premium_discount' => 'UNKNOWN',
                'equilibrium' => null,
                'range_high' => null,
                'range_low' => null,
                'current_price' => null,
                'dealing_range_position' => null,
                'liquidity' => [],
                'valid' => false
            ];
        }

        $swings = SmcAnalyzer::detectSwings($candles);

        $events = SmcAnalyzer::detectStructureEvents($swings);

        $bias = SmcAnalyzer::getBias($events);

        $currentPrice = (float)end($candles)['close_price'];

        $rangeHigh = self::getRangeHigh($candles);

        $rangeLow = self::getRangeLow($candles);

        $equilibrium = ($rangeHigh + $rangeLow) / 2;

        $premiumDiscount = self::getPremiumDiscount(
            $currentPrice,
            $rangeHigh,
            $rangeLow
        );

        $position = self::calculateRangePosition(
            $currentPrice,
            $rangeHigh,
            $rangeLow
        );

        $liquidity = SmcAnalyzer::getLiquidityTargets($swings);

        return [

            'timeframe' => $htf,

            'bias' => $bias,

            'premium_discount' => $premiumDiscount,

            'equilibrium' => $equilibrium,

            'range_high' => $rangeHigh,

            'range_low' => $rangeLow,

            'current_price' => $currentPrice,

            'dealing_range_position' => $position,

            'liquidity' => $liquidity,

            'valid' => true
        ];
    }

    /*
    |--------------------------------------------------------------------------
    | Premium / Discount Logic
    |--------------------------------------------------------------------------
    */

    public static function getPremiumDiscount(
        float $currentPrice,
        float $rangeHigh,
        float $rangeLow
    ): string {

        $equilibrium = ($rangeHigh + $rangeLow) / 2;

        if ($currentPrice > $equilibrium) {
            return 'PREMIUM';
        }

        if ($currentPrice < $equilibrium) {
            return 'DISCOUNT';
        }

        return 'EQUILIBRIUM';
    }

    /*
    |--------------------------------------------------------------------------
    | Range Position %
    |--------------------------------------------------------------------------
    */

    public static function calculateRangePosition(
        float $currentPrice,
        float $rangeHigh,
        float $rangeLow
    ): float {

        $range = $rangeHigh - $rangeLow;

        if ($range <= 0) {
            return 50;
        }

        return round(
            (($currentPrice - $rangeLow) / $range) * 100,
            2
        );
    }

    /*
    |--------------------------------------------------------------------------
    | Trading Alignment Check
    |--------------------------------------------------------------------------
    */

    public static function isAlignedWithHTF(
        string $executionBias,
        string $htfBias
    ): bool {

        if ($executionBias === 'WAIT') {
            return false;
        }

        return $executionBias === $htfBias;
    }

    /*
    |--------------------------------------------------------------------------
    | Narrative
    |--------------------------------------------------------------------------
    */

    public static function buildNarrative(
        string $executionBias,
        array $htfContext
    ): string {

        $htfBias = $htfContext['bias'] ?? 'NEUTRAL';

        $pd = $htfContext['premium_discount'] ?? 'UNKNOWN';

        $position = $htfContext['dealing_range_position'] ?? 50;

        if (
            $executionBias === $htfBias &&
            $executionBias === 'BUY' &&
            $pd === 'DISCOUNT'
        ) {
            return 'Bullish continuation from discount pricing.';
        }

        if (
            $executionBias === $htfBias &&
            $executionBias === 'SELL' &&
            $pd === 'PREMIUM'
        ) {
            return 'Bearish continuation from premium pricing.';
        }

        if (
            $executionBias !== $htfBias
        ) {
            return 'Counter-trend setup against higher timeframe structure.';
        }

        return 'Neutral institutional positioning.';
    }

    /*
    |--------------------------------------------------------------------------
    | Strong HTF Confluence
    |--------------------------------------------------------------------------
    */

    public static function getHTFConfluenceScore(
        string $executionBias,
        array $htfContext
    ): int {

        $score = 0;

        $htfBias = $htfContext['bias'] ?? 'WAIT';

        $pd = $htfContext['premium_discount'] ?? 'UNKNOWN';

        if ($executionBias === $htfBias) {
            $score += 3;
        }

        if (
            $executionBias === 'BUY' &&
            $pd === 'DISCOUNT'
        ) {
            $score += 2;
        }

        if (
            $executionBias === 'SELL' &&
            $pd === 'PREMIUM'
        ) {
            $score += 2;
        }

        return $score;
    }

    /*
    |--------------------------------------------------------------------------
    | Internal Helpers
    |--------------------------------------------------------------------------
    */

    private static function getRangeHigh(array $candles): float
    {
        return max(
            array_map(
                fn($c) => (float)$c['high_price'],
                array_slice($candles, -120)
            )
        );
    }

    private static function getRangeLow(array $candles): float
    {
        return min(
            array_map(
                fn($c) => (float)$c['low_price'],
                array_slice($candles, -120)
            )
        );
    }
} 