from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify, current_app
from flask_login import login_required, current_user
from app.extensions import db
from app.models.course import (
    Course, CourseCategory, Trainer, CourseVideo,
    CourseEnrollment, Certificate, CourseReview
)
from datetime import datetime
from functools import wraps

courses_bp = Blueprint("courses", __name__, url_prefix="/courses")


def premium_required(f):
    """Decorator to require premium subscription for route access."""
    @wraps(f)
    @login_required
    def decorated(*args, **kwargs):
        if not current_user.has_premium_access:
            flash("هذه الميزة متاحة فقط للمشتركين في الخطط المدفوعة", "warning")
            return redirect(url_for('subscription.plans'))
        return f(*args, **kwargs)
    return decorated


# ══════════════════════════════════════════════════════════════
#  Course Catalog
# ══════════════════════════════════════════════════════════════

@courses_bp.route("/")
@premium_required
def index():
    """Course catalog page."""
    page = request.args.get("page", 1, type=int)
    category_slug = request.args.get("category", "").strip()
    level = request.args.get("level", "").strip()
    q = request.args.get("q", "").strip()
    sort = request.args.get("sort", "newest").strip()

    query = Course.query.filter_by(status="published", is_active=True)

    # Apply filters
    if category_slug:
        category = CourseCategory.query.filter_by(slug=category_slug, is_active=True).first()
        if category:
            query = query.filter_by(category_id=category.id)

    if level:
        query = query.filter_by(level=level)

    if q:
        query = query.filter(db.or_(
            Course.title.ilike(f"%{q}%"),
            Course.title_ar.ilike(f"%{q}%"),
            Course.description.ilike(f"%{q}%"),
            Course.description_ar.ilike(f"%{q}%")
        ))

    # Apply sorting
    if sort == "newest":
        query = query.order_by(Course.created_at.desc())
    elif sort == "popular":
        query = query.order_by(Course.current_enrollments.desc())
    elif sort == "rating":
        # Subquery for average rating would go here
        query = query.order_by(Course.created_at.desc())
    elif sort == "price_low":
        query = query.order_by(Course.price.asc())
    elif sort == "price_high":
        query = query.order_by(Course.price.desc())

    pagination = query.paginate(page=page, per_page=12, error_out=False)

    categories = CourseCategory.query.filter_by(is_active=True).order_by(CourseCategory.display_order).all()
    featured_courses = Course.query.filter_by(status="published", is_active=True, featured=True)\
        .limit(3).all()

    return render_template("courses/index.html",
        pagination=pagination,
        categories=categories,
        featured_courses=featured_courses,
        category_filter=category_slug,
        level_filter=level,
        q=q,
        sort=sort
    )


@courses_bp.route("/category/<slug>")
def category(slug):
    """Courses by category."""
    category = CourseCategory.query.filter_by(slug=slug, is_active=True).first_or_404()
    page = request.args.get("page", 1, type=int)

    pagination = Course.query.filter_by(
        category_id=category.id,
        status="published",
        is_active=True
    ).order_by(Course.created_at.desc()).paginate(page=page, per_page=12, error_out=False)

    categories = CourseCategory.query.filter_by(is_active=True).all()

    return render_template("courses/index.html",
        pagination=pagination,
        categories=categories,
        current_category=category
    )


@courses_bp.route("/<slug>")
def detail(slug):
    """Single course detail page."""
    course = Course.query.filter_by(slug=slug, is_active=True).first_or_404()

    # Check if user is enrolled
    is_enrolled = False
    enrollment = None
    if current_user.is_authenticated:
        enrollment = CourseEnrollment.query.filter_by(
            user_id=str(current_user.id),
            course_id=course.id
        ).first()
        is_enrolled = enrollment is not None

    # Get reviews
    reviews = CourseReview.query.filter_by(
        course_id=course.id,
        is_approved=True
    ).order_by(CourseReview.created_at.desc()).limit(10).all()

    # Related courses
    related_courses = Course.query.filter(
        Course.category_id == course.category_id,
        Course.id != course.id,
        Course.status == "published",
        Course.is_active == True
    ).limit(4).all()

    return render_template("courses/detail.html",
        course=course,
        is_enrolled=is_enrolled,
        enrollment=enrollment,
        reviews=reviews,
        related_courses=related_courses
    )


# ══════════════════════════════════════════════════════════════
#  Enrollment
# ══════════════════════════════════════════════════════════════

