/**
 * POST /api/analyzer/itglue/configurations/:id/revert/:writeId
 *
 * Mirrors the Applications revert path but PATCHes /configurations/:id.
 */

import { NextRequest, NextResponse } from 'next/server';
import { requirePermission } from '@/lib/auth-utils';
import postgresClient from '@/lib/services/postgres-client';
import {
  createPendingWrite,
  getWriteById,
  markWriteCommitted,
  markWriteFailed,
  markWriteReverted,
} from '@/lib/services/analyzer/asset-audit/persistence';
import { getITGlueClient } from '@/lib/services/itglue-client';
import { getITGlueSyncService } from '@/lib/services/itglue-sync-service';
import { audit } from '@/lib/services/audit';

const FIELD_TO_ITGLUE_ATTR: Record<string, string> = {
  name: 'name',
  hostname: 'hostname',
  primary_ip: 'primary-ip',
  mac_address: 'mac-address',
  serial_number: 'serial-number',
  asset_tag: 'asset-tag',
  position: 'position',
  notes: 'notes',
  operating_system_notes: 'operating-system-notes',
};

export async function POST(
  _request: NextRequest,
  { params }: { params: Promise<{ id: string; writeId: string }> }
) {
  const { session, error } = await requirePermission('itglue', 'write');
  if (error) return error;

  const { id: assetId, writeId } = await params;
  const userId =
    (session?.user as { id: string; email?: string } | undefined)?.id ?? null;
  const userEmail =
    (session?.user as { id: string; email?: string } | undefined)?.email ??
    undefined;

  const original = await getWriteById(writeId);
  if (!original) return NextResponse.json({ error: 'Write not found' }, { status: 404 });
  if (original.asset_id !== assetId || original.asset_type !== 'configuration') {
    return NextResponse.json(
      { error: 'Write does not reference this configuration' },
      { status: 400 }
    );
  }
  if (original.status === 'reverted') {
    return NextResponse.json(
      { error: 'Write already reverted' },
      { status: 400 }
    );
  }
  if (original.status !== 'committed') {
    return NextResponse.json(
      { error: `Cannot revert a write in status '${original.status}'` },
      { status: 400 }
    );
  }

  const exists = await postgresClient.query(
    `SELECT 1 FROM itg_configurations WHERE id = $1 LIMIT 1`,
    [assetId]
  );
  if (exists.rowCount === 0) {
    return NextResponse.json({ error: 'Configuration not found' }, { status: 404 });
  }

  const attrKey = FIELD_TO_ITGLUE_ATTR[original.field_name];
  if (!attrKey) {
    return NextResponse.json(
      { error: `Cannot map field '${original.field_name}' to IT Glue attribute` },
      { status: 400 }
    );
  }

  const revertRow = await createPendingWrite({
    audit_id: original.audit_id,
    asset_type: 'configuration',
    asset_id: assetId,
    field_name: original.field_name,
    before_value: original.after_value,
    after_value: original.before_value,
    performed_by_user_id: userId,
    source_evidence: { reverts_write_id: original.id },
  });

  try {
    const client = getITGlueClient();
    const updated = await client.updateConfiguration(assetId, {
      [attrKey]: original.before_value,
    });

    await markWriteCommitted(revertRow.id, updated);
    await markWriteReverted(original.id);

    try {
      await getITGlueSyncService().refreshConfigurationById(assetId);
    } catch (refreshErr) {
      console.warn(
        `[itglue-config-revert] mirror refresh failed for ${assetId}:`,
        refreshErr instanceof Error ? refreshErr.message : refreshErr
      );
    }

    await audit.log({
      userId: userId ?? undefined,
      userEmail,
      action: 'itglue.revert',
      resource: 'configuration',
      resourceId: assetId,
      details: {
        revert_write_id: revertRow.id,
        original_write_id: original.id,
        field_name: original.field_name,
        before: original.after_value,
        after: original.before_value,
      },
    });

    return NextResponse.json({
      writeId: revertRow.id,
      revertedWriteId: original.id,
      status: 'committed',
      asset: updated,
    });
  } catch (err) {
    const message = err instanceof Error ? err.message : String(err);
    await markWriteFailed(revertRow.id, message);
    return NextResponse.json(
      {
        writeId: revertRow.id,
        status: 'failed',
        error: 'IT Glue revert failed',
        message,
      },
      { status: 502 }
    );
  }
}
