"""Modelos de la base de datos - Atento a tu Futuro v2."""
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin

from extensions import db, login_manager


ROLES = ("estudiante", "instructor", "aliado", "admin", "super_admin")


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))


class User(UserMixin, db.Model):
    __tablename__ = "usuarios"
    id = db.Column(db.Integer, primary_key=True)
    nombre = db.Column(db.String(120), nullable=False)
    apellido = db.Column(db.String(120), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False, index=True)
    dni = db.Column(db.String(20), unique=True, nullable=True)
    telefono = db.Column(db.String(20), nullable=True)
    password_hash = db.Column(db.String(255), nullable=False)
    fecha_registro = db.Column(db.DateTime, default=datetime.utcnow)
    activo = db.Column(db.Boolean, default=True)

    rol = db.Column(db.String(20), default="estudiante", nullable=False, index=True)
    codigo_alianza = db.Column(db.String(20), nullable=True, index=True)
    institucion = db.Column(db.String(120), nullable=True)

    inscripciones = db.relationship("Inscripcion", backref="usuario", lazy=True)
    progresos_lecciones = db.relationship("ProgresoLeccion", backref="usuario", lazy=True)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

    @property
    def nombre_completo(self):
        return f"{self.nombre} {self.apellido}"

    @property
    def es_estudiante(self):
        return self.rol == "estudiante"

    @property
    def es_instructor(self):
        return self.rol == "instructor"

    @property
    def es_aliado(self):
        return self.rol == "aliado"

    @property
    def es_admin(self):
        return self.rol in ("admin", "super_admin")

    @property
    def es_super_admin(self):
        return self.rol == "super_admin"


class Curso(db.Model):
    __tablename__ = "cursos"
    id = db.Column(db.Integer, primary_key=True)
    titulo = db.Column(db.String(200), nullable=False)
    slug = db.Column(db.String(200), unique=True, nullable=False, index=True)
    descripcion = db.Column(db.Text, nullable=False)
    ruta = db.Column(db.String(50), nullable=False)
    duracion_min = db.Column(db.Integer, default=25)
    imagen = db.Column(db.String(255), default="/static/img/curso-default.jpg")
    video_promocional = db.Column(db.String(500), nullable=True)  # NUEVO
    publicado = db.Column(db.Boolean, default=True)
    fecha_creacion = db.Column(db.DateTime, default=datetime.utcnow)
    autor_id = db.Column(db.Integer, db.ForeignKey("usuarios.id"), nullable=True)

    modulos = db.relationship("Modulo", backref="curso", lazy=True, cascade="all, delete-orphan")
    inscripciones = db.relationship("Inscripcion", backref="curso", lazy=True)

    # Alias para compatibilidad con templates antiguos que usaban 'duracion'
    @property
    def duracion(self):
        return self.duracion_min


class Modulo(db.Model):
    __tablename__ = "modulos"
    id = db.Column(db.Integer, primary_key=True)
    curso_id = db.Column(db.Integer, db.ForeignKey("cursos.id"), nullable=False)
    titulo = db.Column(db.String(200), nullable=False)
    orden = db.Column(db.Integer, default=1)
    lecciones = db.relationship("Leccion", backref="modulo", lazy=True, cascade="all, delete-orphan")


class Leccion(db.Model):
    __tablename__ = "lecciones"
    id = db.Column(db.Integer, primary_key=True)
    modulo_id = db.Column(db.Integer, db.ForeignKey("modulos.id"), nullable=False)
    titulo = db.Column(db.String(200), nullable=False)
    contenido = db.Column(db.Text)
    video_url = db.Column(db.String(500))
    orden = db.Column(db.Integer, default=1)
    duracion_min = db.Column(db.Integer, default=5)

    tipo = db.Column(db.String(20), default="video", nullable=False)
    scorm_path = db.Column(db.String(255), nullable=True)
    scorm_entry = db.Column(db.String(255), nullable=True)
    scorm_version = db.Column(db.Integer, default=1)
    scorm_updated_at = db.Column(db.DateTime, nullable=True)

    progresos = db.relationship("ProgresoLeccion", backref="leccion", lazy=True, cascade="all, delete-orphan")


