import logging
import json

_logger = logging.getLogger(__name__)


class AdaptiveEngine:
    """4-phase adaptive learning engine.

    Phase 1: Module-level up/down stepping
    Phase 2: Micro-lesson injection
    Phase 3: Module skipping
    Phase 4: No-progress alerts
    """

    DEFAULT_SETTINGS = {
        'step_up_threshold': 0.85,
        'step_down_threshold': 0.50,
        'micro_lesson_trigger': 2,
        'module_skip_threshold': 0.95,
        'no_progress_alert_days': 3,
        'max_retries': 3,
    }

    @staticmethod
    def get_settings(env, teacher_id=None, entity_id=None):
        """Get adaptive settings for teacher/entity or defaults."""
        Settings = env['encoach.adaptive.settings'].sudo()
        settings = None
        if teacher_id:
            settings = Settings.search([('teacher_id', '=', teacher_id)], limit=1)
        if not settings and entity_id:
            settings = Settings.search([('entity_id', '=', entity_id), ('teacher_id', '=', False)], limit=1)

        if settings:
            return {
                'step_up_threshold': settings.step_up_threshold,
                'step_down_threshold': settings.step_down_threshold,
                'micro_lesson_trigger': settings.micro_lesson_trigger,
                'module_skip_threshold': settings.module_skip_threshold,
                'no_progress_alert_days': settings.no_progress_alert_days,
                'max_retries': settings.max_retries,
            }
        return dict(AdaptiveEngine.DEFAULT_SETTINGS)

    @staticmethod
    def process_checkpoint(env, student_id, course_id, module_id, score, settings=None):
        """Process a module checkpoint and make adaptive decisions."""
        if not settings:
            settings = AdaptiveEngine.DEFAULT_SETTINGS

        Event = env['encoach.adaptive.event'].sudo()
        Module = env['encoach.course.module'].sudo()
        module = Module.browse(module_id)

        decision = None
        signals = []

        signals.append({
            'signal_name': 'checkpoint_score',
            'signal_value': score,
        })

        if score >= settings['step_up_threshold']:
            decision = 'step_up'
            module.write({'status': 'completed'})
            next_module = Module.search([
                ('course_id', '=', course_id),
                ('sequence', '>', module.sequence),
                ('status', '=', 'locked'),
            ], limit=1, order='sequence')
            if next_module:
                next_module.write({'status': 'available'})

        elif score < settings['step_down_threshold']:
            decision = 'step_down'

        else:
            decision = 'continue'
            module.write({'status': 'completed'})
            next_module = Module.search([
                ('course_id', '=', course_id),
                ('sequence', '>', module.sequence),
                ('status', '=', 'locked'),
            ], limit=1, order='sequence')
            if next_module:
                next_module.write({'status': 'available'})

        if score >= settings['module_skip_threshold']:
            skip_modules = Module.search([
                ('course_id', '=', course_id),
                ('sequence', '>', module.sequence),
                ('status', '=', 'locked'),
            ], limit=2, order='sequence')
            for sm in skip_modules:
                sm.write({'status': 'skipped'})
            if skip_modules:
                decision = 'skip_ahead'
                signals.append({'signal_name': 'module_skip', 'signal_value': len(skip_modules)})

        for sig in signals:
            Event.create({
                'student_id': student_id,
                'course_id': course_id,
                'event_type': 'signal',
                'signal_name': sig['signal_name'],
                'signal_value': sig['signal_value'],
            })

        Event.create({
            'student_id': student_id,
            'course_id': course_id,
            'event_type': 'decision',
            'decision': decision,
            'context': json.dumps({'module_id': module_id, 'score': score}),
        })

        return {
            'decision': decision,
            'score': score,
            'signals': signals,
        }

    @staticmethod
    def check_no_progress(env, student_id, course_id, settings=None):
        """Phase 4: Check if student has stalled."""
        if not settings:
            settings = AdaptiveEngine.DEFAULT_SETTINGS

        from datetime import datetime, timedelta
        cutoff = datetime.now() - timedelta(days=settings['no_progress_alert_days'])

        Event = env['encoach.adaptive.event'].sudo()
        recent_events = Event.search_count([
            ('student_id', '=', student_id),
            ('course_id', '=', course_id),
            ('created_at', '>=', cutoff.strftime('%Y-%m-%d %H:%M:%S')),
        ])

        if recent_events == 0:
            Event.create({
                'student_id': student_id,
                'course_id': course_id,
                'event_type': 'signal',
                'signal_name': 'no_progress_alert',
                'signal_value': settings['no_progress_alert_days'],
            })
            return True
        return False
