import jwt from 'jsonwebtoken';
import { Op } from 'sequelize';
import User from '../models/User.js';
import UserToken from '../models/UserToken.js';
import UserClub from '../models/UserClub.js';
import HttpError from '../exceptions/HttpError.js';
import { config } from 'dotenv';
import { devLog } from './logger.js';
config(); // sorgt dafür, dass process.env.JWT_SECRET geladen wird

export const getUserByToken = async (token) => {
    try {
        if (!token) {
            throw new HttpError('Token fehlt', 401);
        }

        // 1. JWT validieren
        let payload;
        try {
            payload = jwt.verify(token, process.env.JWT_SECRET);
        } catch (e) {
            throw new HttpError('Unauthorized: Invalid credentials', 401);
        }

        // 2. Token-Eintrag prüfen (existiert und nicht abgelaufen)
        const stored = await UserToken.findOne({
            where: {
                token,
                expiresAt: { [Op.gt]: new Date() }
            }
        });
        if (!stored) {
            throw new HttpError('Unauthorized: Invalid credentials', 401);
        }

        // 3. User laden
        const user = await User.findByPk(payload.userId);
        if (!user) {
            throw new HttpError('Benutzer nicht gefunden', 404);
        }

        return user;
    } catch (err) {
        console.error(err);
        // Falls es ein HttpError ist, einfach weiterwerfen
        if (err instanceof HttpError) throw err;
    // ansonsten: nicht maskieren, sondern als Unauthorized behandeln
    throw new HttpError('Unauthorized: Invalid credentials', 401);
    }
};

export const hasUserClubAccess = async (userId, clubId) => {
    try {
        const userClub = await UserClub.findOne({
            where: {
                user_id: userId,
                club_id: clubId,
                approved: true
            }
        });
        return userClub !== null;
    } catch (error) {
        console.error('[hasUserClubAccess] - error:', error);
        throw new HttpError('notfound', 500);
    }
}

export const checkAccess = async (userToken, clubId) => {
    try {
        const user = await getUserByToken(userToken);
    const hasAccess = await hasUserClubAccess(user.id, clubId);
        if (!hasAccess) {
            // Debug-Hilfe: keine Tokens loggen, nur userId/clubId.
            // (Wir loggen das immer, weil auf Servern NODE_ENV teils nicht gesetzt ist.)
            console.warn('[checkAccess] noaccess:', {
                userId: user?.id,
                clubId,
                clubIdType: typeof clubId,
            });
            throw new HttpError('noaccess', 403);
        }
    } catch (error) {
        throw error;
    }
};

export const checkGlobalAccess = async (userToken) => {
    try {
        const user = await getUserByToken(userToken);
        return user; // Einfach den User zurückgeben, da globale Zugriffe nur Authentifizierung benötigen
    } catch (error) {
        throw error;
    }
};
