/**
 * GET /api/admin/device-link-conflicts
 *   Returns unresolved device-link reviews with candidate CI details, paged.
 *   Query params:
 *     limit  (default 50, max 200)
 *     offset (default 0)
 *     source (filter: 'datto_rmm' | 'itglue' | ...)
 */

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

interface ReviewRow {
  id: string;
  detected_at: string;
  xref_id: string;
  source: string;
  source_id: string;
  hostname: string | null;
  serial: string | null;
  mac: string | null;
  xref_company_id: string | null;
  xref_company_name: string | null;
  last_seen_at: string | null;
  candidate_ci_ids: string[];
  match_confidences: string[];
}

interface CiRow {
  id: string;
  reference_title: string | null;
  serial_number: string | null;
  rmm_device_audit_mac_address: string | null;
  company_id: string | null;
  company_name: string | null;
  is_deleted: boolean;
}

export async function GET(request: NextRequest) {
  const { error } = await requirePermission('admin', 'access');
  if (error) return error;

  const url = request.nextUrl;
  const limit = Math.min(parseInt(url.searchParams.get('limit') ?? '50', 10) || 50, 200);
  const offset = Math.max(parseInt(url.searchParams.get('offset') ?? '0', 10) || 0, 0);
  const source = url.searchParams.get('source');

  const params: unknown[] = [limit, offset];
  let sourceFilter = '';
  if (source) {
    params.push(source);
    sourceFilter = `AND dx.source = $${params.length}`;
  }

  const reviews = await postgresClient.query<ReviewRow>(
    `SELECT r.id::text, r.detected_at::text, r.candidate_ci_ids::text[],
            r.match_confidences,
            dx.id::text AS xref_id, dx.source, dx.source_id,
            dx.hostname, dx.serial, dx.mac,
            dx.company_id::text AS xref_company_id,
            c.company_name AS xref_company_name,
            dx.last_seen_at::text
       FROM device_link_review r
       JOIN device_external_ids dx ON dx.id = r.device_external_id
       LEFT JOIN companies c ON c.id = dx.company_id
      WHERE r.resolved_at IS NULL
        ${sourceFilter}
      ORDER BY r.detected_at DESC
      LIMIT $1 OFFSET $2`,
    params
  );

  // Bulk-fetch all candidate CI details in one query.
  const allCiIds = new Set<string>();
  for (const r of reviews.rows) {
    for (const id of r.candidate_ci_ids ?? []) allCiIds.add(String(id));
  }
  const ciDetails = new Map<string, CiRow>();
  if (allCiIds.size > 0) {
    const ciRes = await postgresClient.query<CiRow>(
      `SELECT ci.id::text, ci.reference_title, ci.serial_number,
              ci.rmm_device_audit_mac_address,
              ci.company_id::text AS company_id,
              c.company_name, COALESCE(ci.is_deleted, false) AS is_deleted
         FROM configuration_items ci
         LEFT JOIN companies c ON c.id = ci.company_id
        WHERE ci.id = ANY($1::bigint[])`,
      [Array.from(allCiIds)]
    );
    for (const ci of ciRes.rows) ciDetails.set(ci.id, ci);
  }

  const totalRes = await postgresClient.query<{ count: string }>(
    `SELECT COUNT(*)::text AS count
       FROM device_link_review r
       JOIN device_external_ids dx ON dx.id = r.device_external_id
      WHERE r.resolved_at IS NULL ${sourceFilter}`,
    source ? [source] : []
  );
  const total = parseInt(totalRes.rows[0]?.count ?? '0', 10);

  const items = reviews.rows.map((r) => ({
    id: r.id,
    detectedAt: r.detected_at,
    xref: {
      id: r.xref_id,
      source: r.source,
      sourceId: r.source_id,
      hostname: r.hostname,
      serial: r.serial,
      mac: r.mac,
      companyId: r.xref_company_id,
      companyName: r.xref_company_name,
      lastSeenAt: r.last_seen_at,
    },
    candidates: (r.candidate_ci_ids ?? []).map((ciId, i) => {
      const ci = ciDetails.get(String(ciId));
      return {
        ciId: String(ciId),
        confidence: r.match_confidences?.[i] ?? null,
        hostname: ci?.reference_title ?? null,
        serial: ci?.serial_number ?? null,
        mac: ci?.rmm_device_audit_mac_address ?? null,
        companyId: ci?.company_id ?? null,
        companyName: ci?.company_name ?? null,
        isDeleted: ci?.is_deleted ?? false,
      };
    }),
  }));

  return NextResponse.json({ items, total, limit, offset });
}
