import { expect, test } from "@playwright/test";

// ─── Feature API tests ─────────────────────────────────────────────

test.describe("Feature API", () => {
  test("GET /api/v1/features returns all 6 bundles with correct shape", async ({ request }) => {
    const response = await request.get("/api/v1/features");
    expect(response.ok()).toBeTruthy();
    const data = await response.json();
    expect(data.bundles).toHaveLength(6);

    const expectedBundles = [
      "background-removal",
      "face-detection",
      "object-eraser-colorize",
      "upscale-enhance",
      "photo-restoration",
      "ocr",
    ];
    for (const id of expectedBundles) {
      const bundle = data.bundles.find((b: any) => b.id === id);
      expect(bundle, `Bundle ${id} missing`).toBeDefined();
      expect(bundle.name).toBeTruthy();
      expect(bundle.description).toBeTruthy();
      expect(bundle.estimatedSize).toBeTruthy();
      expect(bundle.enablesTools).toBeInstanceOf(Array);
      expect(bundle.enablesTools.length).toBeGreaterThan(0);
      expect(["not_installed", "installed", "installing", "error"]).toContain(bundle.status);
    }
  });

  test("each bundle has the correct tools", async ({ request }) => {
    const response = await request.get("/api/v1/features");
    const data = await response.json();

    const toolMap: Record<string, string[]> = {
      "background-removal": ["remove-background", "passport-photo"],
      "face-detection": ["blur-faces", "red-eye-removal", "smart-crop"],
      "object-eraser-colorize": ["erase-object", "colorize"],
      "upscale-enhance": ["upscale", "enhance-faces", "noise-removal"],
      "photo-restoration": ["restore-photo"],
      ocr: ["ocr"],
    };

    for (const [bundleId, expectedTools] of Object.entries(toolMap)) {
      const bundle = data.bundles.find((b: any) => b.id === bundleId);
      expect(bundle.enablesTools).toEqual(expectedTools);
    }
  });

  test("POST install returns 404 for unknown bundle", async ({ request }) => {
    const response = await request.post("/api/v1/admin/features/nonexistent/install");
    expect(response.status()).toBe(404);
  });

  test("POST uninstall returns 409 for not-installed bundle", async ({ request }) => {
    const response = await request.post("/api/v1/admin/features/background-removal/uninstall");
    expect(response.status()).toBe(409);
  });

  test("GET disk-usage returns totalBytes", async ({ request }) => {
    const response = await request.get("/api/v1/admin/features/disk-usage");
    expect(response.ok()).toBeTruthy();
    const data = await response.json();
    expect(typeof data.totalBytes).toBe("number");
  });
});

// ─── Tool route guard tests ─────────────────────────────────────────

test.describe("Tool route guards", () => {
  const pngBuffer = Buffer.from(
    "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==",
    "base64",
  );

  const aiTools = [
    { tool: "remove-background", bundle: "background-removal" },
    { tool: "upscale", bundle: "upscale-enhance" },
    { tool: "blur-faces", bundle: "face-detection" },
    { tool: "erase-object", bundle: "object-eraser-colorize" },
    { tool: "ocr", bundle: "ocr" },
    { tool: "colorize", bundle: "object-eraser-colorize" },
    { tool: "enhance-faces", bundle: "upscale-enhance" },
    { tool: "noise-removal", bundle: "upscale-enhance" },
    { tool: "red-eye-removal", bundle: "face-detection" },
    { tool: "restore-photo", bundle: "photo-restoration" },
    { tool: "passport-photo", bundle: "background-removal" },
  ];

  for (const { tool, bundle } of aiTools) {
    test(`${tool} returns 501 FEATURE_NOT_INSTALLED with correct bundle`, async ({ request }) => {
      const response = await request.post(`/api/v1/tools/${tool}`, {
        multipart: {
          file: {
            name: "test.png",
            mimeType: "image/png",
            buffer: pngBuffer,
          },
          settings: JSON.stringify({}),
        },
      });
      expect(response.status()).toBe(501);
      const body = await response.json();
      expect(body.code).toBe("FEATURE_NOT_INSTALLED");
      expect(body.feature).toBe(bundle);
      expect(body.featureName).toBeTruthy();
      expect(body.estimatedSize).toBeTruthy();
    });
  }

  test("non-AI tool works normally (resize)", async ({ request }) => {
    const response = await request.post("/api/v1/tools/resize", {
      multipart: {
        file: {
          name: "test.png",
          mimeType: "image/png",
          buffer: pngBuffer,
        },
        settings: JSON.stringify({ width: 100, height: 100, method: "fit" }),
      },
    });
    // Should succeed or fail with a processing error, NOT 501
    expect(response.status()).not.toBe(501);
  });
});

