<?php
/**
 * سودانا — StepController v21
 * Server-Driven Flow Engine
 *
 * الفلسفة: Frontend = renderer فقط. Backend يتحكم في كل خطوة.
 *
 * القواعد:
 *   - كل انتقال يُحقَّق من الـ backend
 *   - لا يمكن تخطي خطوات
 *   - السياق مخزون في DB (source of truth)
 *   - كل request له request_id للـ tracing
 */
class StepController {

    // ══ Flow Definitions ══════════════════════════════════════════
    private static array $flows = [

        'medical_telemedicine_v1' => [
            'version'     => 'v1',
            'description' => 'تشخيص طبي عن بعد',
            'steps'       => [
                'intake_symptoms' => [
                    'type'      => 'input',
                    'prompt_ar' => 'مرحباً، أنا هنا لمساعدتك. صِف ما تشعر به الآن بالتفصيل.',
                    'required'  => true,
                    'next'      => 'structured_questions',
                ],
                'structured_questions' => [
                    'type'      => 'form',
                    'prompt_ar' => 'لأساعدك بشكل أفضل، يرجى الإجابة:',
                    'fields'    => [
                        ['key'=>'duration',   'label'=>'منذ متى تعاني من هذه الأعراض؟', 'type'=>'select',
                         'options'=>['يوم واحد','2-3 أيام','أسبوع','أكثر من أسبوع']],
                        ['key'=>'severity',   'label'=>'درجة الألم أو الانزعاج (1-10)?', 'type'=>'number', 'min'=>1,'max'=>10],
                        ['key'=>'temperature','label'=>'هل لديك حرارة؟', 'type'=>'bool'],
                        ['key'=>'age',        'label'=>'العمر', 'type'=>'number'],
                        ['key'=>'chronic',    'label'=>'هل لديك أمراض مزمنة؟', 'type'=>'text', 'required'=>false],
                    ],
                    'next' => 'triage',
                ],
                'triage' => [
                    'type'    => 'system',  // server computes triage level
                    'handler' => 'computeTriage',
                    'next'    => 'specialization_mapping',
                ],
                'specialization_mapping' => [
                    'type'    => 'system',
                    'handler' => 'mapSpecialization',
                    'next'    => 'pde_decision',
                ],
                'pde_decision' => [
                    'type'    => 'system',
                    'handler' => 'runPDE',
                    'next'    => [
                        'low'       => 'ai_guidance',
                        'medium'    => 'providers',
                        'high'      => 'providers',
                        'emergency' => 'emergency_alert',
                    ],
                ],
                'ai_guidance' => [
                    'type'      => 'ai_response',
                    'prompt_ar' => 'إرشادات صحية عامة (منخفض الخطورة)',
                    'next'      => 'providers',  // still show providers optionally
                    'optional_provider' => true,
                ],
                'emergency_alert' => [
                    'type'      => 'emergency',
                    'prompt_ar' => '🚨 حالتك تستدعي تدخلاً طارئاً — اتصل 999 فوراً',
                    'block_booking' => true,
                    'terminal'  => false,
                    'next'      => null,
                ],
                'providers' => [
                    'type'      => 'provider_list',
                    'prompt_ar' => 'اختر الطبيب المناسب لك:',
                    'next'      => 'booking',
                ],
                'booking' => [
                    'type'      => 'booking_form',
                    'prompt_ar' => 'احجز موعدك',
                    'fields'    => [
                        ['key'=>'consultation_type','label'=>'نوع الاستشارة','type'=>'select',
                         'options'=>['chat'=>'محادثة نصية','video'=>'مكالمة مرئية','clinic'=>'زيارة عيادة']],
                        ['key'=>'booking_date','label'=>'التاريخ','type'=>'date'],
                        ['key'=>'booking_time','label'=>'الوقت','type'=>'time'],
                        ['key'=>'notes','label'=>'ملاحظات للطبيب','type'=>'textarea','required'=>false],
                    ],
                    'next' => 'consultation',
                ],
                'consultation' => [
                    'type'      => 'tele_session',
                    'prompt_ar' => 'جلسة الاستشارة مع الطبيب',
                    'next'      => 'prescription',
                ],
                'prescription' => [
                    'type'      => 'prescription_form',
                    'prompt_ar' => 'الوصفة الطبية (يكملها الطبيب)',
                    'next'      => 'follow_up',
                ],
                'follow_up' => [
                    'type'      => 'follow_up',
                    'prompt_ar' => 'المتابعة بعد 48 ساعة',
                    'terminal'  => true,
                ],
            ],
        ],

        // ══ FAMILY SUPPORT FLOW ═════════════════════════════════════
        'family_support_v1' => [
            'version'     => 'v1',
            'description' => 'دعم الأسرة والصحة المنزلية',
            'steps'       => [
                'family_concern' => [
                    'type'      => 'input',
                    'prompt_ar' => 'ما هو استفساركم المتعلق بالأسرة؟ (صحة، تربية، رعاية...)',
                    'next'      => 'triage',
                ],
                'triage' => [
                    'type'      => 'ai_response',
                    'prompt_ar' => 'أقيّم الموضوع وأوجهك للمساعدة المناسبة',
                    'next'      => 'providers',
                ],
                'providers' => [
                    'type'           => 'provider_list',
                    'prompt_ar'      => 'متخصصو الأسرة والصحة المنزلية:',
                    'specialization' => 'family',
                    'next'           => 'booking',
                ],
                'booking' => [
                    'type'      => 'booking_form',
                    'prompt_ar' => 'احجز استشارة أسرة',
                    'fields'    => [
                        ['key'=>'consult_type','label'=>'نوع الاستشارة','type'=>'select',
                         'options'=>['chat'=>'محادثة','video'=>'مكالمة مرئية']],
                        ['key'=>'booking_date','label'=>'التاريخ','type'=>'date'],
                        ['key'=>'booking_time','label'=>'الوقت','type'=>'time'],
                    ],
                    'next' => 'confirmation',
                ],
                'confirmation' => [
                    'type'      => 'confirmation',
                    'prompt_ar' => 'تم حجز استشارة الأسرة ✅',
                    'terminal'  => true,
                ],
            ],
        ],

        'service_booking_v1' => [
            'version'     => 'v1',
            'description' => 'حجز خدمة عامة',
            'steps'       => [
                'service_type' => [
                    'type'      => 'input',
                    'prompt_ar' => 'ما نوع الخدمة التي تحتاجها؟',
                    'next'      => 'providers',
                ],
                'providers' => [
                    'type'      => 'provider_list',
                    'prompt_ar' => 'اختر مزود الخدمة:',
                    'next'      => 'booking',
                ],
                'booking' => [
                    'type'      => 'booking_form',
                    'prompt_ar' => 'احجز موعدك',
                    'next'      => 'confirmation',
                ],
                'confirmation' => [
                    'type'      => 'confirmation',
                    'prompt_ar' => 'تم الحجز بنجاح ✅',
                    'terminal'  => true,
                ],
            ],
        ],


        // ══ LEGAL CONSULTATION FLOW (FIXED v22) ══════════════════════
        'legal_consultation_v1' => [
            'version'     => 'v1',
            'description' => 'استشارة قانونية',
            'steps'       => [
                'legal_issue' => [
                    'type'      => 'form',
                    'prompt_ar' => 'ما نوع الاستشارة القانونية التي تحتاجها؟',
                    'fields'    => [
                        ['key'=>'legal_issue_type','label'=>'نوع القضية','type'=>'select',
                         'options'=>['عقد تجاري','نزاع قانوني','قضية عمالية','قانون الأسرة','استشارة عامة']],
                    ],
                    'next' => 'legal_details',
                ],
                'legal_details' => [
                    'type'      => 'form',
                    'prompt_ar' => 'اشرح موقفك القانوني بإيجاز',
                    'fields'    => [
                        ['key'=>'legal_description','label'=>'تفاصيل الموقف','type'=>'textarea'],
                        ['key'=>'legal_urgency','label'=>'مدى الإلحاح','type'=>'select',
                         'options'=>['عاجل جداً (خلال 24 ساعة)','هذا الأسبوع','لا يوجد ضغط وقت']],
                    ],
                    'next' => 'providers',
                ],
                'providers' => [
                    'type'            => 'provider_list',
                    'prompt_ar'       => 'محامون موثّقون متاحون:',
                    'specialization'  => 'legal',
                    'next'            => 'booking',
                ],
                'booking' => [
                    'type'      => 'booking_form',
                    'prompt_ar' => 'احجز استشارتك القانونية',
                    'fields'    => [
                        ['key'=>'consultation_type','label'=>'نوع الاستشارة','type'=>'select',
                         'options'=>['chat'=>'محادثة نصية','video'=>'مكالمة مرئية','clinic'=>'مكتب المحامي']],
                        ['key'=>'booking_date','label'=>'التاريخ','type'=>'date'],
                        ['key'=>'booking_time','label'=>'الوقت','type'=>'time'],
                        ['key'=>'notes','label'=>'ملاحظات','type'=>'textarea','required'=>false],
                    ],
                    'next' => 'confirmation',
                ],
                'confirmation' => [
                    'type'      => 'confirmation',
                    'prompt_ar' => 'تم حجز استشارتك القانونية ✅',
                    'terminal'  => true,
                ],
            ],
        ],

        // ══ BUSINESS CONSULTING FLOW (FIXED v22) ══════════════════════
        'business_consulting_v1' => [
            'version'     => 'v1',
            'description' => 'استشارة أعمال',
            'steps'       => [
                'biz_need' => [
                    'type'      => 'form',
                    'prompt_ar' => 'ما نوع الاستشارة التجارية التي تحتاجها؟',
                    'fields'    => [
                        ['key'=>'biz_type','label'=>'نوع الاستشارة','type'=>'select',
                         'options'=>['تقنية وذكاء اصطناعي','استثمار وتمويل','زراعة وموارد','هندسة ومقاولات','فينتك وCRM','استراتيجية نمو']],
                    ],
                    'next' => 'biz_details',
                ],
                'biz_details' => [
                    'type'      => 'form',
                    'prompt_ar' => 'صِف مشروعك أو احتياجك التجاري',
                    'fields'    => [
                        ['key'=>'biz_description','label'=>'تفاصيل المشروع','type'=>'textarea'],
                        ['key'=>'biz_budget','label'=>'الميزانية التقريبية','type'=>'select',
                         'options'=>['أقل من 5,000 SDG','5,000 - 15,000 SDG','أكثر من 15,000 SDG']],
                    ],
                    'next' => 'providers',
                ],
                'providers' => [
                    'type'           => 'provider_list',
                    'prompt_ar'      => 'مستشارون أعمال متاحون:',
                    'specialization' => 'enterprise_services',
                    'next'           => 'booking',
                ],
                'booking' => [
                    'type'      => 'booking_form',
                    'prompt_ar' => 'احجز استشارتك التجارية',
                    'fields'    => [
                        ['key'=>'consultation_type','label'=>'نوع الاستشارة','type'=>'select',
                         'options'=>['chat'=>'محادثة نصية','video'=>'مكالمة مرئية']],
                        ['key'=>'booking_date','label'=>'التاريخ','type'=>'date'],
                        ['key'=>'booking_time','label'=>'الوقت','type'=>'time'],
                        ['key'=>'notes','label'=>'ملاحظات','type'=>'textarea','required'=>false],
                    ],
                    'next' => 'confirmation',
                ],
                'confirmation' => [
                    'type'      => 'confirmation',
                    'prompt_ar' => 'تم حجز استشارتك التجارية ✅',
                    'terminal'  => true,
                ],
            ],
        ],
        // ── CORPORATE SOLUTIONS FLOW ──────────────────────────────
        'corporate_solutions_v1' => [
            'version'     => 'v1',
            'description' => 'حلول الشركات — 5 مراحل',
            'steps'       => [
                'org_profile' => [
                    'type'      => 'redirect',
                    'prompt_ar' => 'سنوجهك لنموذج حلول الشركات الكامل',
                    'redirect'  => '/app/corporate-solutions.php',
                    'next'      => null,
                ],
            ],
        ],


        // ══ ENGINEERING CONSULTING FLOW (NEW v22) ═════════════════════
        'engineering_consulting_v1' => [
            'version'     => 'v1',
            'description' => 'استشارة هندسية',
            'steps'       => [
                'eng_need' => [
                    'type'      => 'form',
                    'prompt_ar' => 'ما نوع الاستشارة الهندسية؟',
                    'fields'    => [
                        ['key'=>'eng_type','label'=>'التخصص','type'=>'select',
                         'options'=>['هندسة مدنية','هندسة كهربائية','هندسة ميكانيكية','مقاولات','استشارة عامة']],
                        ['key'=>'eng_description','label'=>'وصف المشروع','type'=>'textarea'],
                    ],
                    'next' => 'providers',
                ],
                'providers' => [
                    'type'           => 'provider_list',
                    'prompt_ar'      => 'مهندسون موثّقون متاحون:',
                    'specialization' => 'engineering',
                    'next'           => 'booking',
                ],
                'booking' => [
                    'type'      => 'booking_form',
                    'prompt_ar' => 'احجز استشارتك الهندسية',
                    'fields'    => [
                        ['key'=>'consultation_type','label'=>'نوع الاستشارة','type'=>'select',
                         'options'=>['video'=>'مكالمة مرئية','clinic'=>'زيارة ميدانية']],
                        ['key'=>'booking_date','label'=>'التاريخ','type'=>'date'],
                        ['key'=>'booking_time','label'=>'الوقت','type'=>'time'],
                    ],
                    'next' => 'confirmation',
                ],
                'confirmation' => [
                    'type'     => 'confirmation',
                    'prompt_ar'=> 'تم حجز استشارتك الهندسية ✅',
                    'terminal' => true,
                ],
            ],
        ],

        // ══ AGRICULTURE CONSULTING FLOW (NEW v22) ═════════════════════
        'agriculture_consulting_v1' => [
            'version'     => 'v1',
            'description' => 'استشارة زراعية',
            'steps'       => [
                'agr_need' => [
                    'type'      => 'form',
                    'prompt_ar' => 'ما نوع الاستشارة الزراعية؟',
                    'fields'    => [
                        ['key'=>'agr_type','label'=>'التخصص','type'=>'select',
                         'options'=>['زراعة محاصيل','تربية حيوانات','ري وموارد مياه','زراعة عضوية','استشارة عامة']],
                        ['key'=>'agr_description','label'=>'وصف الاحتياج','type'=>'textarea'],
                    ],
                    'next' => 'providers',
                ],
                'providers' => [
                    'type'           => 'provider_list',
                    'prompt_ar'      => 'خبراء زراعيون موثّقون:',
                    'specialization' => 'agriculture',
                    'next'           => 'booking',
                ],
                'booking' => [
                    'type'      => 'booking_form',
                    'prompt_ar' => 'احجز استشارتك الزراعية',
                    'fields'    => [
                        ['key'=>'consultation_type','label'=>'نوع الاستشارة','type'=>'select',
                         'options'=>['video'=>'مكالمة مرئية','clinic'=>'زيارة ميدانية']],
                        ['key'=>'booking_date','label'=>'التاريخ','type'=>'date'],
                        ['key'=>'booking_time','label'=>'الوقت','type'=>'time'],
                    ],
                    'next' => 'confirmation',
                ],
                'confirmation' => [
                    'type'     => 'confirmation',
                    'prompt_ar'=> 'تم حجز استشارتك الزراعية ✅',
                    'terminal' => true,
                ],
            ],
        ],

        // ══ BUSINESS PLAN FLOW ════════════════════════════════════════
        'business_plan_v1' => [
            'version'     => 'v1',
            'description' => 'بناء خطة عمل',
            'steps'       => [
                'idea_input'      => ['type'=>'input',       'prompt_ar'=>'صِف فكرتك التجارية', 'next'=>'market_analysis'],
                'market_analysis' => ['type'=>'ai_response', 'prompt_ar'=>'تحليل السوق',         'next'=>'bde_generate'],
                'bde_generate'    => ['type'=>'bde_form',    'prompt_ar'=>'توليد الوثيقة',        'next'=>'review'],
                'review'          => ['type'=>'confirmation', 'terminal'=>true],
            ],
        ],
    ];

