import { NextResponse } from 'next/server';
import { and, eq, isNull, or } from 'drizzle-orm';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { db } from '@/lib/db';
import { systemSettings } from '@/lib/db/schema/system';
import { ValidationError, errorResponse } from '@/lib/errors';
import { env } from '@/lib/env';

/**
 * POST /api/v1/admin/documenso-webhook/test
 *
 * Fires a synthetic Documenso webhook against the local receiver to
 * verify the full pipeline: secret check, body parsing, dedup,
 * audit-log write. Echoes the receiver's response back to the
 * caller so the admin page can render success/failure inline.
 *
 * Body: { event?: string } - defaults to 'DOCUMENT_OPENED' which is
 * the lowest-impact event (no DB mutations beyond the audit-log
 * write).
 */
export const POST = withAuth(
  withPermission('admin', 'manage_settings', async (req, ctx) => {
    try {
      const [portSecretRow] = await db
        .select({ value: systemSettings.value })
        .from(systemSettings)
        .where(
          and(
            eq(systemSettings.key, 'documenso_webhook_secret'),
            or(eq(systemSettings.portId, ctx.portId), isNull(systemSettings.portId)),
          ),
        )
        .limit(1);
      const portWebhookSecret =
        typeof portSecretRow?.value === 'string' && portSecretRow.value.length > 0
          ? portSecretRow.value
          : null;
      const effectiveSecret = portWebhookSecret ?? env.DOCUMENSO_WEBHOOK_SECRET ?? null;
      if (!effectiveSecret) {
        throw new ValidationError(
          'No Documenso webhook secret configured. Set documenso_webhook_secret or DOCUMENSO_WEBHOOK_SECRET first.',
        );
      }

      const body = (await req.json().catch(() => ({}))) as { event?: string };
      const event = body.event ?? 'DOCUMENT_OPENED';

      // Synthetic payload that the receiver will accept and audit-log.
      // documentId is namespaced so a real Documenso doc can never
      // collide with this test ping.
      const payload = {
        event,
        payload: {
          id: `test-${Date.now()}`,
          status: 'PENDING',
          recipients: [],
        },
      };

      const url = `${env.APP_URL?.replace(/\/$/, '') ?? ''}/api/webhooks/documenso`;
      const startedAt = Date.now();
      const res = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Documenso-Secret': effectiveSecret,
        },
        body: JSON.stringify(payload),
      });
      const elapsedMs = Date.now() - startedAt;
      const responseBody = await res.text();
      let parsed: unknown = responseBody;
      try {
        parsed = JSON.parse(responseBody);
      } catch {
        // non-JSON response, surface as-is
      }
      return NextResponse.json({
        data: {
          ok: res.ok,
          status: res.status,
          elapsedMs,
          response: parsed,
        },
      });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
