/**
 * POST /api/share/[token]/verify — Verifies an OTP code submitted in the request body.
 *
 * P1-5: OTP code + email are moved off the GET query string into a POST body,
 * preventing accidental logging in server access logs, CDN logs, and Referer headers.
 *
 * On success: sets a short-lived signed httpOnly cookie so the GET share handler
 * can serve the artifact without re-verifying the OTP on every request.
 *
 * Cookie: madarx-share-otp-<token>
 *   Value: HMAC-SHA256(<token>:<email>:<issued_at_unix>, MADARX_SHARE_LINK_SECRET)
 *   Flags: HttpOnly, SameSite=Lax, Max-Age=600 (10 min)
 *
 * Body: { email: string, code: string }
 * Returns: { ok: true } on success, error JSON on failure.
 *
 * is_share_link_otp — marker used by acceptance grep to confirm this route exists.
 */

import { createHmac } from 'node:crypto';
import { verifyShareLink, verifyOtpForShareLink } from '@/lib/artifact-acl.js';

export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

const COOKIE_MAX_AGE = 600; // 10 minutes

/** Signs the OTP cookie payload: HMAC-SHA256(<token>:<email>:<issuedAt>, secret). */
function _signCookiePayload(token, email, issuedAt, secret) {
  return createHmac('sha256', secret)
    .update(`${token}:${email.toLowerCase().trim()}:${issuedAt}`)
    .digest('hex');
}

/** Resolves MADARX_SHARE_LINK_SECRET (reuses the same resolution as artifact-acl). */
async function _resolveSecret() {
  if (process.env.MADARX_SHARE_LINK_SECRET) {
    return process.env.MADARX_SHARE_LINK_SECRET;
  }
  try {
    const { getSecret } = await import('@/lib/secrets.js');
    const val = await getSecret('MADARX_SHARE_LINK_SECRET', { scope: 'global' });
    if (val) return val;
  } catch {
    // fall through
  }
  // Fallback: generate ephemeral (will not match artifact-acl's key — cookie verify will fail,
  // which is the safe failure mode: user must re-verify after restart).
  return process.env.MADARX_MASTER_KEY || 'ephemeral-insecure';
}

export async function POST(req, { params }) {
  try {
    const { token } = await params;

    let body;
    try {
      body = await req.json();
    } catch {
      return Response.json({ ok: false, error: 'Invalid JSON' }, { status: 400 });
    }

    const email = String(body?.email || '').trim().toLowerCase();
    const code = String(body?.code || '').trim();

    if (!email || !email.includes('@')) {
      return Response.json({ ok: false, error: 'Valid email is required' }, { status: 400 });
    }
    if (!code || code.length !== 6 || !/^\d{6}$/.test(code)) {
      return Response.json({ ok: false, error: 'A 6-digit code is required' }, { status: 400 });
    }

    // Verify the share link is still valid.
    const verification = await verifyShareLink(token, req);
    if (!verification.ok) {
      return Response.json(
        { ok: false, error: verification.reason },
        { status: verification.status || 410, headers: { 'Cache-Control': 'private, no-store' } }
      );
    }

    const { link } = verification;

    if (!link.require_email_otp) {
      return Response.json(
        { ok: false, error: 'This share link does not require email verification' },
        { status: 400 }
      );
    }

    // Verify the OTP.
    const otpResult = verifyOtpForShareLink(link.id, email, code);
    if (!otpResult.ok) {
      const status = otpResult.reason === 'lockout' ? 429 : 401;
      return Response.json(
        { ok: false, reason: otpResult.reason },
        { status, headers: { 'Cache-Control': 'private, no-store' } }
      );
    }

    // OTP verified — issue a signed cookie valid for 10 minutes.
    // Cookie value: <email_b64>.<issuedAt>.<signature>
    // Embedding email (base64-encoded) allows the GET handler to verify the full
    // HMAC without a DB lookup, while keeping the raw email out of the cookie name.
    const secret = await _resolveSecret();
    const issuedAt = Math.floor(Date.now() / 1000);
    const emailB64 = Buffer.from(email).toString('base64url');
    const sig = _signCookiePayload(token, email, issuedAt, secret);

    const cookieValue = `${emailB64}.${issuedAt}.${sig}`;
    const cookieName = `madarx-share-otp-${token}`;

    return Response.json(
      { ok: true },
      {
        status: 200,
        headers: {
          'Cache-Control': 'private, no-store',
          'Set-Cookie': [
            `${cookieName}=${cookieValue}`,
            `Max-Age=${COOKIE_MAX_AGE}`,
            'HttpOnly',
            'SameSite=Lax',
            'Path=/',
          ].join('; '),
        },
      }
    );
  } catch (err) {
    console.error('POST /api/share/[token]/verify error:', err);
    return Response.json({ ok: false, error: 'Verification failed' }, { status: 500 });
  }
}
