/**
 * POST /api/admin/device-link-conflicts/[id]/resolve
 *   Body: { ciId: string, note?: string }
 *
 * Resolves a conflict by manually picking a configuration_item to link the
 * underlying device_external_ids row to. Sets link_confidence='manual' and
 * marks the review row resolved.
 *
 * Validates that ciId is in candidate_ci_ids — admins can't pick an arbitrary
 * CI here. (For an arbitrary-CI override, separate flow.)
 */

import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { requirePermission } from '@/lib/auth-utils';
import postgresClient from '@/lib/services/postgres-client';

const ResolveBody = z.object({
  ciId: z.string().regex(/^\d+$/, 'ciId must be numeric'),
  note: z.string().max(500).optional(),
});

export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { session, error } = await requirePermission('admin', 'access');
  if (error) return error;

  const { id } = await params;
  if (!/^[0-9a-f-]{36}$/i.test(id)) {
    return NextResponse.json({ error: 'Invalid review id' }, { status: 400 });
  }

  let body: unknown;
  try {
    body = await request.json();
  } catch {
    return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 });
  }
  const parsed = ResolveBody.safeParse(body);
  if (!parsed.success) {
    return NextResponse.json(
      { error: 'Invalid payload', details: parsed.error.flatten() },
      { status: 400 }
    );
  }

  const ciIdNum = Number(parsed.data.ciId);

  return postgresClient.transaction(async (tx) => {
    const reviewRes = await tx.query<{
      device_external_id: string;
      candidate_ci_ids: string[];
      resolved_at: string | null;
    }>(
      `SELECT device_external_id::text, candidate_ci_ids::text[], resolved_at::text
         FROM device_link_review
        WHERE id = $1
        FOR UPDATE`,
      [id]
    );
    if (reviewRes.rowCount === 0) {
      return NextResponse.json({ error: 'Review not found' }, { status: 404 });
    }
    const review = reviewRes.rows[0];
    if (review.resolved_at) {
      return NextResponse.json({ error: 'Already resolved' }, { status: 409 });
    }
    if (!review.candidate_ci_ids.map(String).includes(String(ciIdNum))) {
      return NextResponse.json(
        { error: 'ciId must be one of the conflict candidates' },
        { status: 400 }
      );
    }

    await tx.query(
      `UPDATE device_external_ids
          SET configuration_item_id = $2,
              link_confidence       = 'manual',
              linked_at             = NOW()
        WHERE id = $1`,
      [review.device_external_id, ciIdNum]
    );

    await tx.query(
      `UPDATE device_link_review
          SET resolved_at         = NOW(),
              resolved_by_user_id = $2,
              resolved_to_ci_id   = $3,
              resolution_note     = $4
        WHERE id = $1`,
      [id, session?.user?.id ?? null, ciIdNum, parsed.data.note ?? null]
    );

    return NextResponse.json({ ok: true, resolvedToCiId: String(ciIdNum) });
  });
}
