"""
Course related routes
"""
from flask import Blueprint, request, make_response
from utils import require_api_key, add_keep_alive, format_api_response, get_db_connection, encrypt_response, create_error_response, format_validation_error, format_not_found_error
from auth.jwt_manager import require_auth, require_user_access
import logging

logger = logging.getLogger(__name__)
from course import course_details_api, m_courses, search
from course.course_inside import course_insid
from course.mentor_profile import mentor_detail_fnc
from course_home import course_home_fnc


course_bp = Blueprint('course', __name__)


@course_bp.route('/course_home', methods=['POST', 'GET'])
@require_api_key
def course_hom():
    response = make_response(course_home_fnc(request))
    return add_keep_alive(response)


@course_bp.route('/search', methods=['POST'])
def search_p():
    response = make_response(search.search_obj(request))
    return add_keep_alive(response)


@course_bp.route('/mentor_detail', methods=['POST','GET'])
@require_api_key
def mentor_det():
    response = make_response(mentor_detail_fnc(request))
    return add_keep_alive(response)


@course_bp.route('/course_details', methods=['POST', 'GET'])
@require_api_key
def course_detail():
    response = make_response(course_details_api.course_details(request))
    return add_keep_alive(response)


@course_bp.route('/my_courses', methods=['POST', 'GET'])
@require_auth
@require_user_access  
def owned_courses():
    response = make_response(m_courses.my_courses(request))
    return add_keep_alive(response)


@course_bp.route('/all_courses', methods=['POST', 'GET'])
@require_api_key
def all_courses():
    response = make_response(m_courses.all_courses(request))
    return add_keep_alive(response)


@course_bp.route('/api/categories', methods=['GET'])
@require_api_key
def get_categories():
    response = make_response(m_courses.get_categories(request))
    return add_keep_alive(response)


@course_bp.route('/api/filter-options', methods=['GET'])
@require_api_key
def get_filter_options():
    response = make_response(m_courses.get_filter_options(request))
    return add_keep_alive(response)


@course_bp.route('/course_inside', methods=['POST', 'GET'])
@require_auth
@require_user_access
def course_insi():
    response = make_response(course_insid(request))
    return add_keep_alive(response)


@course_bp.route('/api/course-topics', methods=['GET'])
@require_api_key

def get_course_topics():
    """Get all topics grouped by courses for a user with hierarchical structure"""
    conn = None
    cursor = None
    try:
        user_id = request.args.get('user_id')
        if not user_id:
            return create_error_response("User ID is required", 400)

        # Use the same connection method as migrate_questions.py
        from database import get_cached_connection
        conn = get_cached_connection()
        if not conn:
            return create_error_response("Database connection failed", 500)
            
        cursor = conn.cursor(dictionary=True)
        
        # Get all courses and their topics that the user is enrolled in with hierarchical structure
        cursor.execute("""
            SELECT 
                c.id as course_id,
                c.title as course_title,
                c.image_url,
                t.id as topic_id,
                t.title as topic_title,
                t.order_sequence,
                t.parent_topic_id,
                t.level,
                t.full_path,
                COUNT(q.id) as question_count
            FROM courses c
            JOIN enrollments e ON c.id = e.course_id AND e.user_id = %s
            LEFT JOIN topics t ON c.id = t.course_id
            LEFT JOIN questions q ON t.id = q.topic_id
            GROUP BY c.id, t.id
            ORDER BY c.title, t.level, t.parent_topic_id, t.order_sequence
        """, (user_id,))
        
        result = cursor.fetchall()
        
        # Group topics by course and build hierarchical structure
        courses_data = {}
        for row in result:
            course_id = row['course_id']
            if course_id not in courses_data:
                courses_data[course_id] = {
                    'course_id': course_id,
                    'course_title': row['course_title'],
                    'thumbnail': row['image_url'],
                    'topics': [],
                    'topic_tree': {}  # For building hierarchy
                }
            
            if row['topic_id']:  # Only add topics that exist
                topic_data = {
                    'topic_id': row['topic_id'],
                    'topic_title': row['topic_title'],
                    'order_sequence': row['order_sequence'],
                    'parent_topic_id': row['parent_topic_id'],
                    'level': row['level'] or 0,
                    'full_path': row['full_path'],
                    'question_count': row['question_count'] or 0,
                    'children': []
                }
                courses_data[course_id]['topic_tree'][row['topic_id']] = topic_data
        
        # Build hierarchical structure for each course
        for course_id in courses_data:
            course_data = courses_data[course_id]
            topic_tree = course_data['topic_tree']
            
            # First, organize topics by their parent-child relationships
            for topic_id, topic in topic_tree.items():
                parent_id = topic['parent_topic_id']
                if parent_id and parent_id in topic_tree:
                    # This is a child topic
                    topic_tree[parent_id]['children'].append(topic)
                else:
                    # This is a root topic (level 0)
                    course_data['topics'].append(topic)
            
            # Sort topics and their children by order_sequence
            def sort_topics(topics_list):
                topics_list.sort(key=lambda x: x['order_sequence'] or 0)
                for topic in topics_list:
                    if topic['children']:
                        sort_topics(topic['children'])
            
            sort_topics(course_data['topics'])
            
            # Remove the temporary topic_tree
            del course_data['topic_tree']
        
        courses_list = list(courses_data.values())
        
        return format_api_response({
            'courses': courses_list,
            'total_courses': len(courses_list)
        })
            
    except Exception as e:
        logger.error(f"Error in get_course_topics: {str(e)}")
        return create_error_response(f"Failed to fetch course topics: {str(e)}")
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()


