/**
 * OIDC interaction handler — checks for an existing Ghost Guild session.
 *
 * Flow:
 * 1. Outline redirects user to /oidc/auth
 * 2. oidc-provider creates an interaction and redirects here
 * 3. If the user has a valid auth-token cookie → complete the interaction (SSO)
 * 4. Otherwise → redirect to the OIDC login page
 */
import jwt from "jsonwebtoken";
import Member from "../../../models/member.js";
import { connectDB } from "../../../utils/mongoose.js";
import { getOidcProvider } from "../../../utils/oidc-provider.js";

export default defineEventHandler(async (event) => {
  const provider = await getOidcProvider();
  const uid = getRouterParam(event, "uid")!;

  // Load the interaction details from oidc-provider
  const interactionDetails = await provider.interactionDetails(
    event.node.req,
    event.node.res
  );
  const { prompt } = interactionDetails;

  // ----- Login prompt -----
  if (prompt.name === "login") {
    // Check for existing Ghost Guild session
    const token = getCookie(event, "auth-token");

    if (token) {
      try {
        const config = useRuntimeConfig();
        const decoded = jwt.verify(token, config.jwtSecret) as {
          memberId: string;
        };

        await connectDB();
        const member = await (Member as any).findById(decoded.memberId);

        if (
          member &&
          member.status !== "suspended" &&
          member.status !== "cancelled"
        ) {
          // Auto-complete the login interaction (SSO)
          const result = {
            login: { accountId: member._id.toString() },
          };
          await provider.interactionFinished(
            event.node.req,
            event.node.res,
            result,
            { mergeWithLastSubmission: false }
          );
          return;
        }
      } catch {
        // Token invalid — fall through to login page
      }
    }

    // No valid session — redirect to login page
    return sendRedirect(event, `/auth/wiki-login?uid=${uid}`, 302);
  }

  // ----- Consent prompt -----
  if (prompt.name === "consent") {
    // Auto-approve consent for our first-party client
    const grant = interactionDetails.grantId
      ? await provider.Grant.find(interactionDetails.grantId)
      : new provider.Grant({
          accountId: interactionDetails.session!.accountId,
          clientId: interactionDetails.params.client_id as string,
        });

    if (grant) {
      grant.addOIDCScope("openid profile email");
      await grant.save();

      const result = { consent: { grantId: grant.jti } };
      await provider.interactionFinished(
        event.node.req,
        event.node.res,
        result,
        { mergeWithLastSubmission: true }
      );
      return;
    }
  }

  // Fallback — shouldn't reach here normally
  throw createError({ statusCode: 400, statusMessage: "Unknown interaction" });
});
