<?php
if (!defined('ABSPATH')) {
    exit;
}

class VMO_Model_Router {
    public function get_route($task_type = 'general', array $context = []) {
        $blueprint_task = $this->map_task($task_type, $context);
        $route_map = $this->get_route_map();
        $route = $route_map[$blueprint_task] ?? $route_map['user_facing_explanation'];

        if (($route['kind'] ?? 'chat') === 'chat') {
            $route = $this->resolve_chat_route($blueprint_task, $route, $context);
        }

        $plan = $context['plan'] ?? $this->get_current_plan();
        $route['requested_task'] = (string) $task_type;
        $route['task'] = $blueprint_task;
        $route['plan'] = function_exists('vmo_normalize_plan_key') ? vmo_normalize_plan_key($plan) : strtolower((string) $plan);
        $route['plan_allowed'] = $this->is_route_allowed($blueprint_task, $plan);

        if (empty($context['skip_log'])) {
            $this->log_route_choice($route, $context);
        }

        return $route;
    }

    private function get_route_map() {
        return [
            'consultation_live' => ['kind' => 'chat', 'tier' => 'fast'],
            'consultation_followup' => ['kind' => 'chat', 'tier' => 'fast'],
            'approval_presentation' => ['kind' => 'chat', 'tier' => 'fast'],
            'dashboard_assistant_chat' => ['kind' => 'chat', 'tier' => 'fast'],
            'phone_reception_reasoning' => ['kind' => 'chat', 'tier' => 'fast'],
            'website_micro_refinement' => ['kind' => 'chat', 'tier' => 'fast'],
            'simple_section_rewrite' => ['kind' => 'chat', 'tier' => 'fast'],
            'user_facing_explanation' => ['kind' => 'chat', 'tier' => 'fast'],
            'simple_daily_summary' => ['kind' => 'chat', 'tier' => 'fast'],
            'jurisdiction_resolution' => ['kind' => 'chat', 'tier' => 'strategic'],
            'business_brief_locking' => ['kind' => 'chat', 'tier' => 'strategic'],
            'market_analysis' => ['kind' => 'chat', 'tier' => 'strategic'],
            'competitor_analysis' => ['kind' => 'chat', 'tier' => 'strategic'],
            'strategy_recommendation' => ['kind' => 'chat', 'tier' => 'strategic'],
            'roadmap_generation' => ['kind' => 'chat', 'tier' => 'strategic'],
            'daily_activity_planning' => ['kind' => 'chat', 'tier' => 'strategic'],
            'website_architecture' => ['kind' => 'chat', 'tier' => 'pro'],
            'core_page_generation' => ['kind' => 'chat', 'tier' => 'pro'],
            'document_need_detection' => ['kind' => 'chat', 'tier' => 'strategic'],
            'document_generation' => ['kind' => 'chat', 'tier' => 'strategic'],
            'website_qa' => ['kind' => 'chat', 'tier' => 'pro'],
            'document_qa' => ['kind' => 'chat', 'tier' => 'strategic'],
            'roadmap_qa' => ['kind' => 'chat', 'tier' => 'strategic'],
            'scan_synthesis' => ['kind' => 'chat', 'tier' => 'strategic'],
            'action_prioritization' => ['kind' => 'chat', 'tier' => 'strategic'],
            'ops_execution_planning' => ['kind' => 'chat', 'tier' => 'strategic'],
            'live_receptionist_session' => [
                'kind' => 'realtime',
                'model' => $this->get_realtime_model(),
                'fallback_model' => $this->get_realtime_fallback_model(),
            ],
            'live_phone_turn' => [
                'kind' => 'realtime',
                'model' => $this->get_realtime_model(),
                'fallback_model' => $this->get_realtime_fallback_model(),
            ],
            'low_latency_voice_response' => [
                'kind' => 'realtime',
                'model' => $this->get_realtime_model(),
                'fallback_model' => $this->get_realtime_fallback_model(),
            ],
            'hero_image_generation' => ['kind' => 'image', 'model' => $this->get_image_model(), 'fallback_model' => null],
            'section_media_generation' => ['kind' => 'image', 'model' => $this->get_image_model(), 'fallback_model' => null],
            'brochure_media_generation' => ['kind' => 'image', 'model' => $this->get_image_model(), 'fallback_model' => null],
            'product_composite_generation' => ['kind' => 'image', 'model' => $this->get_image_model(), 'fallback_model' => null],
            'placeholder_replacement_generation' => ['kind' => 'image', 'model' => $this->get_image_model(), 'fallback_model' => null],
            'premium_hero_video' => ['kind' => 'sora', 'model' => $this->get_sora_model(), 'fallback_model' => $this->get_sora_fallback_model()],
            'campaign_motion_loop' => ['kind' => 'sora', 'model' => $this->get_sora_model(), 'fallback_model' => $this->get_sora_fallback_model()],
            'cinematic_background_loop' => ['kind' => 'sora', 'model' => $this->get_sora_model(), 'fallback_model' => $this->get_sora_fallback_model()],
        ];
    }

