import { decrypt } from "@/lib/cipher";
import { ADMIN_SESSION_TOKEN_DEFAULTS, ADMIN_SESSION_ID_TOKEN_DEFAULTS } from "@/lib/cookie";
import { error } from "@/lib/response";
import { logError } from "@/lib/logger";
import { verifySession } from "@/lib/session";
import type { Context, Next } from "hono";
import { getCookie } from "hono/cookie";
import { decode } from "hono/jwt";
import { AdminConsoleSessionRepository } from "@/internal/repository/admin_console/admin_console_session";
// import { isAdminSessionBlacklisted } from "@/lib/session";

export async function adminAuthMiddleware(ctx: Context, next: Next) {
    const sessionToken = getCookie(ctx, ADMIN_SESSION_TOKEN_DEFAULTS.name) || getCookie(ctx, "admin_session") || getCookie(ctx, "kc_session");
    const adminSessionId = getCookie(ctx, ADMIN_SESSION_ID_TOKEN_DEFAULTS.name) || getCookie(ctx, "admin_session_id") || getCookie(ctx, "kc_session_id");

    if (!sessionToken || !adminSessionId) {
        logError(`adminAuthMiddleware: Missing session tokens in cookies. Found Session: ${!!sessionToken}, ID: ${!!adminSessionId}`);
        return error(ctx, "Unauthorized", 401);
    }

    const db = ctx.get("datastore");
    if (db) {
        const sessionRepo = new AdminConsoleSessionRepository(db);
        const session = await sessionRepo.getSessionById(adminSessionId);
        if (!session) {
            logError("adminAuthMiddleware: Session not found in database");
            return error(ctx, "Unauthorized", 401);
        }
    }

    try {
        const decryptedToken = decrypt(sessionToken);

        // Redis Blacklist Check
        const redis = ctx.get("redisDB");
        if (redis) {
            // const isBlacklisted = await isAdminSessionBlacklisted(redis, decryptedToken);
            // if (isBlacklisted) {
            //     logError("adminAuthMiddleware: Session token is blacklisted");
            //     return error(ctx, "Unauthorized", 401);
            // }
        }

        const isValid = await verifySession(decryptedToken);

        if (!isValid) {
            logError("adminAuthMiddleware: Session token verification failed (expired or invalid JWT)");
            return error(ctx, "Unauthorized", 401);
        }

        try {
            const { payload: decoded } = decode(decryptedToken) as { payload: { email?: string } };
            if (decoded.email) {
                ctx.set("adminEmail", decoded.email);
            }
        } catch (e) { /* ignore decode error, verification already happened */ }

        await next();
    } catch (err) {
        logError(`adminAuthMiddleware: Error during authentication: ${err}`);
        return error(ctx, "Unauthorized", 401);
    }
}
