import { NextResponse } from "next/server";
import { z } from "zod";
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { llmProviderRegistry } from "@open-mercato/shared/lib/ai/llm-provider-registry";
import { getAgent, loadAgentRegistry } from "../../../../../lib/agent-registry.js";
import { hasRequiredFeatures } from "../../../../../lib/auth.js";
import { createModelFactory, resolveAllowRuntimeOverride } from "../../../../../lib/model-factory.js";
import {
  hasAllowlistSnapshotRestrictions,
  intersectEffectiveAllowlistWithSnapshot,
  intersectAllowlists,
  isModelAllowedForProviderInEffective,
  isProviderAllowedInEffective,
  readAgentRuntimeOverrideAllowlist
} from "../../../../../lib/model-allowlist.js";
import { AiTenantModelAllowlistRepository } from "../../../../../data/repositories/AiTenantModelAllowlistRepository.js";
import { AiAgentRuntimeOverrideRepository } from "../../../../../data/repositories/AiAgentRuntimeOverrideRepository.js";
function modelsForPicker(provider, allowedModelIds) {
  if (provider.defaultModels.length > 0) return provider.defaultModels;
  return (allowedModelIds ?? []).map((id) => ({ id, name: id }));
}
const agentIdPattern = /^[a-z0-9_]+\.[a-z0-9_]+$/;
const agentIdParamSchema = z.object({
  agentId: z.string().regex(agentIdPattern, 'agentId must match "<module>.<agent>" (lowercase, digits, underscores only)')
});
const openApi = {
  tag: "AI Assistant",
  summary: "Available models for an AI agent",
  methods: {
    GET: {
      operationId: "aiAssistantGetAgentModels",
      summary: "Get the providers and curated models available for the chat-UI picker for this agent",
      description: 'Returns all configured providers with their curated model catalogs, filtered to providers that have an API key configured in the current environment. When the agent declares `allowRuntimeOverride: false`, the response reflects that constraint so the UI picker can hide itself. Includes the agent\'s resolved default provider/model so the picker can render a "(default)" badge next to the right entry. RBAC: requires the same features as the agent itself (typically `ai_assistant.view`).',
      responses: [
        {
          status: 200,
          description: "Providers and curated models available for the agent picker. Empty `providers` array when `allowRuntimeOverride` is false."
        }
      ],
      errors: [
        { status: 401, description: "Unauthenticated." },
        { status: 403, description: "Caller lacks the agent's required features." },
        { status: 404, description: "Unknown agent id." }
      ]
    }
  }
};
const metadata = {
  GET: { requireAuth: true, requireFeatures: ["ai_assistant.view"] }
};
async function GET(req, { params }) {
  const auth = await getAuthFromRequest(req);
  if (!auth?.sub) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  const rawParams = await params;
  const paramResult = agentIdParamSchema.safeParse(rawParams);
  if (!paramResult.success) {
    return NextResponse.json(
      { error: "Invalid agentId path parameter.", code: "validation_error", issues: paramResult.error.issues },
      { status: 400 }
    );
  }
  const agentId = paramResult.data.agentId;
  try {
    await loadAgentRegistry();
    const container = await createRequestContainer();
    const rbacService = container.resolve("rbacService");
    const acl = await rbacService.loadAcl(auth.sub, {
      tenantId: auth.tenantId,
      organizationId: auth.orgId
    });
    const agent = getAgent(agentId);
    if (!agent) {
      return NextResponse.json({ error: `Agent "${agentId}" not found.`, code: "agent_unknown" }, { status: 404 });
    }
    const agentFeatures = agent.requiredFeatures ?? [];
    if (agentFeatures.length > 0) {
      const permitted = hasRequiredFeatures(agentFeatures, acl.features, acl.isSuperAdmin);
      if (!permitted) {
        return NextResponse.json(
          {
            error: `Access to agent "${agentId}" requires features: ${agentFeatures.join(", ")}.`,
            code: "agent_features_denied"
          },
          { status: 403 }
        );
      }
    }
    const allowRuntimeOverride = resolveAllowRuntimeOverride(agent);
    let tenantAllowlistSnapshot = null;
    let agentRuntimeOverrideAllowlist = null;
    let tenantRuntimeOverride = null;
    if (auth.tenantId) {
      try {
        const em = container.resolve("em");
        const allowlistRepo = new AiTenantModelAllowlistRepository(em);
        tenantAllowlistSnapshot = await allowlistRepo.getSnapshot({
          tenantId: auth.tenantId,
          organizationId: auth.orgId ?? null
        });
        const runtimeOverrideRepo = new AiAgentRuntimeOverrideRepository(em);
        const runtimeOverrideDefaultRow = await runtimeOverrideRepo.getDefault({
          tenantId: auth.tenantId,
          organizationId: auth.orgId ?? null,
          agentId
        });
        tenantRuntimeOverride = runtimeOverrideDefaultRow ? {
          providerId: runtimeOverrideDefaultRow.providerId ?? null,
          modelId: runtimeOverrideDefaultRow.modelId ?? null,
          baseURL: runtimeOverrideDefaultRow.baseUrl ?? null
        } : null;
        const runtimeOverrideRow = await runtimeOverrideRepo.getExact({
          tenantId: auth.tenantId,
          organizationId: auth.orgId ?? null,
          agentId
        });
        const tenantAgentAllowlist = runtimeOverrideRow ? {
          allowedProviders: runtimeOverrideRow.allowedOverrideProviders ?? null,
          allowedModelsByProvider: runtimeOverrideRow.allowedOverrideModelsByProvider ?? {}
        } : null;
        agentRuntimeOverrideAllowlist = hasAllowlistSnapshotRestrictions(tenantAgentAllowlist) ? tenantAgentAllowlist : null;
      } catch (snapshotError) {
        console.error("[AI Agents Models] Failed to load tenant allowlist:", snapshotError);
      }
    }
    const factory = createModelFactory(container);
    const defaultResolution = factory.resolveModel({
      moduleId: agent.moduleId,
      agentDefaultModel: agent.defaultModel,
      agentDefaultProvider: agent.defaultProvider,
      agentDefaultBaseUrl: agent.defaultBaseUrl,
      allowRuntimeOverride,
      tenantOverride: tenantRuntimeOverride ?? void 0,
      tenantAllowlist: tenantAllowlistSnapshot
    });
    const defaultProviderId = defaultResolution.providerId;
    const defaultModelId = defaultResolution.modelId;
    const env = process.env;
    const knownProviderIds = llmProviderRegistry.list().map((p) => p.id);
    const baseEffectiveAllowlist = intersectAllowlists(
      env,
      knownProviderIds,
      tenantAllowlistSnapshot
    );
    const envAgentAllowlist = readAgentRuntimeOverrideAllowlist(env, agentId, knownProviderIds);
    const effectiveAllowlist = intersectEffectiveAllowlistWithSnapshot(
      intersectEffectiveAllowlistWithSnapshot(
        baseEffectiveAllowlist,
        knownProviderIds,
        envAgentAllowlist
      ),
      knownProviderIds,
      agentRuntimeOverrideAllowlist
    );
    const providers = allowRuntimeOverride ? llmProviderRegistry.list().filter((provider) => provider.isConfigured()).filter((provider) => isProviderAllowedInEffective(effectiveAllowlist, provider.id)).map((provider) => {
      const allowedModelIds = effectiveAllowlist.modelsByProvider[provider.id];
      const filteredModels = modelsForPicker(provider, allowedModelIds).filter(
        (model) => isModelAllowedForProviderInEffective(effectiveAllowlist, provider.id, model.id)
      );
      return {
        id: provider.id,
        name: provider.name,
        isDefault: provider.id === defaultProviderId,
        models: filteredModels.map((model) => ({
          id: model.id,
          name: model.name,
          contextWindow: model.contextWindow,
          tags: model.tags,
          isDefault: provider.id === defaultProviderId && model.id === defaultModelId
        }))
      };
    }) : [];
    return NextResponse.json({
      agentId,
      allowRuntimeOverride,
      allowRuntimeModelOverride: allowRuntimeOverride,
      defaultProviderId,
      defaultModelId,
      defaultProviderName: llmProviderRegistry.get(defaultProviderId)?.name ?? defaultProviderId,
      defaultModelName: llmProviderRegistry.get(defaultProviderId)?.defaultModels.find((model) => model.id === defaultModelId)?.name ?? defaultModelId,
      providers
    });
  } catch (error) {
    console.error("[AI Agents Models] GET error:", error);
    return NextResponse.json({ error: "Failed to resolve agent models." }, { status: 500 });
  }
}
export {
  GET,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
