import { NextFunction, Response } from "express";
import { Logger, ILogObj } from "tslog";
import { Request, expressjwt } from "express-jwt";
import fs from "fs";
import { Language } from "../langs/lang";
import { ReturnHelper } from "./express/return";
import express from "express";
import config from "config";
import jwt from "jsonwebtoken";

const log: Logger<ILogObj> = new Logger({ name: "[JwtHelper]", type: "pretty" });

export default class JwtHelper {
	static secure = (app: express.Application) => {
		var publicKey = fs.readFileSync("src/helpers/key/public.key");

		app.use(
			expressjwt({
				secret: publicKey,
				algorithms: ["RS256"],
				getToken: function fromHeaderOrQuerystring(req): any {
					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;
				},
			}).unless({
				path: [
					"/token",
					/^\/uploads\/.*/, // ⚠️ TAMBAHKAN INI - exclude semua path /uploads/
				],
			}),
			function (req: Request, res: Response, next: NextFunction) {
				if (!req.auth?.data.id) {
					return ReturnHelper.errorResponse(res, 403, 666, Language.lang.failed_access);
				}

				return next();
			},
		);

		app.use(function (err: any, req: Request, res: Response, next: NextFunction) {
			if (err.name === "UnauthorizedError") {
				return ReturnHelper.errorResponse(res, 403, 666, Language.lang.failed_access);
			}

			return next();
		});
	};

	static token = (user: { id: string; username: string; name: string }) => {
		var privateKey = fs.readFileSync("src/helpers/key/private.key");
		var token = jwt.sign(
			{
				exp: Math.floor(Date.now() / 1000) + Number(config.get("auth.access_token_lifetime")),
				data: {
					id: user.id,
					username: user.username,
					name: user.name,
				},
			},
			privateKey,
			{ algorithm: "RS256" },
		);
		return token;
	};
}
