"""
成长路径相关数据库模型
"""
from enum import Enum
from typing import List, Optional, TYPE_CHECKING
from datetime import datetime
from decimal import Decimal

if TYPE_CHECKING:
    from app.models.course import Course
    from app.models.user import User

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

from app.models.base import BaseModel, SoftDeleteMixin


class GrowthPathStatus(str, Enum):
    """成长路径学习状态"""
    NOT_STARTED = "not_started"  # 未开始
    IN_PROGRESS = "in_progress"  # 进行中
    COMPLETED = "completed"      # 已完成


class NodeStatus(str, Enum):
    """节点状态"""
    LOCKED = "locked"          # 锁定（前置未完成）
    UNLOCKED = "unlocked"      # 已解锁（可以开始）
    IN_PROGRESS = "in_progress"  # 学习中
    COMPLETED = "completed"    # 已完成


class GrowthPathNode(BaseModel, SoftDeleteMixin):
    """
    成长路径节点表
    每个节点对应一门课程
    """
    __tablename__ = "growth_path_nodes"

    # 关联
    growth_path_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("growth_paths.id", ondelete="CASCADE"),
        nullable=False,
        comment="成长路径ID"
    )
    course_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("courses.id", ondelete="CASCADE"),
        nullable=False,
        comment="课程ID"
    )

    # 节点信息
    stage_name: Mapped[Optional[str]] = mapped_column(
        String(100), nullable=True, comment="所属阶段名称"
    )
    title: Mapped[str] = mapped_column(
        String(200), nullable=False, comment="节点标题"
    )
    description: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True, comment="节点描述"
    )

    # 配置
    order_num: Mapped[int] = mapped_column(
        Integer, default=0, nullable=False, comment="排序顺序"
    )
    is_required: Mapped[bool] = mapped_column(
        Boolean, default=True, nullable=False, comment="是否必修"
    )
    prerequisites: Mapped[Optional[List[int]]] = mapped_column(
        JSON, nullable=True, comment="前置节点IDs"
    )
    estimated_days: Mapped[int] = mapped_column(
        Integer, default=7, nullable=False, comment="预计学习天数"
    )
    
    # 画布位置（用于可视化编辑器）
    position_x: Mapped[Optional[int]] = mapped_column(
        Integer, nullable=True, default=0, comment="画布X坐标"
    )
    position_y: Mapped[Optional[int]] = mapped_column(
        Integer, nullable=True, default=0, comment="画布Y坐标"
    )

    # 关联关系
    growth_path: Mapped["GrowthPath"] = relationship(  # noqa: F821
        "GrowthPath", back_populates="nodes"
    )
    course: Mapped["Course"] = relationship("Course")
    user_completions: Mapped[List["UserNodeCompletion"]] = relationship(
        "UserNodeCompletion", back_populates="node"
    )


class UserGrowthPathProgress(BaseModel):
    """
    用户成长路径进度表
    记录用户在某条成长路径上的整体进度
    """
    __tablename__ = "user_growth_path_progress"

    # 关联
    user_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("users.id", ondelete="CASCADE"),
        nullable=False,
        comment="用户ID"
    )
    growth_path_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("growth_paths.id", ondelete="CASCADE"),
        nullable=False,
        comment="成长路径ID"
    )

    # 进度信息
    current_node_id: Mapped[Optional[int]] = mapped_column(
        Integer, nullable=True, comment="当前学习节点ID"
    )
    completed_node_ids: Mapped[Optional[List[int]]] = mapped_column(
        JSON, nullable=True, comment="已完成节点IDs"
    )
    total_progress: Mapped[Decimal] = mapped_column(
        DECIMAL(5, 2), default=0.00, nullable=False, comment="总进度百分比"
    )

    # 状态
    status: Mapped[str] = mapped_column(
        String(20),
        default=GrowthPathStatus.NOT_STARTED.value,
        nullable=False,
        comment="状态"
    )

    # 时间记录
    started_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True, comment="开始时间"
    )
    completed_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True, comment="完成时间"
    )
    last_activity_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True, comment="最后活动时间"
    )

    # 关联关系
    user: Mapped["User"] = relationship("User")
    growth_path: Mapped["GrowthPath"] = relationship("GrowthPath")  # noqa: F821


class UserNodeCompletion(BaseModel):
    """
    用户节点完成记录表
    详细记录用户在每个节点上的学习状态
    """
    __tablename__ = "user_node_completions"

    # 关联
    user_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("users.id", ondelete="CASCADE"),
        nullable=False,
        comment="用户ID"
    )
    growth_path_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("growth_paths.id", ondelete="CASCADE"),
        nullable=False,
        comment="成长路径ID"
    )
    node_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("growth_path_nodes.id", ondelete="CASCADE"),
        nullable=False,
        comment="节点ID"
    )

    # 进度信息
    course_progress: Mapped[Decimal] = mapped_column(
        DECIMAL(5, 2), default=0.00, nullable=False, comment="课程学习进度"
    )
    status: Mapped[str] = mapped_column(
        String(20),
        default=NodeStatus.LOCKED.value,
        nullable=False,
        comment="状态"
    )

    # 时间记录
    unlocked_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True, comment="解锁时间"
    )
    started_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True, comment="开始学习时间"
    )
    completed_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True, comment="完成时间"
    )

    # 关联关系
    user: Mapped["User"] = relationship("User")
    node: Mapped["GrowthPathNode"] = relationship(
        "GrowthPathNode", back_populates="user_completions"
    )
    growth_path: Mapped["GrowthPath"] = relationship("GrowthPath")  # noqa: F821