    private function resolve_chat_route($blueprint_task, array $route, array $context) {
        $default_tier = $route['tier'] ?? 'fast';

        // Pro tier: use GPT-5.5-pro. On error, fall DOWN to strategic (5.5)
        // — still capable, but cheaper/faster.
        if ($default_tier === 'pro') {
            $route['model'] = $this->get_pro_model();
            $route['fallback_model'] = $this->get_strategic_model();
            $route['tier'] = 'pro';
            return $route;
        }

        // Strategic tier: gpt-5.5. On error, fall DOWN to fast (5.4-mini).
        // Complexity-based ESCALATION (fast → strategic) is intentional and
        // happens via should_escalate(); error fallback must NOT also escalate.
        if ($default_tier === 'strategic') {
            $route['model'] = $this->get_strategic_model();
            $route['fallback_model'] = $this->get_fast_model();
            $route['tier'] = 'strategic';
            return $route;
        }

        // Fast tier (default): start with gpt-5.4-mini. If the prompt is
        // genuinely complex, ESCALATE up to strategic (gpt-5.5) at choose-time.
        // On runtime error, fall to a peer (nano) — NEVER auto-upgrade to 5.5
        // just because the mini call failed, since 5.5 is much pricier and
        // overkill for a transient mini error.
        $use_strategic = $this->should_escalate($blueprint_task, $context);
        if ($use_strategic) {
            $route['model'] = $this->get_strategic_model();
            $route['fallback_model'] = $this->get_fast_model();
            $route['tier'] = 'strategic';
        } else {
            $route['model'] = $this->get_fast_model();
            $route['fallback_model'] = $this->get_nano_model();
            $route['tier'] = 'fast';
        }

        return $route;
    }

    private function should_escalate($blueprint_task, array $context) {
        $fast_routes = [
            'consultation_live',
            'consultation_followup',
            'approval_presentation',
            'dashboard_assistant_chat',
            'phone_reception_reasoning',
            'website_micro_refinement',
            'simple_section_rewrite',
            'user_facing_explanation',
            'simple_daily_summary',
        ];

        if (!in_array($blueprint_task, $fast_routes, true)) {
            return false;
        }

        $complexity = $context['complexity'] ?? null;
        if (is_numeric($complexity) && (float) $complexity >= 0.65) {
            return true;
        }

        if (!empty($context['requires_strategic_reasoning']) || !empty($context['requires_qa']) || !empty($context['requires_generation'])) {
            return true;
        }

        $prompt = (string) ($context['prompt'] ?? '');
        if (strlen($prompt) > 1800) {
            return true;
        }

        return false;
    }

    private function map_task($task_type, array $context) {
        $task = strtolower(trim((string) $task_type));

        $aliases = [
            'general' => 'user_facing_explanation',
            'consultation' => 'consultation_live',
            'consultation_live' => 'consultation_live',
            'consultation_followup' => 'consultation_followup',
            'strategy_analysis' => 'strategy_recommendation',
            'legal_documents' => 'document_generation',
            'seo_optimization' => 'website_qa',
            'content_creation' => 'core_page_generation',
            'business_planning' => 'roadmap_generation',
            'website_building' => 'core_page_generation',
            'competitor_research' => 'competitor_analysis',
            'website_qa' => 'website_qa',
            'document_generation' => 'document_generation',
            'roadmap_generation' => 'roadmap_generation',
            'market_analysis' => 'market_analysis',
            'scan_synthesis' => 'scan_synthesis',
            'approval_presentation' => 'approval_presentation',
            'dashboard_assistant_chat' => 'dashboard_assistant_chat',
            'phone_reception_reasoning' => 'phone_reception_reasoning',
            'live_phone_reasoning' => 'phone_reception_reasoning',
            'simple_section_rewrite' => 'simple_section_rewrite',
            'website_micro_refinement' => 'website_micro_refinement',
            'simple_daily_summary' => 'simple_daily_summary',
            'daily_activity_planning' => 'daily_activity_planning',
            'ops_execution_planning' => 'ops_execution_planning',
            'jurisdiction_resolution' => 'jurisdiction_resolution',
            'business_brief_locking' => 'business_brief_locking',
            'live_receptionist_session' => 'live_receptionist_session',
            'live_phone_turn' => 'live_phone_turn',
            'hero_image_generation' => 'hero_image_generation',
            'premium_hero_video' => 'premium_hero_video',
        ];

        if (isset($aliases[$task])) {
            return $aliases[$task];
        }

        if (strpos($task, 'consult') !== false) {
            return 'consultation_live';
        }
        if (strpos($task, 'competitor') !== false) {
            return 'competitor_analysis';
        }
        if (strpos($task, 'roadmap') !== false || strpos($task, 'plan') !== false) {
            return 'roadmap_generation';
        }
        if (strpos($task, 'daily') !== false) {
            return 'daily_activity_planning';
        }
        if (strpos($task, 'qa') !== false) {
            return 'website_qa';
        }
        if (strpos($task, 'document') !== false || strpos($task, 'legal') !== false) {
            return 'document_generation';
        }
        if (strpos($task, 'website') !== false || strpos($task, 'page') !== false) {
            return 'core_page_generation';
        }
        if (strpos($task, 'market') !== false) {
            return 'market_analysis';
        }
        if (strpos($task, 'seo') !== false) {
            return 'website_qa';
        }
        if (strpos($task, 'image') !== false || strpos($task, 'media') !== false) {
            return 'hero_image_generation';
        }
        if (strpos($task, 'video') !== false || strpos($task, 'sora') !== false) {
            return 'premium_hero_video';
        }
        if (strpos($task, 'voice') !== false || strpos($task, 'phone') !== false) {
            return 'live_phone_turn';
        }

        return !empty($context['requires_strategic_reasoning']) ? 'strategy_recommendation' : 'user_facing_explanation';
    }

