import { NextResponse } from 'next/server';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { errorResponse } from '@/lib/errors';
import { entriesForSections } from '@/lib/settings/registry';
import { resolveForAdminAPI } from '@/lib/settings/resolver';

/**
 * GET /api/v1/admin/settings/resolved?sections=documenso.api,documenso.signers
 *
 * Returns the resolved value + source (port/global/env/default) for every
 * registry entry in the requested sections. Drives the registry-driven
 * admin form: the `source` field gates the "Using env fallback" badge.
 *
 * Sensitive fields surface `isSet` only — never the decrypted value.
 */
export const GET = withAuth(
  withPermission('admin', 'manage_settings', async (req, ctx) => {
    try {
      const url = new URL(req.url);
      const sectionsParam = url.searchParams.get('sections');
      if (!sectionsParam) {
        return NextResponse.json({ data: { entries: [], values: {} } }, { status: 200 });
      }
      const sections = sectionsParam
        .split(',')
        .map((s) => s.trim())
        .filter(Boolean);
      const entries = entriesForSections(sections);
      const keys = entries.map((e) => e.key);
      const resolved = await resolveForAdminAPI(keys, ctx.portId);

      // Return the entry metadata so the client can render labels/types
      // without bundling the registry into the client JS. Strip the
      // `validator` + `transform` function references — they're not
      // JSON-serializable.
      const entriesForClient = entries.map((e) => ({
        key: e.key,
        section: e.section,
        label: e.label,
        description: e.description,
        type: e.type,
        options: e.options,
        encrypted: !!e.encrypted,
        sensitive: !!(e.sensitive || e.encrypted),
        scope: e.scope,
        envFallback: e.envFallback,
        placeholder: e.placeholder,
        defaultValue: e.defaultValue,
      }));

      const values: Record<string, unknown> = {};
      for (const [k, r] of resolved.entries()) {
        values[k] = r;
      }

      return NextResponse.json({ data: { entries: entriesForClient, values } });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
