import { NextFunction, Request, Response } from "express";
import { ApiValidationError } from "../Models/Server.Error.model";
import crypto from "crypto";
import fs from "fs";
import path from "path";
import { challenges } from "../api/SysAdminChallenges/Challenges.Controller";
import { IPayload } from "../Models/SysAdminPayload/SysAdminPayload.interface";

export async function sysAdminAuthMiddleware(
    request: Request,
    response: Response,
    next: NextFunction,
): Promise<void | Response | ApiValidationError> {
    const publicKeyPath = path.resolve(process.cwd(), process.env.SYS_ADMIN_API_PUBLIC_KEY || "");
    const publicKey = fs.readFileSync(publicKeyPath);
    const payload: IPayload = request.body.payload;

    if (payload === undefined) {
        return response
            .status(501)
            .json(new ApiValidationError(501, "No autorizado. No tiene privilegios de administrador."));
    }

    try {
        const { nonce, signature } = payload;

        if (!challenges.has(nonce.nonce)) {
            return response.status(401).end();
        }

        const ok = crypto.verify(
            null,
            Buffer.from(nonce.nonce) as unknown as Uint8Array,
            publicKey,
            Buffer.from(signature, "base64") as unknown as Uint8Array,
        );

        challenges.delete(nonce.nonce);

        if (!ok) {
            return response.status(403).end();
        }

        next();
    } catch (error) {
        return response
            .status(501)
            .json(new ApiValidationError(501, "Credenciales de acceso no validas. No autorizado"));
    }
}