    // ══ Start Flow ════════════════════════════════════════════════
    public static function start(string $flowId, ?int $userId, array $initialContext = []): array {
        if (!isset(self::$flows[$flowId])) {
            return ['error' => 'flow_not_found', 'message' => "Flow '$flowId' غير موجود"];
        }

        $flow      = self::$flows[$flowId];
        $sessionId = bin2hex(random_bytes(16));
        $firstStep = array_key_first($flow['steps']);
        $progress  = self::getProgress($flowId, $firstStep);

        // Store in DB (source of truth)
        try {
            db()->prepare(
                "INSERT INTO flow_sessions
                 (session_id, user_id, flow_id, flow_version, current_step, context_data, status)
                 VALUES (?,?,?,?,'initial',?,  'active')"
            )->execute([
                $sessionId,
                $userId,
                $flowId,
                $flow['version'],
                json_encode(array_merge($initialContext, [
                    '_flow_id'   => $flowId,
                    '_started'   => date('c'),
                    '_request_id'=> uniqid('req_', true),
                ]), JSON_UNESCAPED_UNICODE),
            ]);
        } catch (Throwable $e) {
            error_log('[StepController::start] DB error: ' . $e->getMessage());
        }

        // Process first step
        $result = self::processStep($sessionId, $flowId, $firstStep, [], $userId);

        return array_merge([
            'success'    => true,
            'session_id' => $sessionId,
            'flow_id'    => $flowId,
            'version'    => $flow['version'],
            'progress'   => $progress,
        ], $result);
    }

