from datetime import datetime, timedelta
import secrets
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.sql import func
from typing import Self
from flask import url_for

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Base(DeclarativeBase):
    pass

class MagicToken(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    token = db.Column(db.String(length=255, collation="utf8mb4_bin"), nullable=False)
    email = db.Column(db.String(length=255), nullable=False)
    expiration_date = db.Column(db.DateTime, nullable=False, server_default=func.now())
    used = db.Column(db.Boolean, nullable=False, default=False)
    user_dn = db.Column(db.String(length=255), nullable=False)

    def __init__(self, token, email, expiration_date, user_dn):
        self.token = token
        self.email = email
        self.expiration_date = expiration_date
        self.user_dn = user_dn

    def url(self) -> str:
        return "https://mdp.iut-fbleau.fr" + url_for('mdp.password_reset_form', token=self.token)

    @staticmethod
    def generate(emails: list[str], user_dn: str) -> Self:
        token = secrets.token_urlsafe(128)
        expiration_date = datetime.now() + timedelta(minutes=15)
        return MagicToken(token, ",".join(emails), expiration_date, user_dn)

    def __repr__(self):
        return f"<MagicToken {self.id} {self.email} {self.expiration_date} {self.used} {self.user_dn}>"