    private function is_route_allowed($blueprint_task, $plan) {
        $normalized_plan = function_exists('vmo_normalize_plan_key') ? vmo_normalize_plan_key($plan) : strtolower((string) $plan);
        if ($normalized_plan === 'free') {
            return !in_array($blueprint_task, ['premium_hero_video', 'campaign_motion_loop', 'cinematic_background_loop'], true);
        }

        return true;
    }

    private function get_current_plan() {
        $user_id = get_current_user_id();
        if ($user_id <= 0) {
            return 'free';
        }

        return (string) get_user_meta($user_id, 'vmo_subscription_status', true);
    }

    private function get_fast_model() {
        return defined('VMO_OPENAI_FAST_MODEL') ? VMO_OPENAI_FAST_MODEL : 'gpt-5.4-mini';
    }

    private function get_nano_model() {
        return defined('VMO_MODEL_NANO') ? VMO_MODEL_NANO : 'gpt-5.4-nano';
    }

    private function get_pro_model() {
        return defined('VMO_MODEL_PRO') ? VMO_MODEL_PRO : 'gpt-5.5-pro';
    }

    private function get_strategic_model() {
        return defined('VMO_OPENAI_STRATEGIC_MODEL') ? VMO_OPENAI_STRATEGIC_MODEL : 'gpt-5.5';
    }

    private function get_realtime_model() {
        return defined('VMO_OPENAI_REALTIME_MODEL') ? VMO_OPENAI_REALTIME_MODEL : 'gpt-realtime-1.5';
    }

    private function get_realtime_fallback_model() {
        return defined('VMO_OPENAI_REALTIME_FALLBACK_MODEL') ? VMO_OPENAI_REALTIME_FALLBACK_MODEL : 'gpt-realtime-mini';
    }

    private function get_image_model() {
        return defined('VMO_OPENAI_IMAGE_MODEL') ? VMO_OPENAI_IMAGE_MODEL : 'gpt-image-2';
    }

    private function get_sora_model() {
        return defined('VMO_OPENAI_SORA_MODEL') ? VMO_OPENAI_SORA_MODEL : 'sora-2-pro';
    }

    private function get_sora_fallback_model() {
        return defined('VMO_OPENAI_SORA_FALLBACK_MODEL') ? VMO_OPENAI_SORA_FALLBACK_MODEL : 'sora-2';
    }

    private function log_route_choice(array $route, array $context) {
        $user_id = isset($context['user_id']) ? (int) $context['user_id'] : (int) get_current_user_id();
        $entry = [
            'task' => $route['task'] ?? 'user_facing_explanation',
            'requested_task' => $route['requested_task'] ?? 'general',
            'kind' => $route['kind'] ?? 'chat',
            'model' => $route['model'] ?? '',
            'fallback_model' => $route['fallback_model'] ?? '',
            'plan' => $route['plan'] ?? 'free',
            'logged_at' => current_time('mysql'),
        ];

        if ($user_id > 0) {
            $log = get_user_meta($user_id, 'vmo_model_route_log', true);
            if (!is_array($log)) {
                $log = [];
            }
            $log[] = $entry;
            update_user_meta($user_id, 'vmo_model_route_log', array_slice($log, -50));
            return;
        }

        $log = get_option('vmo_model_route_log', []);
        if (!is_array($log)) {
            $log = [];
        }
        $log[] = $entry;
        update_option('vmo_model_route_log', array_slice($log, -50), false);
    }
}

if (!function_exists('vmo_get_model_router')) {
    function vmo_get_model_router() {
        static $router = null;

        if ($router === null) {
            $router = new VMO_Model_Router();
        }

        return $router;
    }
}

if (!function_exists('vmo_get_openai_route')) {
    function vmo_get_openai_route($task_type = 'general', array $context = []) {
        return vmo_get_model_router()->get_route($task_type, $context);
    }
}

if (!function_exists('vmo_get_routed_model')) {
    function vmo_get_routed_model($task_type = 'general', array $context = []) {
        $route = vmo_get_openai_route($task_type, $context);
        return $route['model'] ?? (defined('VMO_OPENAI_MODEL') ? VMO_OPENAI_MODEL : 'gpt-5.5');
    }
}

if (!function_exists('vmo_get_routed_fallback_model')) {
    function vmo_get_routed_fallback_model($task_type = 'general', array $context = []) {
        $route = vmo_get_openai_route($task_type, $context);
        return $route['fallback_model'] ?? null;
    }
}