    // ══ Advance Flow ══════════════════════════════════════════════
    public static function next(string $sessionId, array $input, ?int $userId): array {
        $session = self::loadSession($sessionId);
        if (!$session) {
            return ['error' => 'session_not_found', 'message' => 'الجلسة غير موجودة أو انتهت'];
        }

        if ($session['status'] !== 'active') {
            return ['error' => 'session_ended', 'message' => 'الجلسة انتهت'];
        }

        $flowId      = $session['flow_id'];
        $currentStep = $session['current_step'];
        $flow        = self::$flows[$flowId] ?? null;

        if (!$flow || !isset($flow['steps'][$currentStep])) {
            return ['error' => 'invalid_step', 'message' => "الخطوة '$currentStep' غير موجودة"];
        }

        $stepDef = $flow['steps'][$currentStep];
        $context = $session['context_data'] ?? [];

        // Validate input for current step
        $validation = self::validateStepInput($stepDef, $input);
        if (!$validation['valid']) {
            return ['error' => 'validation_failed', 'message' => $validation['message'], 'fields' => $validation['fields'] ?? []];
        }

        // Merge input into context
        $context = array_merge($context, $input, ['_last_step' => $currentStep]);

        // Determine next step
        $nextStep = self::resolveNextStep($stepDef, $context, $flowId, $currentStep);

        if (!$nextStep) {
            // ── PART 5: abandonment signal if session ends before booking ──
            if (empty($context['booking_id'])) {
                GrowthBrain::observe('flow.abandoned', [
                    'step'    => $currentStep,
                    'service' => $context['service_type'] ?? null,
                ]);
            }
            self::completeSession($sessionId, $context);
            return ['success'=>true,'completed'=>true,'message'=>'تم اكتمال الجلسة بنجاح',
                    'progress'=>['current'=>10,'total'=>10,'pct'=>100,'label'=>'اكتمل ✅']];
        }

        // Log transition
        self::logTransition($sessionId, $currentStep, $nextStep, $input);

        // ── PHASE 2 INJECTION ─────────────────────────────────────
        // Fire booking.completed exactly once: after user submits booking form.
        // Condition: step is 'booking' AND booking_id exists in context.
        // Zero impact on existing flow logic — emit is fire-and-forget.
        if ($currentStep === 'booking' && in_array($nextStep, ['consultation', 'confirmation'])) {
            EventBus::emit('booking.completed', [
                'user_id'     => $userId,
                'provider_id' => $context['provider_id'] ?? null,
                'booking_id'  => $context['booking_id']  ?? null,
                'service'     => $context['service_type'] ?? $context['sector'] ?? 'medical',
            ]);
        }

        // Update session
        self::updateSession($sessionId, $nextStep, $context);

        // Process new step
        $progress = self::getProgress($flowId, $nextStep);
        $result   = self::processStep($sessionId, $flowId, $nextStep, $context, $userId);

        return array_merge(['success'=>true, 'previous_step'=>$currentStep, 'progress'=>$progress], $result);
    }

