"""Integration tests for learning system.

Tests the complete learning flow including enrollment, progress tracking, and skill improvement.
"""

import pytest
from datetime import datetime, timedelta

from openclaw.learning.models import (
    Course, SkillEffect, SkillType, CourseStatus, CourseProgress
)
from openclaw.learning.courses import (
    create_technical_analysis_course,
    create_risk_management_course,
    create_market_psychology_course,
    create_advanced_strategy_course,
    get_course_by_id,
)
from openclaw.learning.manager import CourseManager
from openclaw.agents.base import BaseAgent


class TestLearningSystemIntegration:
    """Integration tests for learning system."""

    def test_course_creation(self):
        """Test courses can be created."""
        course = create_technical_analysis_course()

        assert course.course_id == "technical_analysis_101"
        assert course.name == "Technical Analysis Fundamentals"
        assert course.duration_days == 7
        assert course.cost == 500.0
        assert len(course.effects) > 0

    def test_all_courses_created(self):
        """Test all predefined courses are created correctly."""
        courses = [
            create_technical_analysis_course(),
            create_risk_management_course(),
            create_market_psychology_course(),
            create_advanced_strategy_course(),
        ]

        assert len(courses) == 4
        for course in courses:
            assert course.course_id is not None
            assert course.name is not None
            assert course.duration_days > 0

    def test_course_skill_effects(self):
        """Test courses have correct skill effects."""
        tech_course = create_technical_analysis_course()
        assert len(tech_course.effects) > 0

        effect = tech_course.effects[0]
        assert effect.skill_type == SkillType.ANALYSIS
        assert effect.improvement > 0

    def test_risk_management_course(self):
        """Test risk management course specifics."""
        course = create_risk_management_course()

        assert course.duration_days == 5
        assert course.cost == 750.0

        effect = course.effects[0]
        assert effect.skill_type == SkillType.RISK_MANAGEMENT
        assert effect.improvement == 0.20


class TestCourseManagerIntegration:
    """Tests for course manager."""

    def test_course_manager_initialization(self):
        """Test course manager can be initialized."""
        agent = BaseAgent(agent_id="test_student", initial_capital=1000.0)
        manager = CourseManager(agent=agent)

        assert manager.agent == agent
        assert len(manager.active_enrollments) == 0
        assert manager.learning_history.agent_id == "test_student"

    def test_can_enroll_basic_course(self):
        """Test can enroll in basic course."""
        agent = BaseAgent(agent_id="test_student", initial_capital=1000.0)
        manager = CourseManager(agent=agent)

        can_enroll, reason = manager.can_enroll("technical_analysis_101")
        assert can_enroll is True

    def test_enroll_in_course(self):
        """Test enrolling in a course."""
        agent = BaseAgent(agent_id="test_student", initial_capital=1000.0)
        manager = CourseManager(agent=agent)

        success, message = manager.enroll("technical_analysis_101")

        assert success is True
        assert "technical_analysis_101" in manager.active_enrollments

    def test_enrollment_deducts_cost(self):
        """Test that enrolling deducts course cost."""
        agent = BaseAgent(agent_id="test_student", initial_capital=1000.0)
        initial_balance = agent.economic_tracker.get_balance()

        manager = CourseManager(agent=agent)
        course = create_technical_analysis_course()

        manager.enroll(course.course_id)

        # Balance should be deducted
        assert agent.economic_tracker.get_balance() < initial_balance

    def test_is_learning_check(self):
        """Test checking if agent is learning."""
        agent = BaseAgent(agent_id="test_student", initial_capital=1000.0)
        manager = CourseManager(agent=agent)

        # Initially not learning
        assert manager.is_learning() is False

        # Enroll in course
        manager.enroll("technical_analysis_101")

        # Now learning
        assert manager.is_learning() is True

    def test_get_current_learning(self):
        """Test getting current course progress."""
        agent = BaseAgent(agent_id="test_student", initial_capital=1000.0)
        manager = CourseManager(agent=agent)

        # Enroll in course
        manager.enroll("technical_analysis_101")

        current = manager.get_current_learning()
        assert current is not None
        assert current.course_id == "technical_analysis_101"

    def test_update_progress(self):
        """Test updating learning progress."""
        agent = BaseAgent(agent_id="test_student", initial_capital=1000.0)
        manager = CourseManager(agent=agent)

        # Enroll and update progress
        manager.enroll("technical_analysis_101")
        manager.update_progress("technical_analysis_101", 50.0)

        progress = manager.active_enrollments["technical_analysis_101"]
        assert progress.progress_percent == 50.0


class TestCourseProgress:
    """Tests for course progress tracking."""

    def test_progress_start(self):
        """Test starting a course."""
        progress = CourseProgress(
            course_id="test_course",
            agent_id="test_agent",
        )

        progress.start()

        assert progress.status == CourseStatus.IN_PROGRESS
        assert progress.start_time is not None
        assert progress.progress_percent == 0.0

    def test_progress_update(self):
        """Test updating progress."""
        progress = CourseProgress(
            course_id="test_course",
            agent_id="test_agent",
        )
        progress.start()

        progress.update_progress(75.0)

        assert progress.progress_percent == 75.0

    def test_progress_complete(self):
        """Test completing a course."""
        progress = CourseProgress(
            course_id="test_course",
            agent_id="test_agent",
        )
        progress.start()
        progress.complete()

        assert progress.status == CourseStatus.COMPLETED
        assert progress.progress_percent == 100.0
        assert progress.actual_completion is not None


class TestLearningHistory:
    """Tests for learning history."""

    def test_learning_history_record(self):
        """Test recording completed course in history."""
        from openclaw.learning.models import LearningHistory

        history = LearningHistory(agent_id="test_agent")
        course = create_technical_analysis_course()

        start_time = datetime.now() - timedelta(days=7)
        completion_time = datetime.now()

        history.record_completion(course, start_time, completion_time)

        assert len(history.completed_courses) == 1
        assert history.has_completed(course.course_id)
        assert history.total_spent == course.cost

    def test_get_learning_summary(self):
        """Test getting learning summary."""
        from openclaw.learning.models import LearningHistory

        history = LearningHistory(agent_id="test_agent")
        course = create_technical_analysis_course()

        start_time = datetime.now() - timedelta(days=7)
        completion_time = datetime.now()
        history.record_completion(course, start_time, completion_time)

        summary = history.get_summary()

        assert summary["agent_id"] == "test_agent"
        assert summary["courses_completed"] == 1
        assert summary["total_spent"] == course.cost
