import { expect, test } from "@playwright/test";
import { del, get, post, put } from "../src/lib/api";

test.describe("API E2E Tests", () => {
  test("should make GET request to health endpoint", async () => {
    const response = await get("/health");

    expect(response).toHaveProperty("status", "healthy");
  });

  test.describe("Settings CRUD Operations", () => {
    test("should GET all settings", async () => {
      const response = await get("/config/settings");
      expect(Array.isArray(response) || typeof response === "object").toBe(
        true
      );
    });

    test("should POST new settings", async () => {
      const testSettings = {
        e2eTestKey: "e2eTestValue",
        timestamp: Date.now()
      };
      const response = await post("/config/settings", testSettings);
      expect(response).toBe(true); // API returns boolean true on success
    });

    test("should GET specific setting by key", async () => {
      // First create a setting
      const testKey = "e2eTestKey";
      const testValue = "e2eTestValue";
      await post("/config/settings", { [testKey]: testValue });

      // Then get it by key - API returns the value directly as plain text
      const response = await fetch(
        `http://localhost:3001/config/settings/${testKey}`
      );
      const text = await response.text();
      expect(text).toBe(testValue); // API returns the raw string value
    });

    test("should DELETE specific setting", async () => {
      // First create a setting
      const testKey = "e2eDeleteKey";
      await post("/config/settings", { [testKey]: "valueToDelete" });

      // Then delete it
      const response = await del(`/config/settings/${testKey}`);
      expect(response).toBeDefined();
    });
  });

  test.describe("Tasks CRUD Operations", () => {
    let createdTaskId: string;

    test("should GET all tasks", async () => {
      const response = await get("/tasks");
      expect(Array.isArray(response)).toBe(true);
    });

    test("should POST new task", async () => {
      const testTask = {
        name: "E2E Test Task",
        description: "Created by e2e test",
        status: "pending",
        type: "settings", // Required field
        createdAt: new Date().toISOString()
      };

      const response = await post("/tasks", testTask);
      expect(response).toHaveProperty("id");
      expect(response.name).toBe(testTask.name);
      createdTaskId = response.id;
    });

    test("should PUT update task", async () => {
      // Skip if no task was created
      if (!createdTaskId) {
        console.log("Skipping PUT test - no task ID available");
        return;
      }

      const updateData = {
        status: "completed"
      };

      const response = await put(`/tasks/${createdTaskId}`, updateData);
      expect(response).toHaveProperty("id", createdTaskId);
      expect(response.status).toBe(updateData.status);
    });

    test("should DELETE task", async () => {
      // Skip if no task was created
      if (!createdTaskId) {
        console.log("Skipping DELETE test - no task ID available");
        return;
      }

      const response = await del(`/tasks/${createdTaskId}`);
      expect(response).toBeDefined();
    });
  });

  test.describe("Files CRUD Operations", () => {
    test("should GET files list", async () => {
      const response = await get("/files");
      expect(Array.isArray(response) || typeof response === "object").toBe(
        true
      );
    });

    test("should GET file stats", async () => {
      const successfulStats = await get("/files/stats/successful");
      expect(
        typeof successfulStats === "number" ||
          typeof successfulStats === "object"
      ).toBe(true);

      const processedStats = await get("/files/stats/processed");
      expect(
        typeof processedStats === "number" || typeof processedStats === "object"
      ).toBe(true);
    });

    test("should POST new file", async () => {
      // Create a simple test file
      const testFile = {
        dataset: "e2e-test-dataset",
        filename: "test-file.txt",
        content: "This is test content for e2e testing"
      };

      try {
        const response = await post(
          `/files/${testFile.dataset}/${testFile.filename}`,
          {
            content: testFile.content
          }
        );
        expect(response).toBeDefined();
      } catch (error) {
        // File creation might require specific format or authentication
        console.log(
          "File creation test skipped - endpoint may require specific setup"
        );
      }
    });

    test("should GET specific file", async () => {
      try {
        const response = await get("/files/e2e-test-dataset/test-file.txt");
        expect(response).toBeDefined();
      } catch (error) {
        // File might not exist or endpoint might require different path
        console.log(
          "File retrieval test - file may not exist from previous test"
        );
      }
    });

    test("should DELETE file", async () => {
      try {
        const response = await del("/files/e2e-test-dataset/test-file.txt");
        expect(response).toBeDefined();
      } catch (error) {
        // File might not exist
        console.log("File deletion test - file may not exist");
      }
    });
  });

  test.describe("Error Handling", () => {
    test("should handle 404 errors", async () => {
      await expect(get("/non-existent-endpoint")).rejects.toThrow();
    });

    test("should handle timeout correctly", async () => {
      // Test with a non-existent endpoint that returns 404
      await expect(
        get("/non-existent-endpoint-that-times-out")
      ).rejects.toThrow("Not Found");
    });
  });
});