    // ══ Step Processing ───────────────────────────────────────────
    private static function processStep(string $sessionId, string $flowId, string $stepName, array $context, ?int $userId): array {
        $flow    = self::$flows[$flowId];
        $stepDef = $flow['steps'][$stepName] ?? null;

        if (!$stepDef) return ['error'=>'step_not_found'];

        $base = [
            'step'      => $stepName,
            'type'      => $stepDef['type'],
            'prompt'    => $stepDef['prompt_ar'] ?? '',
            'fields'    => $stepDef['fields'] ?? null,
            'terminal'  => $stepDef['terminal'] ?? false,
            'progress'  => self::getProgress($flowId, $stepName),
        ];

        switch ($stepDef['type']) {

            case 'system':
                return self::handleSystemStep($stepDef, $context, $sessionId, $flowId, $stepName, $userId, $base);

            case 'emergency':
                return array_merge($base, [
                    'emergency'     => true,
                    'block_booking' => true,
                    'cta'           => ['label'=>'اتصل 999 الآن','url'=>'tel:999','icon'=>'🚨'],
                    'actions'       => [['label'=>'🚨 اتصل 999 فوراً','url'=>'tel:999']],
                ]);

            case 'provider_list':
                // v22: read specialization from step definition as fallback
                $specialization = $context['specialization'] ?? $stepDef['specialization'] ?? null;
                $providers      = self::fetchProviders($specialization, $userId);
                return array_merge($base, [
                    'providers'  => $providers,
                    'empty_state'=> empty($providers) ? ['message'=>'لا يوجد أطباء متاحون حالياً','cta'=>'انضم كطبيب'] : null,
                ]);

            case 'ai_response':
                $answer = self::getAIGuidance($context);
                return array_merge($base, ['answer'=>$answer,'source'=>'ai_guided']);

            case 'tele_session':
                $bookingId = $context['booking_id'] ?? null;
                $sessionData = $bookingId ? self::initTeleSession($bookingId, $userId, $context) : [];
                return array_merge($base, $sessionData);

            case 'prescription_form':
                return array_merge($base, [
                    'doctor_only' => true,
                    'message'     => 'هذه الخطوة تُكمَل من قِبَل الطبيب فقط',
                ]);

            case 'follow_up':
                return array_merge($base, [
                    'schedule' => date('Y-m-d', strtotime('+2 days')),
                    'message'  => 'سنتواصل معك بعد 48 ساعة للمتابعة',
                ]);

            default:
                return $base;
        }
    }

