import type { FastifyInstance } from "fastify";
import { requireSession } from "../../../lib/auth.js";
import { writeAuditLog } from "../../../lib/audit.js";
import {
  getNeuraHubDocumentImportSummary,
  getNeuraHubFormImportSummary,
  importNeuraHubDocumentCatalog,
  importNeuraHubFormTemplates,
} from "../../../lib/neurahub.js";
import { getSessionProfile } from "../../../lib/session.js";

export async function registerNeuraHubIntegrationRoutes(app: FastifyInstance) {
  app.get("/documents/summary", async (request, reply) => {
    const session = await requireSession(request, reply);
    const profile = await getSessionProfile(session);

    if (!profile) {
      throw reply.unauthorized("Session is no longer valid");
    }

    const summary = await getNeuraHubDocumentImportSummary(profile.lawFirm.id);
    return summary;
  });

  app.post("/documents/import", async (request, reply) => {
    const session = await requireSession(request, reply);
    const profile = await getSessionProfile(session);

    if (!profile) {
      throw reply.unauthorized("Session is no longer valid");
    }

    const summary = await getNeuraHubDocumentImportSummary(profile.lawFirm.id);

    if (!summary.sourceConfigured) {
      throw reply.badRequest(summary.sourceError ?? "neuraHub database is not configured.");
    }

    if (!summary.sourceReachable) {
      throw reply.serviceUnavailable(summary.sourceError ?? "neuraHub database is unavailable.");
    }

    const result = await importNeuraHubDocumentCatalog({
      lawFirmId: profile.lawFirm.id,
      userId: profile.user.id,
    });

    await writeAuditLog({
      lawFirmId: profile.lawFirm.id,
      officeId: profile.user.primaryOfficeId ?? null,
      actorUserId: profile.user.id,
      entityType: "workspace_document_library",
      entityId: profile.lawFirm.id,
      action: "integration.neurahub.documents.import",
      afterJson: {
        sourceCount: result.sourceCount,
        importedCount: result.importedCount,
        documentTypesCreated: result.documentTypesCreated,
        documentTypesReused: result.documentTypesReused,
        importedLibrary: result.importedLibrary,
      },
      request,
    });

    return reply.code(201).send(result);
  });

  app.get("/forms/summary", async (request, reply) => {
    const session = await requireSession(request, reply);
    const profile = await getSessionProfile(session);

    if (!profile) {
      throw reply.unauthorized("Session is no longer valid");
    }

    const summary = await getNeuraHubFormImportSummary(profile.lawFirm.id);
    return summary;
  });

  app.post("/forms/import", async (request, reply) => {
    const session = await requireSession(request, reply);
    const profile = await getSessionProfile(session);

    if (!profile) {
      throw reply.unauthorized("Session is no longer valid");
    }

    const summary = await getNeuraHubFormImportSummary(profile.lawFirm.id);

    if (!summary.sourceConfigured) {
      throw reply.badRequest(summary.sourceError ?? "neuraHub database is not configured.");
    }

    if (!summary.sourceReachable) {
      throw reply.serviceUnavailable(summary.sourceError ?? "neuraHub database is unavailable.");
    }

    const result = await importNeuraHubFormTemplates({
      lawFirmId: profile.lawFirm.id,
      userId: profile.user.id,
    });

    await writeAuditLog({
      lawFirmId: profile.lawFirm.id,
      officeId: profile.user.primaryOfficeId ?? null,
      actorUserId: profile.user.id,
      entityType: "form_template",
      entityId: profile.lawFirm.id,
      action: "integration.neurahub.forms.import",
      afterJson: {
        sourceCount: result.sourceCount,
        importedCount: result.importedCount,
        createdCount: result.createdCount,
        updatedCount: result.updatedCount,
        fieldsImportedCount: result.fieldsImportedCount,
        withBasePdfCount: result.withBasePdfCount,
        templatesMissingBasePdfCount: result.templatesMissingBasePdfCount,
        importedCatalog: result.importedCatalog,
      },
      request,
    });

    return reply.code(201).send(result);
  });
}