@courses_bp.route("/<int:course_id>/enroll", methods=["POST"])
@login_required
def enroll(course_id):
    """Enroll in a course."""
    course = Course.query.filter_by(
        id=course_id,
        status="published",
        is_active=True
    ).first_or_404()

    # Check if already enrolled
    existing = CourseEnrollment.query.filter_by(
        user_id=str(current_user.id),
        course_id=course_id
    ).first()
    if existing:
        flash("أنت مسجل بالفعل في هذه الدورة", "info")
        return redirect(url_for("courses.learn", course_id=course_id))

    # Check if course is full
    if course.max_students and course.current_enrollments >= course.max_students:
        flash("عذراً، هذه الدورة ممتلئة", "error")
        return redirect(url_for("courses.detail", slug=course.slug))

    # For paid courses, redirect to payment (placeholder)
    if not course.is_free and course.price > 0:
        flash("سيتم توجيهك لصفحة الدفع", "info")
        # TODO: Implement payment flow
        return redirect(url_for("courses.detail", slug=course.slug))

    # Create enrollment
    enrollment = CourseEnrollment(
        user_id=str(current_user.id),
        course_id=course_id,
        status="enrolled"
    )
    db.session.add(enrollment)

    # Update course enrollment count
    course.current_enrollments += 1

    db.session.commit()
    flash(f"تم التسجيل في الدورة {course.display_title} بنجاح!", "success")
    return redirect(url_for("courses.learn", course_id=course_id))


# ══════════════════════════════════════════════════════════════
#  Learning Interface
# ══════════════════════════════════════════════════════════════

@courses_bp.route("/my-courses")
@login_required
def my_courses():
    """User's enrolled courses."""
    page = request.args.get("page", 1, type=int)
    status_filter = request.args.get("status", "").strip()

    query = CourseEnrollment.query.filter_by(user_id=str(current_user.id))
    if status_filter:
        query = query.filter_by(status=status_filter)

    pagination = query.order_by(CourseEnrollment.enrolled_at.desc())\
        .paginate(page=page, per_page=12, error_out=False)

    return render_template("courses/my_courses.html",
        pagination=pagination,
        status_filter=status_filter
    )


@courses_bp.route("/learn/<int:course_id>")
@login_required
def learn(course_id):
    """Course learning interface."""
    enrollment = CourseEnrollment.query.filter_by(
        user_id=str(current_user.id),
        course_id=course_id
    ).first_or_404()

    course = enrollment.course

    # Get first video or last watched
    if enrollment.last_watched_video_id:
        current_video = CourseVideo.query.filter_by(
            id=enrollment.last_watched_video_id,
            is_active=True
        ).first()
    else:
        current_video = course.videos.filter_by(is_active=True).order_by(CourseVideo.position).first()

    if not current_video:
        flash("لا توجد فيديوهات في هذه الدورة بعد", "info")
        return redirect(url_for("courses.detail", slug=course.slug))

    # Get all videos for sidebar
    videos = course.videos.filter_by(is_active=True).order_by(CourseVideo.position).all()

    # Mark as in progress
    if enrollment.status == "enrolled":
        enrollment.status = "in_progress"
        db.session.commit()

    return render_template("courses/learn.html",
        course=course,
        enrollment=enrollment,
        videos=videos,
        current_video=current_video
    )


@courses_bp.route("/learn/<int:course_id>/<int:video_id>")
@login_required
def learn_video(course_id, video_id):
    """Watch specific video."""
    enrollment = CourseEnrollment.query.filter_by(
        user_id=str(current_user.id),
        course_id=course_id
    ).first_or_404()

    course = enrollment.course
    current_video = CourseVideo.query.filter_by(
        id=video_id,
        course_id=course_id,
        is_active=True
    ).first_or_404()

    # Check if video is preview (non-enrolled can watch)
    if not current_video.is_preview:
        # Verify enrollment
        if enrollment.user_id != str(current_user.id):
            flash("يجب التسجيل في الدورة لمشاهدة هذا الفيديو", "error")
            return redirect(url_for("courses.detail", slug=course.slug))

    videos = course.videos.filter_by(is_active=True).order_by(CourseVideo.position).all()

    # Update last watched
    enrollment.last_watched_video_id = video_id
    db.session.commit()

    return render_template("courses/learn.html",
        course=course,
        enrollment=enrollment,
        videos=videos,
        current_video=current_video
    )


# ══════════════════════════════════════════════════════════════
#  API Endpoints for Progress Tracking
# ══════════════════════════════════════════════════════════════

@courses_bp.route("/api/<int:course_id>/progress", methods=["POST"])
@login_required
def update_progress(course_id):
    """Update user's progress in course."""
    enrollment = CourseEnrollment.query.filter_by(
        user_id=str(current_user.id),
        course_id=course_id
    ).first_or_404()

    data = request.get_json()
    video_id = data.get("video_id")
    position = data.get("position", 0)

    if video_id:
        enrollment.last_watched_video_id = video_id
        enrollment.last_position_seconds = position

    db.session.commit()
    return jsonify({"progress": enrollment.progress_percentage})