    // ══ System Step Handlers ──────────────────────────────────────
    private static function handleSystemStep(array $def, array $ctx, string $sid, string $fid, string $step, ?int $uid, array $base): array {
        switch ($def['handler'] ?? '') {

            case 'computeTriage':
                $level = self::computeTriage($ctx);
                $ctx['triage_level'] = $level;
                // MANDATORY: create medical case after triage, before provider matching
                if (empty($ctx['medical_case_id'])) {
                    $caseId = self::createMedicalCase($sid, $uid, $ctx);
                    if ($caseId) $ctx['medical_case_id'] = $caseId;
                }
                self::updateSession($sid, $step, $ctx);
                return array_merge($base, ['triage_level'=>$level,'auto_advance'=>true]);

            case 'mapSpecialization':
                $spec = self::mapSpecialization($ctx);
                $ctx['specialization'] = $spec;
                // Update medical case with specialization
                if (!empty($ctx['medical_case_id'])) {
                    self::updateMedicalCase($ctx['medical_case_id'], ['specialization'=>$spec]);
                }
                self::updateSession($sid, $step, $ctx);
                return array_merge($base, ['specialization'=>$spec,'auto_advance'=>true]);

            case 'runPDE':
                $decision = self::runPDE($ctx);
                $ctx['pde_decision'] = $decision;
                self::updateSession($sid, $step, $ctx);
                return array_merge($base, ['decision'=>$decision,'auto_advance'=>true]);
        }
        return $base;
    }

    // ── Triage Engine (deterministic — no AI) ────────────────────
    private static function computeTriage(array $ctx): string {
        $severity    = (int)($ctx['severity'] ?? 5);
        $symptoms    = strtolower($ctx['intake_symptoms'] ?? '');
        $duration    = $ctx['duration'] ?? '';
        $hasTemp     = !empty($ctx['temperature']);

        // Emergency patterns (always override)
        $emergencyPatterns = [
            'فقدان وعي','تشنج','ضيق تنفس شديد','نزيف شديد','ألم صدر شديد',
            'نوبة قلبية','جلطة','اختناق','سكتة',
        ];
        foreach ($emergencyPatterns as $p) {
            if (mb_strpos($symptoms, $p) !== false) return 'emergency';
        }

        // Scoring (deterministic)
        $score = 0;
        $score += min($severity * 10, 100);
        if ($hasTemp) $score += 15;
        if (str_contains($duration, 'أكثر من أسبوع')) $score += 20;
        if (str_contains($duration, 'أسبوع')) $score += 10;
        if (preg_match('/ألم.*قلب|ضغط.*صدر|صعوبة.*تنفس/u', $symptoms)) $score += 30;

        if ($score >= 80) return 'high';
        if ($score >= 50) return 'medium';
        return 'low';
    }

