/**
 * POST /_emdash/api/setup/atproto-admin
 *
 * Step 2 of setup for atproto auth: initiate OAuth flow with user's PDS.
 * Returns the authorization URL for the client to redirect to.
 *
 * The actual admin creation happens in the OAuth callback
 * (routes/callback.ts) when the PDS redirects back.
 */

import type { APIRoute } from "astro";

export const prerender = false;

import type { ActorIdentifier } from "@atcute/lexicons";
import {
	apiError,
	apiSuccess,
	getPublicOrigin,
	handleError,
	isParseError,
	OptionsRepository,
	parseBody,
} from "emdash/api/route-utils";
import { setupAtprotoAdminBody } from "emdash/api/schemas";

export const POST: APIRoute = async ({ request, locals }) => {
	const { emdash } = locals;

	if (!emdash?.db) {
		return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
	}

	try {
		// Check if setup is already complete
		const options = new OptionsRepository(emdash.db);
		const setupComplete = await options.get("emdash:setup_complete");

		if (setupComplete === true || setupComplete === "true") {
			return apiError("SETUP_COMPLETE", "Setup already complete", 400);
		}

		// Parse request body
		const body = await parseBody(request, setupAtprotoAdminBody);
		if (isParseError(body)) return body;

		// Merge into existing setup state (preserves title/tagline from step 1)
		const existing = (await options.get<Record<string, unknown>>("emdash:setup_state")) ?? {};
		await options.set("emdash:setup_state", {
			...existing,
			step: "atproto_admin",
			handle: body.handle,
		});

		// Get OAuth client and generate authorization URL
		const url = new URL(request.url);
		const baseUrl = getPublicOrigin(url, emdash?.config);
		const { getAtprotoOAuthClient } = await import("@emdash-cms/auth-atproto/oauth-client");
		const { getAtprotoStorage } = await import("../storage.js");
		// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- emdash locals satisfy EmdashLocals shape required by getAtprotoStorage
		const storage = await getAtprotoStorage(emdash as Parameters<typeof getAtprotoStorage>[0]);
		const client = await getAtprotoOAuthClient(baseUrl, storage);

		const { url: authUrl } = await client.authorize({
			// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- body.handle is a validated string, ActorIdentifier is atcute's branded type
			target: { type: "account", identifier: body.handle as ActorIdentifier },
		});

		return apiSuccess({
			url: authUrl.toString(),
		});
	} catch (error) {
		return handleError(error, "Failed to start AT Protocol setup", "SETUP_ATPROTO_ERROR");
	}
};
