import type { APIRoute } from 'astro';
import { z } from 'astro:schema';
import { checkApiBasicAuth } from '@util/auth.ts';

export function externalApi<InputSchema extends z.ZodType | undefined>(params: {
  input?: InputSchema;
  auth?: boolean;
  handler: ({
    input,
    params
  }: {
    input: InputSchema extends z.ZodType ? z.infer<InputSchema> : {};
    params: Record<string, string | undefined>;
  }) => Response | Promise<Response>;
}): APIRoute {
  return async (context) => {
    if (params.auth && !checkApiBasicAuth(context.request.headers)) {
      return new Response(null, { status: 401 });
    }

    let input;
    if (params.input) {
      try {
        input = await params.input.parseAsync(await context.request.json());
      } catch (_) {
        return new Response(null, { status: 400 });
      }
    } else {
      input = {};
    }

    return params.handler({ input: input, params: context.params });
  };
}
