from datetime import datetime, timedelta
from itsdangerous import URLSafeTimedSerializer as Serializer
from flask import current_app
from cpm_assessment import db
import secrets

class PasswordResetToken(db.Model):
    """
    Represents a one-time use password reset token.
    """
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    token = db.Column(db.String(64), unique=True, nullable=False, index=True)
    is_used = db.Column(db.Boolean, nullable=False, default=False)
    used_at = db.Column(db.DateTime, nullable=True)
    created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    expires_at = db.Column(db.DateTime, nullable=False)

    # Relationships
    user = db.relationship('User', backref='password_reset_tokens')

    def __init__(self, user_id, expires_in_hours=24):
        self.user_id = user_id
        self.token = secrets.token_urlsafe(32)
        self.expires_at = datetime.utcnow() + timedelta(hours=expires_in_hours)

    def is_valid(self):
        """
        Checks if this token is still valid (not used and not expired).
        """
        return not self.is_used and datetime.utcnow() < self.expires_at

    def mark_as_used(self):
        """
        Marks this token as used (one-time use).
        """
        if not self.is_used:
            self.is_used = True
            self.used_at = datetime.utcnow()
            db.session.commit()

    @staticmethod
    def find_valid_token(token_string):
        """
        Finds a valid (unused and not expired) token.
        Returns the token object if valid, otherwise None.
        """
        token = PasswordResetToken.query.filter_by(token=token_string).first()
        if token and token.is_valid():
            return token
        return None

    def __repr__(self):
        return f"PasswordResetToken(user_id={self.user_id}, token='{self.token[:8]}...', is_used={self.is_used})"