/**
 * LogLift evidence webhook.
 *
 * The Datto RMM collector component uploads gzipped event-log JSON to B2,
 * then POSTs the metadata here. Pulse downloads the gzip, slims it, persists
 * it as RMM evidence, and (when the hostname matches a single IT Glue
 * Configuration) fires an asset-first audit on the side.
 *
 * Auth: `x-openclaw-key` header — same shared secret the collector already
 * carries for OpenClaw API calls.
 *
 * Public route per `middleware.ts` (`/api/rmm/loglift` exclusion).
 */

import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';

import { validateOpenClawKey } from '@/lib/utils/openclaw-auth';
import { OBJECT_KEY_REGEX } from '@/lib/services/b2/client';
import { processLogliftWebhook } from '@/lib/services/rmm/loglift-receiver';

export const dynamic = 'force-dynamic';
export const maxDuration = 60;

const WebhookSchema = z.object({
  runId: z.string().min(1).max(200),
  clientId: z.string().min(1).max(200),
  computerName: z.string().min(1).max(200),
  deviceUid: z.string().max(200).nullable().optional(),
  summary: z.object({
    totalEvents: z.number().int().nonnegative().nullable().optional(),
    criticalEvents: z.number().int().nonnegative().nullable().optional(),
    errorCount: z.number().int().nonnegative().nullable().optional(),
    warningCount: z.number().int().nonnegative().nullable().optional(),
    timeRange: z.string().max(200).nullable().optional(),
  }),
  objectKey: z
    .string()
    .min(1)
    .max(500)
    .refine((s) => OBJECT_KEY_REGEX.test(s), {
      message: 'objectKey does not match the required eventlogs path shape',
    }),
  collectedAt: z.string().min(1).max(64),
  rmmContext: z
    .object({
      siteName: z.string().max(200).nullable().optional(),
      siteUid: z.string().max(200).nullable().optional(),
      accountUid: z.string().max(200).nullable().optional(),
    })
    .partial()
    .nullable()
    .optional(),
  issueDescription: z.string().max(4000).nullable().optional(),
  ticketNumber: z.string().max(64).nullable().optional(),
});

export async function POST(req: NextRequest) {
  const auth = validateOpenClawKey(req);
  if (auth) return auth;

  let raw: unknown;
  try {
    raw = await req.json();
  } catch {
    return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 });
  }

  const parsed = WebhookSchema.safeParse(raw);
  if (!parsed.success) {
    return NextResponse.json(
      {
        error: 'Invalid payload',
        details: parsed.error.flatten(),
      },
      { status: 400 }
    );
  }

  try {
    const result = await processLogliftWebhook(parsed.data);
    return NextResponse.json(
      {
        executionId: result.executionId,
        matched: result.matched,
        parsed: result.parsed,
        auditId: result.audit_id,
      },
      { status: 200 }
    );
  } catch (err) {
    const message = err instanceof Error ? err.message : String(err);
    console.error('[LOGLIFT-WEBHOOK]', message, err);
    return NextResponse.json(
      { error: 'Failed to process LogLift webhook', message },
      { status: 500 }
    );
  }
}
