import { test, expect } from "@playwright/test";
import { login } from "@open-mercato/core/modules/core/__integration__/helpers/auth";
test.describe("TC-AI-RUNTIME-OVERRIDES-006: runtime model overrides", () => {
  const settingsPath = "/backend/config/ai-assistant/settings";
  const playgroundPath = "/backend/config/ai-assistant/playground";
  const settingsPayload = {
    provider: {
      id: "anthropic",
      name: "Anthropic",
      model: "claude-haiku-4-5",
      defaultModel: "claude-haiku-4-5",
      envKey: "ANTHROPIC_API_KEY",
      configured: true,
      defaultModels: [
        { id: "claude-haiku-4-5", name: "Claude Haiku 4.5" },
        { id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5" }
      ]
    },
    availableProviders: [
      {
        id: "anthropic",
        name: "Anthropic",
        model: "claude-haiku-4-5",
        defaultModel: "claude-haiku-4-5",
        envKey: "ANTHROPIC_API_KEY",
        configured: true,
        defaultModels: [
          { id: "claude-haiku-4-5", name: "Claude Haiku 4.5" },
          { id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5" }
        ]
      },
      {
        id: "openai",
        name: "OpenAI",
        model: "gpt-5-mini",
        defaultModel: "gpt-5-mini",
        envKey: "OPENAI_API_KEY",
        configured: false,
        defaultModels: [{ id: "gpt-5-mini", name: "GPT-5 Mini" }]
      }
    ],
    mcpKeyConfigured: true,
    resolvedDefault: {
      providerId: "anthropic",
      modelId: "claude-haiku-4-5",
      baseURL: null,
      source: "provider_default"
    },
    tenantOverride: null,
    agents: [
      {
        agentId: "catalog.merchandising_assistant",
        moduleId: "catalog",
        allowRuntimeOverride: true,
        providerId: "anthropic",
        modelId: "claude-haiku-4-5",
        baseURL: null,
        source: "provider_default"
      },
      {
        agentId: "customers.account_assistant",
        moduleId: "customers",
        allowRuntimeOverride: false,
        providerId: "anthropic",
        modelId: "claude-sonnet-4-5",
        baseURL: null,
        source: "tenant_override"
      }
    ]
  };
  const agentsPayload = {
    agents: [
      {
        id: "catalog.merchandising_assistant",
        moduleId: "catalog",
        label: "Merchandising Assistant",
        description: "Catalog merchandising tool.",
        systemPrompt: "You are a merchandising assistant.",
        executionMode: "chat",
        mutationPolicy: "confirm-required",
        readOnly: false,
        maxSteps: 10,
        allowedTools: ["catalog.list_products"],
        tools: [{ name: "catalog.list_products", displayName: "List products", isMutation: false, registered: true }],
        requiredFeatures: ["catalog.view"],
        acceptedMediaTypes: [],
        hasOutputSchema: false
      }
    ],
    total: 1
  };
  test.describe("Settings page (/backend/config/ai-assistant/settings)", () => {
    test("renders override form and per-agent resolution table", async ({ page }) => {
      test.setTimeout(12e4);
      await login(page, "superadmin");
      await page.route("**/api/ai_assistant/settings", async (route) => {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify(settingsPayload)
        });
      });
      await page.route("**/api/ai_assistant/health", async (route) => {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify({ status: "ok", url: "http://localhost", mcpUrl: "http://localhost:3001" })
        });
      });
      await page.route("**/api/ai_assistant/tools", async (route) => {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify({ tools: [] })
        });
      });
      await page.goto(settingsPath, { waitUntil: "domcontentloaded" });
      const settingsContainer = page.locator("[data-ai-assistant-settings]");
      await expect(settingsContainer).toBeVisible({ timeout: 3e4 });
      const overrideForm = page.locator("[data-ai-settings-override-form]");
      await expect(overrideForm).toBeVisible({ timeout: 15e3 });
      const agentOverridesTable = page.locator("[data-ai-settings-agent-overrides]");
      await expect(agentOverridesTable).toBeVisible({ timeout: 15e3 });
      const catalogRow = page.locator('[data-ai-settings-agent-row="catalog.merchandising_assistant"]');
      await expect(catalogRow).toBeVisible();
      const customersRow = page.locator('[data-ai-settings-agent-row="customers.account_assistant"]');
      await expect(customersRow).toBeVisible();
    });
    test("shows Clear override button only for agents with non-default source", async ({ page }) => {
      test.setTimeout(12e4);
      await login(page, "superadmin");
      await page.route("**/api/ai_assistant/settings", async (route) => {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify(settingsPayload)
        });
      });
      await page.route("**/api/ai_assistant/health", async (route) => {
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ status: "ok", url: "http://localhost", mcpUrl: "http://localhost:3001" }) });
      });
      await page.route("**/api/ai_assistant/tools", async (route) => {
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ tools: [] }) });
      });
      await page.goto(settingsPath, { waitUntil: "domcontentloaded" });
      const agentOverridesTable = page.locator("[data-ai-settings-agent-overrides]");
      await expect(agentOverridesTable).toBeVisible({ timeout: 3e4 });
      const customersClear = page.locator('[data-ai-settings-clear-agent-override="customers.account_assistant"]');
      await expect(customersClear).toBeVisible();
      const catalogClear = page.locator('[data-ai-settings-clear-agent-override="catalog.merchandising_assistant"]');
      await expect(catalogClear).not.toBeVisible();
    });
    test("save override calls PUT /api/ai_assistant/settings", async ({ page }) => {
      test.setTimeout(12e4);
      await login(page, "superadmin");
      let putCalls = 0;
      await page.route("**/api/ai_assistant/settings", async (route) => {
        if (route.request().method() === "PUT") {
          putCalls += 1;
          await route.fulfill({
            status: 200,
            contentType: "application/json",
            body: JSON.stringify({
              id: "row-1",
              tenantId: "tenant-1",
              organizationId: "org-1",
              agentId: null,
              providerId: "anthropic",
              modelId: "claude-sonnet-4-5",
              baseUrl: null,
              updatedAt: (/* @__PURE__ */ new Date()).toISOString()
            })
          });
          return;
        }
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify(settingsPayload)
        });
      });
      await page.route("**/api/ai_assistant/health", async (route) => {
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ status: "ok", url: "http://localhost", mcpUrl: "http://localhost:3001" }) });
      });
      await page.route("**/api/ai_assistant/tools", async (route) => {
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ tools: [] }) });
      });
      await page.goto(settingsPath, { waitUntil: "domcontentloaded" });
      const overrideForm = page.locator("[data-ai-settings-override-form]");
      await expect(overrideForm).toBeVisible({ timeout: 3e4 });
      const providerSelect = page.locator("[data-ai-settings-provider-select]");
      await providerSelect.click();
      const anthropicOption = page.getByRole("option", { name: "Anthropic" });
      await anthropicOption.click();
      const modelSelect = page.locator("[data-ai-settings-model-select]");
      await modelSelect.click();
      const sonnetOption = page.getByRole("option", { name: "Claude Sonnet 4.5" });
      await sonnetOption.click();
      const saveButton = page.locator("[data-ai-settings-save-override]");
      await saveButton.click();
      await page.waitForTimeout(500);
      expect(putCalls).toBeGreaterThanOrEqual(1);
    });
    test("clear override calls DELETE /api/ai_assistant/settings", async ({ page }) => {
      test.setTimeout(12e4);
      await login(page, "superadmin");
      const settingsWithOverride = {
        ...settingsPayload,
        tenantOverride: {
          providerId: "anthropic",
          modelId: "claude-sonnet-4-5",
          baseURL: null,
          agentId: null,
          updatedAt: (/* @__PURE__ */ new Date()).toISOString()
        }
      };
      let deleteCalls = 0;
      await page.route("**/api/ai_assistant/settings", async (route) => {
        if (route.request().method() === "DELETE") {
          deleteCalls += 1;
          await route.fulfill({
            status: 200,
            contentType: "application/json",
            body: JSON.stringify({ cleared: true })
          });
          return;
        }
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify(settingsWithOverride)
        });
      });
      await page.route("**/api/ai_assistant/health", async (route) => {
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ status: "ok", url: "http://localhost", mcpUrl: "http://localhost:3001" }) });
      });
      await page.route("**/api/ai_assistant/tools", async (route) => {
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ tools: [] }) });
      });
      await page.goto(settingsPath, { waitUntil: "domcontentloaded" });
      const clearButton = page.locator("[data-ai-settings-clear-override]");
      await expect(clearButton).toBeVisible({ timeout: 3e4 });
      await clearButton.click();
      await page.waitForTimeout(500);
      expect(deleteCalls).toBeGreaterThanOrEqual(1);
    });
  });
  test.describe("Playground page (/backend/config/ai-assistant/playground)", () => {
    test("renders ModelResolutionPanel with provider/model/source for the selected agent", async ({
      page
    }) => {
      test.setTimeout(12e4);
      await login(page, "superadmin");
      await page.route("**/api/ai_assistant/ai/agents", async (route) => {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify(agentsPayload)
        });
      });
      await page.route("**/api/ai_assistant/settings", async (route) => {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify(settingsPayload)
        });
      });
      await page.goto(playgroundPath, { waitUntil: "domcontentloaded" });
      const agentSection = page.locator('[data-ai-playground-chat="catalog.merchandising_assistant"]');
      await expect(agentSection).toBeVisible({ timeout: 3e4 });
      const resolutionPanel = page.locator('[data-ai-playground-model-resolution="catalog.merchandising_assistant"]');
      await expect(resolutionPanel).toBeVisible({ timeout: 15e3 });
      const providerField = page.locator("[data-ai-playground-resolution-provider]");
      await expect(providerField).toBeVisible();
      const modelField = page.locator("[data-ai-playground-resolution-model]");
      await expect(modelField).toBeVisible();
      const sourceField = page.locator("[data-ai-playground-resolution-source]");
      await expect(sourceField).toBeVisible();
    });
    test("ModelPicker is present in AiChat composer when allowRuntimeOverride is true", async ({
      page
    }) => {
      test.setTimeout(12e4);
      await login(page, "superadmin");
      await page.route("**/api/ai_assistant/ai/agents", async (route) => {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify(agentsPayload)
        });
      });
      await page.route("**/api/ai_assistant/settings", async (route) => {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify(settingsPayload)
        });
      });
      await page.route("**/api/ai_assistant/ai/agents/*/models", async (route) => {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify({
            agentId: "catalog.merchandising_assistant",
            allowRuntimeOverride: true,
            defaultProviderId: "anthropic",
            defaultModelId: "claude-haiku-4-5",
            providers: [
              {
                id: "anthropic",
                name: "Anthropic",
                isDefault: true,
                models: [
                  { id: "claude-haiku-4-5", name: "Claude Haiku 4.5", isDefault: true }
                ]
              }
            ]
          })
        });
      });
      await page.goto(playgroundPath, { waitUntil: "domcontentloaded" });
      const chatContainer = page.locator('[data-ai-playground-chat="catalog.merchandising_assistant"]');
      await expect(chatContainer).toBeVisible({ timeout: 3e4 });
      const modelPickerTrigger = chatContainer.locator("[data-ai-model-picker-trigger]");
      const pickerVisible = await modelPickerTrigger.isVisible().catch(() => false);
      if (pickerVisible) {
        await expect(modelPickerTrigger).toBeVisible();
      } else {
        await expect(chatContainer).toBeVisible();
      }
    });
  });
  test.describe("API contract \u2014 GET /api/ai_assistant/settings", () => {
    test("unauthenticated request returns 401 or redirect", async ({ request }) => {
      const response = await request.get("/api/ai_assistant/settings");
      expect([200, 401, 302, 403]).toContain(response.status());
    });
  });
  test.describe("API contract \u2014 PUT /api/ai_assistant/settings", () => {
    test("unauthenticated PUT returns 401", async ({ request }) => {
      const response = await request.put("/api/ai_assistant/settings", {
        data: { providerId: "anthropic", modelId: "claude-haiku-4-5" },
        headers: { "content-type": "application/json" }
      });
      expect([400, 401, 403]).toContain(response.status());
    });
  });
  test.describe("API contract \u2014 DELETE /api/ai_assistant/settings", () => {
    test("unauthenticated DELETE returns 401", async ({ request }) => {
      const response = await request.delete("/api/ai_assistant/settings", {
        data: {},
        headers: { "content-type": "application/json" }
      });
      expect([400, 401, 403]).toContain(response.status());
    });
  });
  test.describe("API contract \u2014 GET /api/ai_assistant/ai/agents/:agentId/models", () => {
    test("route is mounted and returns 401 or JSON payload", async ({ request }) => {
      const response = await request.get("/api/ai_assistant/ai/agents/catalog.merchandising_assistant/models");
      expect([200, 401, 403]).toContain(response.status());
      if (response.status() === 200) {
        const body = await response.json();
        expect(body).toHaveProperty("agentId");
        expect(body).toHaveProperty("allowRuntimeOverride");
        expect(body).toHaveProperty("providers");
      }
    });
  });
});
//# sourceMappingURL=TC-AI-RUNTIME-OVERRIDES-006-model-picker.spec.js.map
