from datetime import datetime
from mongoengine import Document, ReferenceField, StringField, IntField, DateTimeField
from models.sub_exam import SubExam  # ReferenceField target
from models.exam import Exam  # ReferenceField target
from models.configuration import Language# ReferenceField target
from bson import ObjectId
from mongoengine.errors import ValidationError, DoesNotExist

from bson import ObjectId, DBRef
from mongoengine.errors import ValidationError, DoesNotExist
from models.configuration import Language  # adjust path if needed

def _resolve_course_language(course):
    """
    Handles:
    - language_id as Language document
    - language_id as LazyReference / DBRef
    - language_id as ObjectId
    - language_id as string
    - language_id as dict {"$oid": "..."} or {"id": "..."}
    - legacy "language" string
    """
    lang_ref = getattr(course, "language_id", None)

    if lang_ref:
        # Case 1: already dereferenced Language doc
        name = getattr(lang_ref, "language_name", None)
        if name:
            return name

        # Case 2: LazyReference (has fetch())
        try:
            if hasattr(lang_ref, "fetch"):
                lang_doc = lang_ref.fetch()
                if lang_doc and getattr(lang_doc, "language_name", None):
                    return lang_doc.language_name
        except Exception:
            pass

        # Case 3: DBRef
        try:
            if isinstance(lang_ref, DBRef):
                lang_doc = Language.objects(id=lang_ref.id).only("language_name").first()
                if lang_doc and lang_doc.language_name:
                    return lang_doc.language_name
        except Exception:
            pass

        # Case 4: dict like {"$oid": "..."} or {"id": "..."}
        try:
            if isinstance(lang_ref, dict):
                raw_id = lang_ref.get("$oid") or lang_ref.get("id") or lang_ref.get("_id")
                if raw_id:
                    lang_doc = Language.objects(id=ObjectId(str(raw_id))).only("language_name").first()
                    if lang_doc and lang_doc.language_name:
                        return lang_doc.language_name
        except Exception:
            pass

        # Case 5: raw ObjectId or string
        try:
            raw_id = lang_ref
            if isinstance(raw_id, str):
                raw_id = ObjectId(raw_id)

            lang_doc = Language.objects(id=raw_id).only("language_name").first()
            if lang_doc and lang_doc.language_name:
                return lang_doc.language_name
        except (ValidationError, DoesNotExist, Exception):
            pass

    # Legacy fallback
    legacy_lang = getattr(course, "language", None)
    if legacy_lang:
        return legacy_lang

    return None


class Course(Document):
   

    exam_id = ReferenceField(Exam, required=True)          # PK of models/exam.py
    sub_exam_id = ReferenceField(SubExam, required=False, default=None)  # PK of models/sub_exam.py
    subject_id = ReferenceField('VideoCourseSubject', required=True)
    chapter_id = ReferenceField('Chapters', required=False, default=None)
    topic_id = ReferenceField('Topic', required= False, default=None)  # PK of sub_exams_list
    course_image = StringField(null=True)   
    language_id = ReferenceField(Language, default=None)               # Language of the course
    course_title = StringField(required=True)
    course_fee = IntField(required=True, min_value=0)        # coins (e.g., 1000)
    discounted_fee = IntField(default=0, min_value=0) # coins (e.g., 800)
    duration = IntField(required=True, min_value=0)            # NEW: duration in days
    status = IntField(default=1, choices=[0, 1])             # 1=active, 0=inactive
    position = IntField(default=0)
    created_date = DateTimeField(default=datetime.utcnow)

    meta = {
        'collection': 'courses',
        'strict': False,
        'indexes': ['exam_id', 'sub_exam_id', 'status', 'position', '-created_date'],
    }

    def to_json(self):
        return {
            'id': str(self.id),
            'exam_id': str(self.exam_id.id) if self.exam_id else None,
            'sub_exam_id': str(self.sub_exam_id.id) if self.sub_exam_id else None,
            'course_image': self.course_image,
            'course_title': self.course_title,
            # 'language': self.language_id,
            'language': _resolve_course_language(self),

            'course_fee': self.course_fee,
            'discounted_fee': self.discounted_fee,
            'duration': self.duration,
            'status': self.status,
            'position': self.position,
            'created_date': self.created_date.isoformat() if self.created_date else None
        }