    // ── Specialization Mapping (deterministic) ───────────────────
    private static function mapSpecialization(array $ctx): string {
        $symptoms = strtolower($ctx['intake_symptoms'] ?? '');
        $map = [
            'قلب|صدر|ضيق|نبض'       => 'cardiology',
            'جلد|بشرة|حكة|طفح'       => 'dermatology',
            'أطفال|رضيع|طفل|ولد|بنت' => 'pediatrics',
            'عين|بصر|رؤية'           => 'ophthalmology',
            'أسنان|ضرس|لثة'          => 'dentistry',
            'نفس|قلق|اكتئاب|توتر'    => 'psychiatry',
            'عظام|مفاصل|كسر'         => 'orthopedics',
            'معدة|كبد|هضم|بطن'       => 'gastroenterology',
        ];
        foreach ($map as $pattern => $spec) {
            if (preg_match("/$pattern/u", $symptoms)) return $spec;
        }
        return 'general_practice';
    }

    // ── PDE Integration ───────────────────────────────────────────
    private static function runPDE(array $ctx): string {
        return $ctx['triage_level'] ?? 'low';
    }

    // ── Resolve Next Step ─────────────────────────────────────────
    private static function resolveNextStep(array $stepDef, array $ctx, string $flowId, string $currentStep): ?string {
        $next = $stepDef['next'] ?? null;
        if (is_null($next)) return null;

        // Terminal check
        if (!empty($stepDef['terminal'])) return null;

        // Router (for system steps with multiple next options)
        if (is_array($next)) {
            $decision = $ctx['pde_decision'] ?? $ctx['triage_level'] ?? null;
            return $next[$decision] ?? $next['low'] ?? array_values($next)[0];
        }

        return $next;
    }

    // ── Validate Step Input ───────────────────────────────────────
    private static function validateStepInput(array $stepDef, array $input): array {
        if ($stepDef['type'] === 'system') return ['valid'=>true];

        $fields  = $stepDef['fields'] ?? [];
        $errors  = [];

        foreach ($fields as $field) {
            $required = $field['required'] ?? true;
            $key      = $field['key'] ?? '';
            if ($required && empty($input[$key])) {
                $errors[] = $field['label'] ?? $key;
            }
        }

        // For input type, just check it's not empty
        if ($stepDef['type'] === 'input' && empty($input)) {
            // Allow — input may be in other field
        }

        return ['valid' => empty($errors), 'message' => implode('، ', $errors) ?: '', 'fields' => $errors];
    }

    // ── DB Helpers ────────────────────────────────────────────────
    private static function loadSession(string $sessionId): ?array {
        try {
            $st = db()->prepare("SELECT * FROM flow_sessions WHERE session_id=? AND status='active' LIMIT 1");
            $st->execute([$sessionId]);
            $row = $st->fetch();
            if (!$row) return null;
            $row['context_data'] = json_decode($row['context_data'] ?? '{}', true) ?: [];
            return $row;
        } catch (Throwable $e) {
            error_log('[StepController::loadSession] ' . $e->getMessage());
            return null;
        }
    }

    private static function updateSession(string $sessionId, string $step, array $context): void {
        try {
            db()->prepare("UPDATE flow_sessions SET current_step=?, context_data=?, updated_at=NOW() WHERE session_id=?")
               ->execute([$step, json_encode($context, JSON_UNESCAPED_UNICODE), $sessionId]);
        } catch (Throwable $e) {
            error_log('[StepController::updateSession] ' . $e->getMessage());
        }
    }

    private static function completeSession(string $sessionId, array $context): void {
        try {
            db()->prepare("UPDATE flow_sessions SET status='completed', context_data=?, completed_at=NOW() WHERE session_id=?")
               ->execute([json_encode($context, JSON_UNESCAPED_UNICODE), $sessionId]);
        } catch (Throwable $ignored) {}
    }

    private static function logTransition(string $sessionId, string $from, string $to, array $input): void {
        try {
            db()->prepare("INSERT INTO flow_step_logs (session_id, step_from, step_to, input_data) VALUES (?,?,?,?)")
               ->execute([$sessionId, $from, $to, json_encode($input, JSON_UNESCAPED_UNICODE)]);
        } catch (Throwable $ignored) {}
    }

