import { NextResponse } from 'next/server';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { errorResponse } from '@/lib/errors';
import { readSetting, SETTING_KEYS } from '@/lib/services/port-config';
import { fetchWithTimeout, FetchTimeoutError } from '@/lib/fetch-with-timeout';
import { logger } from '@/lib/logger';

/**
 * POST /api/v1/admin/embedded-signing/test
 *
 * Verifies that the configured `embedded_signing_host` (the marketing
 * site that hosts the branded embedded-signing wrapper) is reachable
 * and returns a 2xx for the test path. Used by the admin "Test
 * connection" button on the Documenso settings page so an admin can
 * tell whether their marketing-site cutover is ready BEFORE signers
 * get sent there from outbound emails.
 *
 * Two checks:
 *   1. Bare host returns 2xx - the site is up.
 *   2. `/sign/health` (or `/`) returns 2xx within 5s - soft probe; not
 *      every marketing site exposes /sign/health, so we degrade to a
 *      root probe when the dedicated path 404s.
 */
export const POST = withAuth(
  withPermission('admin', 'manage_settings', async (_req, ctx) => {
    try {
      const host = await readSetting<string>(SETTING_KEYS.embeddedSigningHost, ctx.portId);
      if (!host) {
        return NextResponse.json({
          data: {
            ok: false,
            error: 'No embedded_signing_host configured. Set the URL in Documenso settings first.',
          },
        });
      }

      const checked: Array<{ path: string; status?: number; ok: boolean; error?: string }> = [];
      const probe = async (path: string) => {
        try {
          const res = await fetchWithTimeout(`${host.replace(/\/$/, '')}${path}`, {
            method: 'GET',
            redirect: 'manual',
          });
          checked.push({
            path,
            status: res.status,
            ok: res.ok || (res.status >= 300 && res.status < 400),
          });
          return res.status;
        } catch (err) {
          const msg =
            err instanceof FetchTimeoutError
              ? `timed out after ${err.timeoutMs}ms`
              : err instanceof Error
                ? err.message
                : String(err);
          checked.push({ path, ok: false, error: msg });
          return null;
        }
      };

      // Try root first - it's the most universal signal of "the site is
      // up." Then probe /sign/success which the post-signing redirect
      // typically points to, so admins can also catch a stale path.
      await probe('/');
      await probe('/sign/success');

      const anyOk = checked.some((c) => c.ok);
      if (!anyOk) {
        logger.warn({ portId: ctx.portId, host, checked }, 'Embedded signing host probe failed');
      }
      return NextResponse.json({
        data: {
          ok: anyOk,
          host,
          checks: checked,
        },
      });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
