/**
 * Reorder widgets endpoint
 *
 * POST /_emdash/api/widget-areas/:name/reorder
 */

import type { APIRoute } from "astro";

import { requirePerm } from "#api/authorize.js";
import { apiError, apiSuccess, handleError } from "#api/error.js";
import { isParseError, parseBody } from "#api/parse.js";
import { reorderWidgetsBody } from "#api/schemas.js";

export const prerender = false;

export const POST: APIRoute = async ({ params, request, locals }) => {
	const { emdash, user } = locals;
	const db = emdash.db;
	const { name } = params;

	const denied = requirePerm(user, "widgets:manage");
	if (denied) return denied;

	if (!name) {
		return apiError("VALIDATION_ERROR", "name is required", 400);
	}

	try {
		// Get the area
		const area = await db
			.selectFrom("_emdash_widget_areas")
			.select("id")
			.where("name", "=", name)
			.executeTakeFirst();

		if (!area) {
			return apiError("NOT_FOUND", `Widget area "${name}" not found`, 404);
		}

		const body = await parseBody(request, reorderWidgetsBody);
		if (isParseError(body)) return body;

		// Verify all widget IDs belong to this area
		const existingWidgets = await db
			.selectFrom("_emdash_widgets")
			.select("id")
			.where("area_id", "=", area.id)
			.execute();

		const existingIds = new Set(existingWidgets.map((w) => w.id));
		for (const id of body.widgetIds) {
			if (!existingIds.has(id)) {
				return apiError("VALIDATION_ERROR", `Widget "${id}" not found in area "${name}"`, 400);
			}
		}

		// Update sort_order for each widget
		await Promise.all(
			body.widgetIds.map((id, index) =>
				db
					.updateTable("_emdash_widgets")
					.set({ sort_order: index })
					.where("id", "=", id)
					.execute(),
			),
		);

		return apiSuccess({ success: true });
	} catch (error) {
		return handleError(error, "Failed to reorder widgets", "WIDGET_REORDER_ERROR");
	}
};
