import {Response, Request, NextFunction} from 'express'
import jwt from "jsonwebtoken"
import UserRepository from "../repository/UserRepository";

export default class CardController {

    TOKEN_SECRET = process.env.TOKEN_SECRET || 'ZnJhbnRpYw'

    constructor(private userRepository : UserRepository) {}

    private extractToken (req : Request) {
        if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
            return req.headers.authorization.split(' ')[1];
        } else if (req.query && req.query.token) {
            return req.query.token;
        }
        return null;
    }

    private async unauthorized(req: Request, res : Response) {
        res.statusCode  = 401;
        return res.json();
    }

    private generateAccessToken(username : object) {
        return jwt.sign(username, this.TOKEN_SECRET, { expiresIn: '900000000s' });
    }

    async login(req: Request, res: Response) {
        const username = req.body.username
        const password = req.body.password
        const user = await this.userRepository.getFirst({username, password})
        if (user != null) {
            const token = this.generateAccessToken({ username });
            res.cookie('jwt', token); // Should be httpOnly
            res.json({token});
        } else {
            res.statusCode  = 401;
            res.json();
        }
    }

    async logout(req: Request, res: Response) {
        res.clearCookie('jwt');
        res.end()
    }

    async isAuthenticated(req: Request, res : Response, next : NextFunction) {
        if(process.env.AUTHENTICATION === 'false') return next()
        if(req.cookies?.jwt === undefined && req.header('Authorization') === undefined) return this.unauthorized(req, res)
        const token = req.cookies.jwt || this.extractToken(req)
        jwt.verify(token, this.TOKEN_SECRET, (err : any, user : any) => {
            if (err) return this.unauthorized(req, res)
            // @ts-ignore
            req.user = user
            return next()
        })
    }


}