@course_bp.route('/api/course-topics-qa', methods=['GET'])
@require_api_key

def get_course_topics_qa():
    """Get all topics grouped by courses for a user with Q&A question counts instead of quiz counts"""
    conn = None
    cursor = None
    try:
        user_id = request.args.get('user_id')
        if not user_id:
            return create_error_response("User ID is required", 400)

        # Use the same connection method as migrate_questions.py
        from database import get_cached_connection
        conn = get_cached_connection()
        if not conn:
            return create_error_response("Database connection failed", 500)
            
        cursor = conn.cursor(dictionary=True)
        
        # Get all courses and their topics that the user is enrolled in with Q&A question counts
        cursor.execute("""
            SELECT 
                c.id as course_id,
                c.title as course_title,
                c.image_url,
                t.id as topic_id,
                t.title as topic_title,
                t.order_sequence,
                t.parent_topic_id,
                t.level,
                t.full_path,
                COUNT(qa.id) as question_count
            FROM courses c
            JOIN enrollments e ON c.id = e.course_id AND e.user_id = %s
            LEFT JOIN topics t ON c.id = t.course_id
            LEFT JOIN qa_questions qa ON t.id = qa.topic_id
            GROUP BY c.id, t.id
            ORDER BY c.title, t.level, t.parent_topic_id, t.order_sequence
        """, (user_id,))
        
        result = cursor.fetchall()
        
        # Group topics by course and build hierarchical structure
        courses_data = {}
        for row in result:
            course_id = row['course_id']
            if course_id not in courses_data:
                courses_data[course_id] = {
                    'course_id': course_id,
                    'course_title': row['course_title'],
                    'thumbnail': row['image_url'],
                    'topics': [],
                    'topic_tree': {}  # For building hierarchy
                }
            
            if row['topic_id']:  # Only add topics that exist
                topic_data = {
                    'topic_id': row['topic_id'],
                    'topic_title': row['topic_title'],
                    'order_sequence': row['order_sequence'],
                    'parent_topic_id': row['parent_topic_id'],
                    'level': row['level'] or 0,
                    'full_path': row['full_path'],
                    'question_count': row['question_count'] or 0,
                    'children': []
                }
                courses_data[course_id]['topic_tree'][row['topic_id']] = topic_data
        
        # Build hierarchical structure for each course
        for course_id in courses_data:
            course_data = courses_data[course_id]
            topic_tree = course_data['topic_tree']
            
            # First, organize topics by their parent-child relationships
            for topic_id, topic in topic_tree.items():
                parent_id = topic['parent_topic_id']
                if parent_id and parent_id in topic_tree:
                    # This is a child topic
                    topic_tree[parent_id]['children'].append(topic)
                else:
                    # This is a root topic (level 0)
                    course_data['topics'].append(topic)
            
            # Sort topics and their children by order_sequence
            def sort_topics(topics_list):
                topics_list.sort(key=lambda x: x['order_sequence'] or 0)
                for topic in topics_list:
                    if topic['children']:
                        sort_topics(topic['children'])
            
            sort_topics(course_data['topics'])
            
            # Remove the temporary topic_tree
            del course_data['topic_tree']
        
        courses_list = list(courses_data.values())
        
        return format_api_response({
            'courses': courses_list,
            'total_courses': len(courses_list)
        })
            
    except Exception as e:
        logger.error(f"Error in get_course_topics_qa: {str(e)}")
        return create_error_response(f"Failed to fetch course topics with Q&A counts: {str(e)}")
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()


