import * as dotenv from 'dotenv';

dotenv.config();

const mariadb = require('mariadb');
const prod_pool = mariadb.createPool({
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.PARTYPLANER_PROD_DATABASE,
    connectionLimit: 5
});
const dev_pool = mariadb.createPool({
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.PARTYPLANER_DEV_DATABASE,
    connectionLimit: 5
});

/**
 * Used in the getUserData method as return value
 */
export interface UserData {
    username: string;
    email: string;
    firstName: string;
    lastName: string;
    lastLogin: string;
    emailIsVerified: string;
    isPremiumUser: string;
}

/**
 * Used in the getSessionData method as return value
 */
export interface SessionData {
    sessionId: string;
    type: string;
    lastLogin: string;
    lastIp: string;
}

/**
 * Returns all data about the given user
 * @param useDev If the dev or prod database should be used
 * @param userId The userId of the user to return the data for
 * @return UserData An object containing the user data
 */
export const getUserData = async (useDev: boolean, userId: string): Promise<UserData> => {
    let conn;
    try {
        if (useDev) {
            conn = await dev_pool.getConnection();
        } else {
            conn = await prod_pool.getConnection();
        }

        let rows = await conn.query('SELECT username, email, first_name, last_Name, last_login, email_is_verified, is_premium_user FROM users WHERE user_id = ?', userId);

        let user: UserData = {} as UserData;

        for (let row in rows) {
            if (row !== 'meta') {
                user = {
                    username: rows[row].username,
                    email: rows[row].email,
                    firstName: rows[row].first_name,
                    lastName: rows[row].last_name,
                    lastLogin: rows[row].last_login,
                    emailIsVerified: rows[row].email_is_verified,
                    isPremiumUser: rows[row].is_premium_user
                };
            }
        }

        return user;
    } catch (err) {
        throw err;
    } finally {
        if (conn) {
            conn.end();
        }
    }
};

/**
 * Returns all active sessions of the given user
 * @param useDev If the dev or prod database should be used
 * @param userId The userId of the user to return the sessions for
 * @return SessionData An object containing the session data
 */
export const getSessionData = async (useDev: boolean, userId: string): Promise<SessionData[]> => {
    let conn;
    try {
        if (useDev) {
            conn = await dev_pool.getConnection();
        } else {
            conn = await prod_pool.getConnection();
        }

        let rows = await conn.query('SELECT session_id, type, last_login, last_ip FROM sessions WHERE user_id = ? AND valid_until > NOW()', userId);

        let sessions: SessionData[] = [];

        for (let row in rows) {
            if (row !== 'meta') {
                sessions.push({
                    sessionId: rows[row].session_id,
                    type: rows[row].type,
                    lastLogin: rows[row].last_login,
                    lastIp: rows[row].last_ip
                });
            }
        }

        return sessions;
    } catch (err) {
        throw err;
    } finally {
        if (conn) {
            conn.end();
        }
    }
};