from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
import os
from config import UPLOAD_FOLDER
from flask_login import UserMixin

db = SQLAlchemy()

class Favorite(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    paste_id = db.Column(db.Integer, db.ForeignKey('paste.id'), nullable=False)
    created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)

    user = db.relationship('User', backref=db.backref('favorites', lazy=True))
    paste = db.relationship('Paste', backref=db.backref('favorited_by', lazy=True))

    paste_favorites = db.Table(
    'paste_favorites',
    db.Column('user_id', db.Integer, db.ForeignKey('user.id'), primary_key=True),
    db.Column('paste_id', db.Integer, db.ForeignKey('paste.id'), primary_key=True)
    )
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password_hash = db.Column(db.String(128), nullable=False)
    role = db.Column(db.String(10), nullable=False, default='user')
    storage_used = db.Column(db.BigInteger, nullable=False, default=0)  # En bytes
    storage_limit = db.Column(db.BigInteger, nullable=False, default=1 * 1024**3) 
    theme_preference = db.Column(db.String(10), default="light")  # Guardar "light" o "dark"
    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 has_unlimited_storage(self):
        return self.storage_limit == -1

    def get_storage_limit(self):
        """Devuelve el límite de almacenamiento del usuario."""
        return self.storage_limit

shared_pastes = db.Table(
    'shared_pastes',
    db.Column('paste_id', db.Integer, db.ForeignKey('paste.id'), primary_key=True),
    db.Column('user_id', db.Integer, db.ForeignKey('user.id'), primary_key=True),
    db.Column('can_edit', db.Boolean, default=False)  # Nuevo campo para indicar permiso de edición
)        

# Tabla intermedia para usuarios con permisos de edición
paste_editors = db.Table(
    'paste_editors',
    db.Column('paste_id', db.Integer, db.ForeignKey('paste.id'), primary_key=True),
    db.Column('user_id', db.Integer, db.ForeignKey('user.id'), primary_key=True)
)

class Paste(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255), nullable=True)
    editable = db.Column(db.Boolean, default=True)
    content_type = db.Column(db.String(50), nullable=False)
    filename = db.Column(db.String(255), nullable=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    expires_at = db.Column(db.DateTime, nullable=True)  # Nuevo campo de expiración
    language = db.Column(db.String(50), nullable=True)
    last_edited_at = db.Column(db.DateTime, nullable=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    size = db.Column(db.Integer, nullable=True)

    # Relaciones
    editors = db.relationship('User', secondary=paste_editors, backref=db.backref('editable_pastes', lazy='dynamic'))
    owner = db.relationship('User', backref=db.backref('owned_pastes', lazy=True), foreign_keys=[owner_id])
    favorites = db.relationship('User', secondary='paste_favorites', backref=db.backref('favorite_pastes', lazy='dynamic'))
    shared_with = db.relationship('User', secondary=shared_pastes, backref=db.backref('shared_pastes', lazy='dynamic'))

    owner = db.relationship(
        'User',
        backref=db.backref('owned_pastes', lazy=True),
        foreign_keys=[owner_id]
    )
    favorites = db.relationship(
        'User',
        secondary='paste_favorites',
        backref=db.backref('favorite_pastes', lazy='dynamic')
    )
    def is_expired(self):
        """ Verifica si el paste ha expirado. """
        return self.expires_at and datetime.utcnow() > self.expires_at
    def to_dict(self):
        return {
            "id": self.id,
            "content_type": self.content_type,
            "filename": self.filename,
            "owner_id": self.owner_id,
            "created_at": self.created_at.isoformat(),
            "language": self.language,
            "user_id": self.user_id,
            "size": self.file_size 
        }


    def get_size(self):
        file_path = os.path.join(UPLOAD_FOLDER, self.filename)
        try:
            return os.path.getsize(file_path)  # Devuelve el tamaño del archivo
        except FileNotFoundError:
            return 0

    def get_type(self):
        # Determinar el tipo de archivo basado en content_type
        if self.content_type.startswith("video"):
            return "Video"
        elif self.content_type.startswith("audio"):
            return "Audio"
        elif self.content_type.startswith("image"):
            return "Image"
        elif self.content_type in ["application/zip", "application/x-tar", "application/gzip", "application/x-bzip2", "application/x-7z-compressed", "application/x-rar-compressed"]:
            return "Compressed"
        elif self.content_type.startswith("text"):
            if self.language:
                return f"Text ({self.language})"
            return "Text"
        else:
            return "Other"

    def has_edit_permission(self, user):
        """
        Verifica si un usuario tiene permiso de edición en este paste.
        """
        # Si el usuario no está autenticado, no puede tener permisos
        if not user.is_authenticated:
            print(f"[DEBUG] Unauthenticated user tried to edit paste {self.id}. Permission denied.")
            return False

        # El dueño del paste siempre tiene permisos
        if user.id == self.owner_id:
            print(f"[DEBUG] User {user.id} is the owner of paste {self.id}. Permission granted.")
            return True

        # Verificar si el usuario tiene permisos en `shared_pastes`
        shared_entry = db.session.query(shared_pastes).filter_by(
            paste_id=self.id,
            user_id=user.id,
            can_edit=True
        ).first()

        if shared_entry:
            print(f"[DEBUG] User {user.id} has edit permissions for paste {self.id}.")
        else:
            print(f"[DEBUG] User {user.id} does NOT have edit permissions for paste {self.id}.")

        return shared_entry is not None

