/**
 * Single media item endpoint
 *
 * GET /_emdash/api/media/:id - Get media item
 * PUT /_emdash/api/media/:id - Update media metadata
 * DELETE /_emdash/api/media/:id - Delete media item
 */

import type { APIRoute } from "astro";

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

export const prerender = false;

/**
 * Get media item
 */
export const GET: APIRoute = async ({ params, locals }) => {
	const { emdash, user } = locals;
	const { id } = params;

	const readDenied = requirePerm(user, "media:read");
	if (readDenied) return readDenied;

	if (!id) {
		return apiError("INVALID_REQUEST", "Media ID required", 400);
	}

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

	const result = await emdash.handleMediaGet(id);
	return unwrapResult(result);
};

/**
 * Update media metadata
 *
 * Authors can edit their own media; editors+ can edit any.
 */
export const PUT: APIRoute = async ({ params, request, locals }) => {
	const { emdash, user } = locals;
	const { id } = params;

	// Minimum permission gate — ownership checked below
	const editDenied = requirePerm(user, "media:edit_own");
	if (editDenied) return editDenied;

	if (!id) {
		return apiError("INVALID_REQUEST", "Media ID required", 400);
	}

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

	try {
		// Fetch media item for ownership check
		const getResult = await emdash.handleMediaGet(id);
		if (!getResult.success || !getResult.data?.item) {
			return apiError("NOT_FOUND", "Media item not found", 404);
		}

		const media = getResult.data.item;

		// Ownership check: authors can edit own, editors+ can edit any
		const ownerDenied = requireOwnerPerm(user, media.authorId, "media:edit_own", "media:edit_any");
		if (ownerDenied) return ownerDenied;

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

		const result = await emdash.handleMediaUpdate(id, {
			alt: body.alt,
			caption: body.caption,
			width: body.width,
			height: body.height,
		});

		return unwrapResult(result);
	} catch (error) {
		return handleError(error, "Failed to update media", "MEDIA_UPDATE_ERROR");
	}
};

/**
 * Delete media item
 *
 * Authors can delete their own media; editors+ can delete any.
 */
export const DELETE: APIRoute = async ({ params, locals }) => {
	const { emdash, user } = locals;
	const { id } = params;

	// Minimum permission gate — ownership checked below
	const deleteDenied = requirePerm(user, "media:delete_own");
	if (deleteDenied) return deleteDenied;

	if (!id) {
		return apiError("INVALID_REQUEST", "Media ID required", 400);
	}

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

	try {
		// Fetch media item for ownership check and storage key
		const getResult = await emdash.handleMediaGet(id);
		if (!getResult.success || !getResult.data?.item) {
			return apiError("NOT_FOUND", "Media item not found", 404);
		}

		const media = getResult.data.item;

		// Ownership check: authors can delete own, editors+ can delete any
		const ownerDenied = requireOwnerPerm(
			user,
			media.authorId,
			"media:delete_own",
			"media:delete_any",
		);
		if (ownerDenied) return ownerDenied;

		// Delete file from storage via the storage adapter
		if (emdash.storage) {
			try {
				await emdash.storage.delete(media.storageKey);
			} catch {
				// Best-effort — continue with database deletion
			}
		}

		// Delete from database
		const result = await emdash.handleMediaDelete(id);

		return unwrapResult(result);
	} catch (error) {
		return handleError(error, "Failed to delete media", "MEDIA_DELETE_ERROR");
	}
};