    // ── Provider Fetch ────────────────────────────────────────────
    // ── Medical Case Lifecycle ────────────────────────────────────
    // MANDATORY: runs after triage, before provider matching
    public static function createMedicalCase(string $sessionId, ?int $userId, array $ctx): int {
        try {
            $db = db();
            $db->prepare(
                "INSERT INTO medical_records (user_id, record_type, title, content, is_private)
                 VALUES (?, 'consultation', ?, ?, 1)"
            )->execute([
                $userId,
                'استشارة طبية — ' . date('Y-m-d H:i'),
                json_encode([
                    'symptoms'       => $ctx['intake_symptoms'] ?? '',
                    'duration'       => $ctx['duration'] ?? '',
                    'severity'       => $ctx['severity'] ?? 5,
                    'triage_level'   => $ctx['triage_level'] ?? 'medium',
                    'specialization' => $ctx['specialization'] ?? 'general_practice',
                    'session_id'     => $sessionId,
                    'created_at'     => date('c'),
                ], JSON_UNESCAPED_UNICODE),
            ]);
            $caseId = (int)$db->lastInsertId();

            // Link case to flow session context
            try {
                $db->prepare(
                    "UPDATE flow_sessions SET context_data = JSON_SET(context_data, '$.medical_case_id', ?)
                     WHERE session_id = ?"
                )->execute([$caseId, $sessionId]);
            } catch (Throwable $ignored) {}

            return $caseId;
        } catch (Throwable $e) {
            error_log('[StepController::createMedicalCase] ' . $e->getMessage());
            return 0;
        }
    }

    public static function updateMedicalCase(int $caseId, array $updates): void {
        try {
            $content = json_encode($updates, JSON_UNESCAPED_UNICODE);
            db()->prepare(
                "UPDATE medical_records SET content = JSON_MERGE_PATCH(content, ?) WHERE id = ?"
            )->execute([$content, $caseId]);
        } catch (Throwable $e) {
            error_log('[StepController::updateMedicalCase] ' . $e->getMessage());
        }
    }

    public static function closeMedicalCase(int $caseId, array $outcome): void {
        try {
            db()->prepare(
                "UPDATE medical_records SET
                 content = JSON_SET(content, '$.closed_at', ?, '$.outcome', ?),
                 is_private = 1
                 WHERE id = ?"
            )->execute([date('c'), json_encode($outcome, JSON_UNESCAPED_UNICODE), $caseId]);
        } catch (Throwable $e) {
            error_log('[StepController::closeMedicalCase] ' . $e->getMessage());
        }
    }

    private static function fetchProviders(?string $specialization, ?int $userId): array {
        try {
            $typeMap = [
                // Medical specialties
                'cardiology'          => ['doctor'],
                'dermatology'         => ['doctor'],
                'pediatrics'          => ['doctor'],
                'general_practice'    => ['doctor'],
                'psychiatry'          => ['doctor','service_provider'],
                'gynecology'          => ['doctor'],
                'orthopedics'         => ['doctor'],
                'neurology'           => ['doctor'],
                // Business & Technology
                'business_technology' => ['service_provider'],
                'business_fintech'    => ['service_provider'],
                'enterprise_services' => ['service_provider'],
                'engineering_business'=> ['service_provider'],
                // Legal
                'legal'               => ['lawyer','service_provider'],
                // Engineering & Services
                'engineering'         => ['service_provider'],
                'agriculture'         => ['service_provider'],
                // Fallback
                'general'             => ['doctor','lawyer','service_provider'],
            ];
            $types  = $typeMap[$specialization] ?? ['doctor'];
            $in     = implode(',', array_fill(0, count($types), '?'));

            // FIX 2: listing_boost ORDER — premium first, then pro, then basic, then by rating
            // Join with provider_plans to get listing_boost for monetization enforcement
            $sql = "SELECT u.id, u.name, u.provider_specialty, u.avg_rating, u.state, u.city,
                           COALESCE(u.provider_plan, 'basic') AS provider_plan,
                           COALESCE(pp.listing_boost, 0) AS listing_boost
                    FROM users u
                    LEFT JOIN provider_plans pp ON pp.plan_key = u.provider_plan
                    WHERE u.user_type IN ($in)
                    AND u.provider_verified = 1
                    ORDER BY
                        COALESCE(pp.listing_boost, 0) DESC,  -- premium (2) → pro (1) → basic (0)
                        u.avg_rating DESC,
                        u.id ASC
                    LIMIT 8";

            $st = db()->prepare($sql);
            $st->execute($types);
            return $st->fetchAll();
        } catch (Throwable $e) {
            error_log('[StepController::fetchProviders] ' . $e->getMessage());
            return [];
        }
    }

    // ── Tele Session Init ─────────────────────────────────────────
    private static function fetchLegalProviders(?int $userId): array {
        return self::fetchProviders('legal', $userId);
    }

    private static function fetchBusinessProviders(?int $userId): array {
        // Returns best-matched business/non-medical provider based on context
        $specializations = ['business_technology','business_fintech','agriculture',
                            'engineering_business','enterprise_services','engineering'];
        $results = [];
        foreach ($specializations as $spec) {
            $providers = self::fetchProviders($spec, $userId);
            $results = array_merge($results, $providers);
        }
        // De-duplicate, sort by listing_boost
        $seen = [];
        $unique = [];
        foreach ($results as $p) {
            if (!isset($seen[$p['id']])) {
                $seen[$p['id']] = true;
                $unique[] = $p;
            }
        }
        usort($unique, fn($a,$b) => ($b['listing_boost']??0) <=> ($a['listing_boost']??0));
        return array_slice($unique, 0, 5);
    }


