"""
课程相关数据库模型
"""
from enum import Enum
from typing import List, Optional
from datetime import datetime

from sqlalchemy import (
    String,
    Text,
    Integer,
    Boolean,
    ForeignKey,
    Enum as SQLEnum,
    Float,
    JSON,
    DateTime,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.models.base import BaseModel, SoftDeleteMixin, AuditMixin


class CourseStatus(str, Enum):
    """课程状态枚举"""

    DRAFT = "draft"  # 草稿
    PUBLISHED = "published"  # 已发布
    ARCHIVED = "archived"  # 已归档


class CourseCategory(str, Enum):
    """课程分类枚举"""

    TECHNOLOGY = "technology"  # 技术
    MANAGEMENT = "management"  # 管理
    BUSINESS = "business"  # 业务
    GENERAL = "general"  # 通用


class Course(BaseModel, SoftDeleteMixin, AuditMixin):
    """
    课程表
    """

    __tablename__ = "courses"

    # 基本信息
    name: Mapped[str] = mapped_column(String(200), nullable=False, comment="课程名称")
    description: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True, comment="课程描述"
    )
    category: Mapped[CourseCategory] = mapped_column(
        SQLEnum(
            CourseCategory,
            values_callable=lambda enum_cls: [e.value for e in enum_cls],
            validate_strings=True,
        ),
        default=CourseCategory.GENERAL,
        nullable=False,
        comment="课程分类",
    )
    status: Mapped[CourseStatus] = mapped_column(
        SQLEnum(
            CourseStatus,
            values_callable=lambda enum_cls: [e.value for e in enum_cls],
            validate_strings=True,
        ),
        default=CourseStatus.DRAFT,
        nullable=False,
        comment="课程状态",
    )

    # 课程详情
    cover_image: Mapped[Optional[str]] = mapped_column(
        String(500), nullable=True, comment="封面图片URL"
    )
    duration_hours: Mapped[Optional[float]] = mapped_column(
        Float, nullable=True, comment="课程时长(小时)"
    )
    difficulty_level: Mapped[Optional[int]] = mapped_column(
        Integer, nullable=True, comment="难度等级(1-5)"
    )
    tags: Mapped[Optional[List[str]]] = mapped_column(
        JSON, nullable=True, comment="标签列表"
    )

    # 发布信息
    published_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True, comment="发布时间"
    )
    publisher_id: Mapped[Optional[int]] = mapped_column(
        Integer, nullable=True, comment="发布人ID"
    )

    # 播课信息
    # 播课功能（Coze工作流直接写数据库）
    broadcast_audio_url: Mapped[Optional[str]] = mapped_column(
        String(500), nullable=True, comment="播课音频URL"
    )
    broadcast_generated_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True, comment="播课生成时间"
    )

    # 排序和权重
    sort_order: Mapped[int] = mapped_column(
        Integer, default=0, nullable=False, comment="排序顺序"
    )
    is_featured: Mapped[bool] = mapped_column(
        Boolean, default=False, nullable=False, comment="是否推荐"
    )
    
    # 统计信息
    student_count: Mapped[int] = mapped_column(
        Integer, default=0, nullable=False, comment="学习人数"
    )
    is_new: Mapped[bool] = mapped_column(
        Boolean, default=True, nullable=False, comment="是否新课程"
    )
    
    # 资料下载设置
    allow_download: Mapped[bool] = mapped_column(
        Boolean, default=False, nullable=False, comment="是否允许下载资料"
    )

    # 关联关系
    materials: Mapped[List["CourseMaterial"]] = relationship(
        "CourseMaterial", back_populates="course"
    )
    knowledge_points: Mapped[List["KnowledgePoint"]] = relationship(
        "KnowledgePoint", back_populates="course"
    )
    
    # 岗位分配关系（通过关联表）
    position_assignments = relationship("PositionCourse", back_populates="course", cascade="all, delete-orphan")
    exams = relationship("Exam", back_populates="course")
    questions = relationship("Question", back_populates="course")