@course_bp.route('/api/topic-hierarchy', methods=['GET'])
@require_api_key

def get_topic_hierarchy():
    """Get topic hierarchy for a specific course"""
    conn = None
    cursor = None
    try:
        course_id = request.args.get('course_id')
        if not course_id:
            return create_error_response("Course ID is required", 400)

        from database import get_cached_connection
        conn = get_cached_connection()
        if not conn:
            return create_error_response("Database connection failed", 500)
            
        cursor = conn.cursor(dictionary=True)
        
        # Get all topics for the course with hierarchy
        cursor.execute("""
            SELECT 
                t.id as topic_id,
                t.title as topic_title,
                t.order_sequence,
                t.parent_topic_id,
                t.level,
                t.full_path,
                t.description,
                COUNT(q.id) as question_count
            FROM topics t
            LEFT JOIN questions q ON t.id = q.topic_id
            WHERE t.course_id = %s
            GROUP BY t.id
            ORDER BY t.level, t.parent_topic_id, t.order_sequence
        """, (course_id,))
        
        topics = cursor.fetchall()
        
        # Build hierarchical structure
        topic_tree = {}
        root_topics = []
        
        # First pass: create all topic objects
        for topic in topics:
            topic_data = {
                'topic_id': topic['topic_id'],
                'topic_title': topic['topic_title'],
                'order_sequence': topic['order_sequence'],
                'parent_topic_id': topic['parent_topic_id'],
                'level': topic['level'] or 0,
                'full_path': topic['full_path'],
                'description': topic['description'],
                'question_count': topic['question_count'] or 0,
                'children': []
            }
            topic_tree[topic['topic_id']] = topic_data
        
        # Second pass: build parent-child relationships
        for topic_id, topic in topic_tree.items():
            parent_id = topic['parent_topic_id']
            if parent_id and parent_id in topic_tree:
                topic_tree[parent_id]['children'].append(topic)
            else:
                root_topics.append(topic)
        
        # Sort by order_sequence
        def sort_topics(topics_list):
            topics_list.sort(key=lambda x: x['order_sequence'] or 0)
            for topic in topics_list:
                if topic['children']:
                    sort_topics(topic['children'])
        
        sort_topics(root_topics)
        
        return format_api_response({
            'course_id': course_id,
            'topics': root_topics,
            'total_topics': len(topics)
        })
            
    except Exception as e:
        logger.error(f"Error in get_topic_hierarchy: {str(e)}")
        return create_error_response(f"Failed to fetch topic hierarchy: {str(e)}")
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()


@course_bp.route('/api/topic', methods=['POST'])
@require_auth
@require_user_access