    private static function initTeleSession(int $bookingId, ?int $userId, array $ctx): array {
        try {
            $token = bin2hex(random_bytes(20));
            $type  = $ctx['consultation_type'] ?? 'chat';
            $db    = db();
            $db->prepare(
                "INSERT INTO tele_sessions (booking_id, user_id, provider_id, session_type, session_token, status)
                 SELECT ?, user_id, provider_id, ?, ?, 'waiting' FROM bookings WHERE id=? LIMIT 1"
            )->execute([$bookingId, $type, $token, $bookingId]);
            $sessionId = (int)$db->lastInsertId();
            return ['tele_session_id'=>$sessionId,'session_token'=>$token,'session_type'=>$type];
        } catch (Throwable $e) {
            return [];
        }
    }

    // ── AI Guidance (low-risk only) ───────────────────────────────
    private static function getAIGuidance(array $ctx): string {
        $symptoms = $ctx['intake_symptoms'] ?? '';
        return "⚕️ بناءً على ما ذكرت، هذه إرشادات عامة:\n\n"
             . "• اشرب كميات كافية من الماء\n"
             . "• الراحة الكافية تساعد على التعافي\n"
             . "• راقب الأعراض للـ 24 ساعة القادمة\n\n"
             . "⚕️ هذه معلومات إرشادية فقط — لا تُغني عن تشخيص الطبيب.\n"
             . "إذا اشتدت الأعراض أو استمرت → راجع الطبيب فوراً.";
    }

    // ── Public Helpers ────────────────────────────────────────────
    public static function getAvailableFlows(): array {
        return array_map(fn($f) => [
            'id'          => array_key_first([array_key_first($f)=>'x']),
            'description' => $f['description'] ?? '',
            'version'     => $f['version'] ?? 'v1',
            'steps_count' => count($f['steps']),
        ], self::$flows);
    }

    public static function getSessionStatus(string $sessionId): ?array {
        return self::loadSession($sessionId);
    }

    // ── FIX 1: Progress Calculation ────────────────────────────────
    public static function getProgress(string $flowId, string $currentStep): array {
        $flow  = self::$flows[$flowId] ?? null;
        if (!$flow) return ['current'=>1,'total'=>1,'pct'=>0,'label'=>'الخطوة 1/1'];

        $steps   = array_keys($flow['steps']);
        // Filter out system steps for display count
        $displaySteps = array_filter($steps, fn($s) => !in_array(
            $flow['steps'][$s]['type'] ?? '', ['system']
        ));
        $displaySteps = array_values($displaySteps);
        $total   = count($displaySteps);
        $current = max(1, array_search($currentStep, $displaySteps) + 1);
        $pct     = (int)round($current / max(1, $total) * 100);

        // Arabic step names for display
        $stepNames = [
            'intake_symptoms'       => 'وصف الأعراض',
            'structured_questions'  => 'أسئلة تفصيلية',
            'providers'             => 'اختيار الطبيب',
            'booking'               => 'الحجز',
            'consultation'          => 'الاستشارة',
            'prescription'          => 'الوصفة الطبية',
            'follow_up'             => 'المتابعة',
            'triage'                => 'التقييم',
            'service_type'          => 'نوع الخدمة',
            'confirmation'          => 'التأكيد',
            'idea_input'            => 'فكرة المشروع',
            'market_analysis'       => 'تحليل السوق',
            'bde_generate'          => 'توليد الوثيقة',
            'review'                => 'المراجعة',
            // Legal
            'legal_issue'           => 'نوع القضية',
            'legal_details'         => 'تفاصيل الموقف',
            // Business
            'biz_need'              => 'نوع الاستشارة',
            'biz_details'           => 'تفاصيل المشروع',
            // Engineering
            'eng_need'              => 'نوع الهندسة',
            // Agriculture
            'agr_need'              => 'نوع الزراعة',
        ];

        $stepLabel = $stepNames[$currentStep] ?? $currentStep;

        return [
            'current'    => $current,
            'total'      => $total,
            'pct'        => $pct,
            'step_name'  => $stepLabel,
            'label'      => "الخطوة {$current} من {$total} — {$stepLabel}",
            'label_en'   => "Step {$current}/{$total}",
            'bar'        => str_repeat('█', (int)($pct/10)) . str_repeat('░', 10-(int)($pct/10)),
        ];
    }
    // ── FAMILY SUPPORT FLOW ─────────────────────────────────────
    private static function runFamilySupport(string $flowId, string $question, int $userId, array $ctx): array {
        // Family support re-uses telemedicine flow with family-specific context
        $ctx['flow_type']      = 'family';
        $ctx['assistant_name'] = 'مساعد الأسرة';
        $ctx['system_context'] = 'family_health_support';
        // Delegate to medical telemedicine with family flag
        return self::runMedicalTelemedicine('medical_telemedicine_v1', $question, $userId, $ctx);
    }


}