// ─── Batch and pipeline guard tests ─────────────────────────────────

test.describe("Batch and pipeline guards", () => {
  const pngBuffer = Buffer.from(
    "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==",
    "base64",
  );

  test("batch endpoint returns 501 for uninstalled AI tool", async ({ request }) => {
    const response = await request.post("/api/v1/tools/remove-background/batch", {
      multipart: {
        "files[]": {
          name: "test.png",
          mimeType: "image/png",
          buffer: pngBuffer,
        },
        settings: JSON.stringify({}),
      },
    });
    expect(response.status()).toBe(501);
    const body = await response.json();
    expect(body.code).toBe("FEATURE_NOT_INSTALLED");
  });
});

// ─── GUI tests (Playwright page interactions) ───────────────────────

test.describe("Feature install UI", () => {
  test("uninstalled AI tool page shows install prompt", async ({ page }) => {
    await page.goto("/remove-background");
    await expect(page.getByText("Background Removal")).toBeVisible({
      timeout: 10000,
    });
    await expect(page.getByText("additional download")).toBeVisible();
    await expect(page.getByRole("button", { name: /enable/i })).toBeVisible();
  });

  test("non-AI tool page loads normally", async ({ page }) => {
    await page.goto("/resize");
    // Should show the normal tool UI, not an install prompt
    await expect(page.getByText("additional download")).not.toBeVisible({
      timeout: 5000,
    });
  });

  test("AI tools show download badge in sidebar", async ({ page }) => {
    await page.goto("/resize");
    // Wait for the sidebar to load
    await expect(page.locator("[data-testid='tool-panel']").or(page.locator("nav"))).toBeVisible({
      timeout: 10000,
    });
    // The download icon should be visible near AI tools
    // Note: we can't easily test for the exact Download icon, but we can check the tool links exist
    const removeBackgroundLink = page.locator("a[href='/remove-background']");
    await expect(removeBackgroundLink).toBeVisible();
  });

  test("settings dialog has AI Features section", async ({ page }) => {
    await page.goto("/resize");
    // Open settings - look for a settings button/gear icon
    const settingsButton = page
      .getByRole("button", { name: /settings/i })
      .or(page.locator("button[aria-label*='ettings']"));
    if (await settingsButton.isVisible({ timeout: 5000 }).catch(() => false)) {
      await settingsButton.click();
      await expect(page.getByText("AI Features")).toBeVisible({
        timeout: 5000,
      });
    }
  });

  test("AI Features settings shows all 6 bundles", async ({ page }) => {
    await page.goto("/resize");
    const settingsButton = page
      .getByRole("button", { name: /settings/i })
      .or(page.locator("button[aria-label*='ettings']"));
    if (await settingsButton.isVisible({ timeout: 5000 }).catch(() => false)) {
      await settingsButton.click();
      // Click AI Features nav item
      const aiNav = page.getByText("AI Features");
      if (await aiNav.isVisible({ timeout: 3000 }).catch(() => false)) {
        await aiNav.click();
        // Should show all 6 bundles
        await expect(page.getByText("Background Removal")).toBeVisible({
          timeout: 5000,
        });
        await expect(page.getByText("Face Detection")).toBeVisible();
        await expect(page.getByText("Object Eraser & Colorize")).toBeVisible();
        await expect(page.getByText("Upscale & Enhance")).toBeVisible();
        await expect(page.getByText("Photo Restoration")).toBeVisible();
        await expect(page.getByText("OCR")).toBeVisible();
      }
    }
  });
});