def create_topic():
    """Create a new topic with optional parent topic"""
    conn = None
    cursor = None
    try:
        data = request.get_json()
        if not data:
            return create_error_response("Request data is required", 400)
        
        course_id = data.get('course_id')
        title = data.get('title')
        description = data.get('description', '')
        parent_topic_id = data.get('parent_topic_id')
        order_sequence = data.get('order_sequence', 1)
        
        if not course_id or not title:
            return create_error_response("Course ID and title are required", 400)

        from database import get_cached_connection
        conn = get_cached_connection()
        if not conn:
            return create_error_response("Database connection failed", 500)
            
        cursor = conn.cursor(dictionary=True)
        
        # Determine level and full_path
        level = 0
        full_path = title
        
        if parent_topic_id:
            # Get parent topic info
            cursor.execute("""
                SELECT level, full_path, title FROM topics WHERE id = %s
            """, (parent_topic_id,))
            parent = cursor.fetchone()
            
            if parent:
                level = (parent['level'] or 0) + 1
                parent_path = parent['full_path'] or parent['title']
                full_path = f"{parent_path} > {title}"
            else:
                return create_error_response("Parent topic not found", 404)
        
        # Insert new topic
        cursor.execute("""
            INSERT INTO topics (course_id, title, description, parent_topic_id, level, full_path, order_sequence)
            VALUES (%s, %s, %s, %s, %s, %s, %s)
        """, (course_id, title, description, parent_topic_id, level, full_path, order_sequence))
        
        topic_id = cursor.lastrowid
        conn.commit()
        
        return format_api_response({
            'topic_id': topic_id,
            'message': 'Topic created successfully'
        })
            
    except Exception as e:
        if conn:
            conn.rollback()
        logger.error(f"Error in create_topic: {str(e)}")
        return create_error_response(f"Failed to create topic: {str(e)}")
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()


@course_bp.route('/api/topic/<int:topic_id>', methods=['PUT'])
@require_auth
@require_user_access

def update_topic(topic_id):
    """Update topic and automatically update full_path for all children"""
    conn = None
    cursor = None
    try:
        data = request.get_json()
        if not data:
            return create_error_response("Request data is required", 400)

        from database import get_cached_connection
        conn = get_cached_connection()
        if not conn:
            return create_error_response("Database connection failed", 500)
            
        cursor = conn.cursor(dictionary=True)
        
        # Get current topic
        cursor.execute("SELECT * FROM topics WHERE id = %s", (topic_id,))
        current_topic = cursor.fetchone()
        if not current_topic:
            return create_error_response("Topic not found", 404)
        
        # Update fields
        title = data.get('title', current_topic['title'])
        description = data.get('description', current_topic['description'])
        parent_topic_id = data.get('parent_topic_id', current_topic['parent_topic_id'])
        order_sequence = data.get('order_sequence', current_topic['order_sequence'])
        
        # Recalculate level and full_path
        level = 0
        full_path = title
        
        if parent_topic_id:
            cursor.execute("SELECT level, full_path, title FROM topics WHERE id = %s", (parent_topic_id,))
            parent = cursor.fetchone()
            if parent:
                level = (parent['level'] or 0) + 1
                parent_path = parent['full_path'] or parent['title']
                full_path = f"{parent_path} > {title}"
        
        # Update topic
        cursor.execute("""
            UPDATE topics 
            SET title = %s, description = %s, parent_topic_id = %s, 
                level = %s, full_path = %s, order_sequence = %s
            WHERE id = %s
        """, (title, description, parent_topic_id, level, full_path, order_sequence, topic_id))
        
        # Update full_path for all children recursively
        def update_children_paths(parent_id, parent_path):
            cursor.execute("SELECT id, title FROM topics WHERE parent_topic_id = %s", (parent_id,))
            children = cursor.fetchall()
            for child in children:
                child_path = f"{parent_path} > {child['title']}"
                cursor.execute("UPDATE topics SET full_path = %s WHERE id = %s", (child_path, child['id']))
                update_children_paths(child['id'], child_path)
        
        update_children_paths(topic_id, full_path)
        
        conn.commit()
        
        return format_api_response({
            'message': 'Topic updated successfully'
        })
            
    except Exception as e:
        if conn:
            conn.rollback()
        logger.error(f"Error in update_topic: {str(e)}")
        return create_error_response(f"Failed to update topic: {str(e)}")
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()