class Inscripcion(db.Model):
    __tablename__ = "inscripciones"
    id = db.Column(db.Integer, primary_key=True)
    usuario_id = db.Column(db.Integer, db.ForeignKey("usuarios.id"), nullable=False)
    curso_id = db.Column(db.Integer, db.ForeignKey("cursos.id"), nullable=False)
    fecha_inscripcion = db.Column(db.DateTime, default=datetime.utcnow)
    progreso = db.Column(db.Float, default=0.0)
    completado = db.Column(db.Boolean, default=False)
    fecha_completado = db.Column(db.DateTime, nullable=True)


class Certificado(db.Model):
    __tablename__ = "certificados"
    id = db.Column(db.Integer, primary_key=True)
    inscripcion_id = db.Column(db.Integer, db.ForeignKey("inscripciones.id"), nullable=False)
    codigo = db.Column(db.String(50), unique=True, nullable=False)
    fecha_emision = db.Column(db.DateTime, default=datetime.utcnow)
    url_pdf = db.Column(db.String(500))


class ProgresoLeccion(db.Model):
    __tablename__ = "progreso_lecciones"

    id = db.Column(db.Integer, primary_key=True)
    usuario_id = db.Column(db.Integer, db.ForeignKey("usuarios.id"), nullable=False, index=True)
    leccion_id = db.Column(db.Integer, db.ForeignKey("lecciones.id"), nullable=False, index=True)
    inscripcion_id = db.Column(db.Integer, db.ForeignKey("inscripciones.id"), nullable=True, index=True)

    lesson_status = db.Column(db.String(30), default="not attempted")
    score_raw = db.Column(db.Float, nullable=True)
    score_min = db.Column(db.Float, nullable=True)
    score_max = db.Column(db.Float, nullable=True)
    total_time = db.Column(db.String(15), default="00:00:00")
    session_time = db.Column(db.String(15), default="00:00:00")

    suspend_data = db.Column(db.Text, nullable=True)
    location = db.Column(db.String(500), nullable=True)

    completion_status = db.Column(db.String(30), nullable=True)
    success_status = db.Column(db.String(30), nullable=True)

    intentos = db.Column(db.Integer, default=0)
    fecha_inicio = db.Column(db.DateTime, nullable=True)
    fecha_ultimo_acceso = db.Column(db.DateTime, nullable=True)
    fecha_completado = db.Column(db.DateTime, nullable=True)
    ultima_version_vista = db.Column(db.Integer, default=1)

    interacciones = db.relationship("InteraccionScorm", backref="progreso", lazy=True, cascade="all, delete-orphan")

    __table_args__ = (
        db.UniqueConstraint("usuario_id", "leccion_id", name="uq_usuario_leccion"),
    )


class InteraccionScorm(db.Model):
    __tablename__ = "interacciones_scorm"

    id = db.Column(db.Integer, primary_key=True)
    progreso_leccion_id = db.Column(db.Integer, db.ForeignKey("progreso_lecciones.id"), nullable=False, index=True)
    orden = db.Column(db.Integer, default=0)

    interaction_id = db.Column(db.String(100), nullable=True)
    tipo = db.Column(db.String(50), nullable=True)
    correct_response = db.Column(db.Text, nullable=True)
    learner_response = db.Column(db.Text, nullable=True)
    result = db.Column(db.String(30), nullable=True)
    weight = db.Column(db.Float, nullable=True)
    latency = db.Column(db.String(15), nullable=True)
    timestamp_scorm = db.Column(db.String(30), nullable=True)
    fecha = db.Column(db.DateTime, default=datetime.utcnow)
