from app import db
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime, timedelta

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password_hash = db.Column(db.String(128))
    role = db.Column(db.String(20), nullable=False)
    is_approved = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    # Student specific fields
    roll_number = db.Column(db.String(20))
    section = db.Column(db.String(10))
    program = db.Column(db.String(50))
    department = db.Column(db.String(50))
    semester = db.Column(db.Integer)
    phone_number = db.Column(db.String(15))
    
    # Learning stats
    last_login = db.Column(db.DateTime)
    current_streak = db.Column(db.Integer, default=0)
    longest_streak = db.Column(db.Integer, default=0)
    last_streak_date = db.Column(db.Date)
    
    # Relationships
    teacher_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    students = db.relationship('User', 
                             backref=db.backref('teacher', remote_side=[id]),
                             lazy='dynamic')
    topics = db.relationship('Topic', backref='teacher', lazy='dynamic')
    progress_records = db.relationship('Progress', backref='student', lazy='dynamic')
    
    def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)
        
        # Ensure last_login is a datetime if provided, otherwise None
        if 'last_login' in kwargs and kwargs['last_login']:
            if isinstance(kwargs['last_login'], str):
                try:
                    self.last_login = datetime.fromisoformat(kwargs['last_login'])
                except ValueError:
                    self.last_login = None
            else:
                self.last_login = kwargs['last_login']
        else:
            self.last_login = None
    
    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)
        
    def update_login_streak(self):
        """Update login streak based on current login time"""
        today = datetime.utcnow().date()
        
        # If last_streak_date is None, this is the first login
        if self.last_streak_date is None:
            self.current_streak = 1
            self.longest_streak = 1
            self.last_streak_date = today
            return
            
        # If last login was today, no streak update needed
        if self.last_streak_date == today:
            return
            
        # If last login was yesterday, increment streak
        if self.last_streak_date == today - timedelta(days=1):
            self.current_streak += 1
            if self.current_streak > self.longest_streak:
                self.longest_streak = self.current_streak
        # If last login was more than a day ago, reset streak
        else:
            self.current_streak = 1
            
        self.last_streak_date = today
        
    def get_vocabulary_count(self):
        """Get the number of vocabulary words saved by this user"""
        from app.models.vocabulary import Vocabulary
        return Vocabulary.query.filter_by(student_id=self.id).count()
    
    def to_dict(self):
        data = {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'role': self.role,
            'is_approved': self.is_approved,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'teacher_id': self.teacher_id
        }
        
        if self.role == 'student':
            data.update({
                'roll_number': self.roll_number,
                'section': self.section,
                'program': self.program,
                'department': self.department
            })
        elif self.role == 'teacher':
            data.update({
                'student_count': self.students.count(),
                'topic_count': self.topics.count()
            })
            
        return data
    
    def __repr__(self):
        return f'<User {self.username}>'