class CourseMaterial(BaseModel, SoftDeleteMixin, AuditMixin):
    """
    课程资料表
    """

    __tablename__ = "course_materials"

    course_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("courses.id", ondelete="CASCADE"),
        nullable=False,
        comment="课程ID",
    )
    name: Mapped[str] = mapped_column(String(200), nullable=False, comment="资料名称")
    description: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True, comment="资料描述"
    )
    file_url: Mapped[str] = mapped_column(String(500), nullable=False, comment="文件URL")
    file_type: Mapped[str] = mapped_column(String(50), nullable=False, comment="文件类型")
    file_size: Mapped[int] = mapped_column(Integer, nullable=False, comment="文件大小(字节)")

    # 排序
    sort_order: Mapped[int] = mapped_column(
        Integer, default=0, nullable=False, comment="排序顺序"
    )

    # 关联关系
    course: Mapped["Course"] = relationship("Course", back_populates="materials")
    # 关联的知识点（直接关联）
    knowledge_points: Mapped[List["KnowledgePoint"]] = relationship(
        "KnowledgePoint", back_populates="material"
    )


class KnowledgePoint(BaseModel, SoftDeleteMixin, AuditMixin):
    """
    知识点表
    """

    __tablename__ = "knowledge_points"

    course_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("courses.id", ondelete="CASCADE"),
        nullable=False,
        comment="课程ID",
    )
    material_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("course_materials.id", ondelete="CASCADE"),
        nullable=False,
        comment="关联资料ID",
    )
    name: Mapped[str] = mapped_column(String(200), nullable=False, comment="知识点名称")
    description: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True, comment="知识点描述"
    )
    type: Mapped[str] = mapped_column(
        String(50), default="概念定义", nullable=False, comment="知识点类型"
    )
    source: Mapped[int] = mapped_column(
        Integer, default=0, nullable=False, comment="来源：0=手动，1=AI分析"
    )
    topic_relation: Mapped[Optional[str]] = mapped_column(
        String(200), nullable=True, comment="与主题的关系描述"
    )

    # 关联关系
    course: Mapped["Course"] = relationship("Course", back_populates="knowledge_points")
    material: Mapped["CourseMaterial"] = relationship("CourseMaterial")


class GrowthPath(BaseModel, SoftDeleteMixin):
    """
    成长路径表
    """

    __tablename__ = "growth_paths"

    name: Mapped[str] = mapped_column(String(200), nullable=False, comment="路径名称")
    description: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True, comment="路径描述"
    )
    target_role: Mapped[Optional[str]] = mapped_column(
        String(100), nullable=True, comment="目标角色"
    )

    # 路径配置
    courses: Mapped[Optional[List[dict]]] = mapped_column(
        JSON, nullable=True, comment="课程列表[{course_id, order, is_required}]"
    )

    # 预计时长
    estimated_duration_days: Mapped[Optional[int]] = mapped_column(
        Integer, nullable=True, comment="预计完成天数"
    )

    # 状态
    is_active: Mapped[bool] = mapped_column(
        Boolean, default=True, nullable=False, comment="是否启用"
    )
    sort_order: Mapped[int] = mapped_column(
        Integer, default=0, nullable=False, comment="排序顺序"
    )


class MaterialKnowledgePoint(BaseModel, SoftDeleteMixin):
    """
    资料知识点关联表
    """
    
    __tablename__ = "material_knowledge_points"
    
    material_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("course_materials.id", ondelete="CASCADE"),
        nullable=False,
        comment="资料ID",
    )
    knowledge_point_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("knowledge_points.id", ondelete="CASCADE"),
        nullable=False,
        comment="知识点ID",
    )
    sort_order: Mapped[int] = mapped_column(
        Integer, default=0, nullable=False, comment="排序顺序"
    )
    is_ai_generated: Mapped[bool] = mapped_column(
        Boolean, default=False, nullable=False, comment="是否AI生成"
    )
