from datetime import datetime
from decimal import Decimal

from sqlalchemy import (
    Boolean, Column, DateTime, ForeignKey, Integer,
    Numeric, String, Text, UniqueConstraint,
)
from sqlalchemy.orm import relationship

from ..core.database import PlatformBase


class Rol(PlatformBase):
    __tablename__ = "roles"

    id_rol = Column(Integer, primary_key=True, index=True)
    nombre = Column(String(50), unique=True, nullable=False)

    usuarios = relationship("Usuario", back_populates="rol")


class Usuario(PlatformBase):
    __tablename__ = "usuarios"

    id_usuario = Column(Integer, primary_key=True, index=True)
    nombre = Column(String(100), nullable=False)
    apellidos = Column(String(150), nullable=True)
    email = Column(String(150), unique=True, nullable=False)
    fecha_creacion = Column(DateTime, default=datetime.utcnow)
    activo = Column(Boolean, default=True)
    id_rol = Column(Integer, ForeignKey("roles.id_rol"), nullable=False)

    rol = relationship("Rol", back_populates="usuarios")
    credencial = relationship("Credencial", back_populates="usuario", uselist=False)
    profesor = relationship("Profesor", back_populates="usuario", uselist=False)
    alumno = relationship("Alumno", back_populates="usuario", uselist=False)


class Credencial(PlatformBase):
    __tablename__ = "credenciales"

    id_credencial = Column(Integer, primary_key=True, index=True)
    id_usuario = Column(Integer, ForeignKey("usuarios.id_usuario", ondelete="CASCADE"), unique=True, nullable=False)
    password_hash = Column(Text, nullable=False)
    ultimo_login = Column(DateTime, nullable=True)

    usuario = relationship("Usuario", back_populates="credencial")


class Profesor(PlatformBase):
    __tablename__ = "profesores"

    id_profesor = Column(Integer, primary_key=True, index=True)
    id_usuario = Column(Integer, ForeignKey("usuarios.id_usuario", ondelete="CASCADE"), unique=True, nullable=False)
    especialidad = Column(String(100), nullable=True)

    usuario = relationship("Usuario", back_populates="profesor")
    cursos = relationship("Curso", back_populates="profesor")


class Alumno(PlatformBase):
    __tablename__ = "alumnos"

    id_alumno = Column(Integer, primary_key=True, index=True)
    id_usuario = Column(Integer, ForeignKey("usuarios.id_usuario", ondelete="CASCADE"), unique=True, nullable=False)
    nivel = Column(String(50), nullable=True)

    usuario = relationship("Usuario", back_populates="alumno")
    matriculas = relationship("Matricula", back_populates="alumno")
    entregas = relationship("Entrega", back_populates="alumno")
    progreso = relationship("Progreso", back_populates="alumno")


class Curso(PlatformBase):
    __tablename__ = "cursos"

    id_curso = Column(Integer, primary_key=True, index=True)
    nombre = Column(String(150), nullable=False)
    descripcion = Column(Text, nullable=True)
    fecha_creacion = Column(DateTime, default=datetime.utcnow)
    id_profesor = Column(Integer, ForeignKey("profesores.id_profesor"), nullable=False)

    profesor = relationship("Profesor", back_populates="cursos")
    matriculas = relationship("Matricula", back_populates="curso")
    actividades = relationship("Actividad", back_populates="curso")
    progreso = relationship("Progreso", back_populates="curso")


class Matricula(PlatformBase):
    __tablename__ = "matriculas"
    __table_args__ = (UniqueConstraint("id_alumno", "id_curso"),)

    id_matricula = Column(Integer, primary_key=True, index=True)
    id_alumno = Column(Integer, ForeignKey("alumnos.id_alumno", ondelete="CASCADE"), nullable=False)
    id_curso = Column(Integer, ForeignKey("cursos.id_curso", ondelete="CASCADE"), nullable=False)
    fecha_matricula = Column(DateTime, default=datetime.utcnow)

    alumno = relationship("Alumno", back_populates="matriculas")
    curso = relationship("Curso", back_populates="matriculas")


class Actividad(PlatformBase):
    __tablename__ = "actividades"

    id_actividad = Column(Integer, primary_key=True, index=True)
    titulo = Column(String(200), nullable=False)
    descripcion = Column(Text, nullable=True)
    fecha_publicacion = Column(DateTime, default=datetime.utcnow)
    fecha_entrega = Column(DateTime, nullable=True)
    puntuacion_maxima = Column(Numeric(5, 2), nullable=True)
    id_curso = Column(Integer, ForeignKey("cursos.id_curso", ondelete="CASCADE"), nullable=False)

    curso = relationship("Curso", back_populates="actividades")
    entregas = relationship("Entrega", back_populates="actividad")


class Entrega(PlatformBase):
    __tablename__ = "entregas"

    id_entrega = Column(Integer, primary_key=True, index=True)
    id_actividad = Column(Integer, ForeignKey("actividades.id_actividad", ondelete="CASCADE"), nullable=False)
    id_alumno = Column(Integer, ForeignKey("alumnos.id_alumno", ondelete="CASCADE"), nullable=False)
    fecha_entrega = Column(DateTime, default=datetime.utcnow)
    contenido = Column(Text, nullable=True)
    estado = Column(String(50), default="pendiente")

    actividad = relationship("Actividad", back_populates="entregas")
    alumno = relationship("Alumno", back_populates="entregas")
    calificacion = relationship("Calificacion", back_populates="entrega", uselist=False)


class Calificacion(PlatformBase):
    __tablename__ = "calificaciones"

    id_calificacion = Column(Integer, primary_key=True, index=True)
    id_entrega = Column(Integer, ForeignKey("entregas.id_entrega", ondelete="CASCADE"), unique=True, nullable=False)
    nota = Column(Numeric(5, 2), nullable=True)
    observaciones = Column(Text, nullable=True)
    fecha_calificacion = Column(DateTime, default=datetime.utcnow)

    entrega = relationship("Entrega", back_populates="calificacion")


class Progreso(PlatformBase):
    __tablename__ = "progreso"
    __table_args__ = (UniqueConstraint("id_alumno", "id_curso"),)

    id_progreso = Column(Integer, primary_key=True, index=True)
    id_alumno = Column(Integer, ForeignKey("alumnos.id_alumno", ondelete="CASCADE"), nullable=False)
    id_curso = Column(Integer, ForeignKey("cursos.id_curso", ondelete="CASCADE"), nullable=False)
    porcentaje = Column(Numeric(5, 2), default=0)

    alumno = relationship("Alumno", back_populates="progreso")
    curso = relationship("Curso", back_populates="progreso")
