import type { FastifyInstance } from "fastify";
import { z } from "zod";
import { requireSession } from "../../lib/auth.js";
import {
  analyzeImmigrationCaseForClient,
  createFormAgentMemory,
  listFormAgentMemories,
  listFormEngineAgents,
  runFormEngineForClient,
} from "../../lib/form-engine.js";
import { getSessionProfile } from "../../lib/session.js";

const clientIdParamSchema = z.object({
  clientId: z.string().uuid(),
});

const agentCodeParamSchema = z.object({
  agentCode: z.string().min(2).max(80),
});

const analysisQuerySchema = z.object({
  caseId: z.string().uuid().optional(),
});

const runSchema = z.object({
  caseId: z.string().uuid().optional().nullable(),
  agentCodes: z.array(z.string().min(2).max(80)).optional(),
  targetCoverage: z.coerce.number().min(0).max(1).optional(),
  maxIterations: z.coerce.number().int().positive().max(6).optional(),
  maxRuntimeMs: z.coerce.number().int().positive().max(6 * 60 * 60 * 1000).optional(),
});

const memoryQuerySchema = z.object({
  templateId: z.string().uuid().optional(),
  clientId: z.string().uuid().optional(),
  caseId: z.string().uuid().optional(),
});

const memorySchema = z.object({
  formTemplateId: z.string().uuid().optional().nullable(),
  clientId: z.string().uuid().optional().nullable(),
  caseId: z.string().uuid().optional().nullable(),
  memoryScope: z.enum(["global", "client", "case"]).default("client"),
  memoryType: z.enum([
    "successful_pattern",
    "failed_pattern",
    "human_correction",
    "mapping_improvement",
    "question_optimization",
    "confidence_adjustment",
  ]),
  summaryText: z.string().min(3).max(4000),
  detailJson: z.unknown().optional(),
  successScore: z.coerce.number().min(0).max(1).optional().nullable(),
  coverageRatio: z.coerce.number().min(0).max(1).optional().nullable(),
});

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

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

    return listFormEngineAgents({
      lawFirmId: profile.lawFirm.id,
      actorUserId: profile.user.id,
    });
  });

  app.get("/agents/:agentCode/memories", async (request, reply) => {
    const session = await requireSession(request, reply);
    const profile = await getSessionProfile(session);
    const { agentCode } = agentCodeParamSchema.parse(request.params);
    const query = memoryQuerySchema.parse(request.query);

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

    return listFormAgentMemories({
      lawFirmId: profile.lawFirm.id,
      agentCode,
      templateId: query.templateId ?? null,
      clientId: query.clientId ?? null,
      caseId: query.caseId ?? null,
    });
  });

  app.post("/agents/:agentCode/memories", async (request, reply) => {
    const session = await requireSession(request, reply);
    const profile = await getSessionProfile(session);
    const { agentCode } = agentCodeParamSchema.parse(request.params);
    const payload = memorySchema.parse(request.body);

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

    const id = await createFormAgentMemory({
      lawFirmId: profile.lawFirm.id,
      actorUserId: profile.user.id,
      agentCode,
      formTemplateId: payload.formTemplateId ?? null,
      clientId: payload.clientId ?? null,
      caseId: payload.caseId ?? null,
      memoryScope: payload.memoryScope,
      memoryType: payload.memoryType,
      summaryText: payload.summaryText,
      detailJson: payload.detailJson,
      successScore: payload.successScore ?? null,
      coverageRatio: payload.coverageRatio ?? null,
    });

    return reply.code(201).send({ id });
  });

  app.get("/clients/:clientId/analysis", async (request, reply) => {
    const session = await requireSession(request, reply);
    const profile = await getSessionProfile(session);
    const { clientId } = clientIdParamSchema.parse(request.params);
    const query = analysisQuerySchema.parse(request.query);

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

    return analyzeImmigrationCaseForClient({
      lawFirmId: profile.lawFirm.id,
      actorUserId: profile.user.id,
      clientId,
      caseId: query.caseId ?? null,
    });
  });

  app.post("/clients/:clientId/run", async (request, reply) => {
    const session = await requireSession(request, reply);
    const profile = await getSessionProfile(session);
    const { clientId } = clientIdParamSchema.parse(request.params);
    const payload = runSchema.parse(request.body);

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

    return runFormEngineForClient({
      lawFirmId: profile.lawFirm.id,
      actorUserId: profile.user.id,
      clientId,
      caseId: payload.caseId ?? null,
      agentCodes: payload.agentCodes ?? null,
      targetCoverage: payload.targetCoverage,
      maxIterations: payload.maxIterations,
      maxRuntimeMs: payload.maxRuntimeMs,
    });
  });
}