@courses_bp.route("/api/<int:course_id>/video/<int:video_id>/complete", methods=["POST"])
@login_required
def mark_video_complete(course_id, video_id):
    """Mark video as completed."""
    enrollment = CourseEnrollment.query.filter_by(
        user_id=str(current_user.id),
        course_id=course_id
    ).first_or_404()

    completed = enrollment.completed_videos_json or []
    if video_id not in completed:
        completed.append(video_id)
        enrollment.completed_videos_json = completed

    # Recalculate progress
    enrollment.update_progress()

    db.session.commit()
    return jsonify({
        "success": True,
        "progress": enrollment.progress_percentage,
        "status": enrollment.status
    })


@courses_bp.route("/api/<int:course_id>/save-position", methods=["POST"])
@login_required
def save_position(course_id):
    """Save video playback position."""
    enrollment = CourseEnrollment.query.filter_by(
        user_id=str(current_user.id),
        course_id=course_id
    ).first_or_404()

    data = request.get_json()
    video_id = data.get("video_id")
    position = data.get("position", 0)

    if video_id:
        enrollment.last_watched_video_id = video_id
        enrollment.last_position_seconds = position
        db.session.commit()

    return jsonify({"success": True})


# ══════════════════════════════════════════════════════════════
#  Reviews
# ══════════════════════════════════════════════════════════════

@courses_bp.route("/<int:course_id>/review", methods=["POST"])
@login_required
def submit_review(course_id):
    """Submit course review."""
    course = Course.query.get_or_404(course_id)

    # Check if enrolled
    enrollment = CourseEnrollment.query.filter_by(
        user_id=str(current_user.id),
        course_id=course_id
    ).first()
    if not enrollment:
        flash("يجب التسجيل في الدورة لتقييمها", "error")
        return redirect(url_for("courses.detail", slug=course.slug))

    # Check if already reviewed
    existing = CourseReview.query.filter_by(
        user_id=str(current_user.id),
        course_id=course_id
    ).first()
    if existing:
        flash("لقد قيمت هذه الدورة مسبقاً", "info")
        return redirect(url_for("courses.detail", slug=course.slug))

    rating = request.form.get("rating", type=int)
    comment = request.form.get("comment", "").strip()

    if not rating or rating < 1 or rating > 5:
        flash("التقييم مطلوب (1-5)", "error")
        return redirect(url_for("courses.detail", slug=course.slug))

    review = CourseReview(
        user_id=str(current_user.id),
        course_id=course_id,
        rating=rating,
        comment=comment
    )
    db.session.add(review)
    db.session.commit()

    flash("شكراً لتقييمك! سيظهر بعد مراجعة الإدارة", "success")
    return redirect(url_for("courses.detail", slug=course.slug))


# ══════════════════════════════════════════════════════════════
#  Certificates
# ══════════════════════════════════════════════════════════════

@courses_bp.route("/certificates")
@login_required
def certificates():
    """User's certificates."""
    from app.models.course import Certificate as Cert
    certs = Cert.query.filter_by(user_id=str(current_user.id))\
        .join(Cert.course).filter(Course.is_active == True)\
        .order_by(Cert.issued_at.desc()).all()
    return render_template("courses/certificates.html", certificates=certs)


@courses_bp.route("/certificates/<int:certificate_id>")
@login_required
def certificate_view(certificate_id):
    """View certificate."""
    from app.models.course import Certificate as Cert
    cert = Cert.query.get_or_404(certificate_id)

    # Verify ownership
    if cert.user_id != str(current_user.id) and not current_user.is_admin:
        flash("غير مصرح بعرض هذه الشهادة", "error")
        return redirect(url_for("courses.certificates"))

    return render_template("courses/certificate_view.html", certificate=cert)


@courses_bp.route("/certificates/<int:certificate_id>/download")
@login_required
def certificate_download(certificate_id):
    """Download certificate PDF."""
    from app.models.course import Certificate as Cert
    from flask import send_file
    import os

    cert = Cert.query.get_or_404(certificate_id)

    # Verify ownership
    if cert.user_id != str(current_user.id) and not current_user.is_admin:
        flash("غير مصرح بتحميل هذه الشهادة", "error")
        return redirect(url_for("courses.certificates"))

    # Get PDF path
    pdf_path = os.path.join(
        current_app.root_path,
        "static",
        "uploads",
        "courses",
        "certificates",
        f"{cert.certificate_number}.pdf"
    )

    if os.path.exists(pdf_path):
        return send_file(pdf_path, as_attachment=True,
            download_name=f"Certificate-{cert.certificate_number}.pdf")
    else:
        flash("ملف الشهادة غير متوفر", "error")
        return redirect(url_for("courses.certificate_view", certificate_id=certificate_id))


@courses_bp.route("/verify/<cert_number>")
def verify_certificate(cert_number):
    """Public certificate verification page."""
    from app.models.course import Certificate as Cert
    from app.helpers.certificate_generator import verify_certificate

    result = verify_certificate(cert_number)
    return render_template("courses/verify_certificate.html",
        cert_number=cert_number, result=result)
