/* eslint-disable @typescript-eslint/no-explicit-any */
import { test, expect } from "@sand4rt/experimental-ct-web";
import { SketchChatInput } from "./sketch-chat-input";

test("initializes with empty content by default", async ({ mount }) => {
  const component = await mount(SketchChatInput, {});

  // Check public property via component's evaluate method
  const content = await component.evaluate((el: SketchChatInput) => el.content);
  expect(content).toBe("");

  // Check textarea value
  await expect(component.locator("#chatInput")).toHaveValue("");
});

test("initializes with provided content", async ({ mount }) => {
  const testContent = "Hello, world!";
  const component = await mount(SketchChatInput, {
    props: {
      content: testContent,
    },
  });

  // Check public property via component's evaluate method
  const content = await component.evaluate((el: SketchChatInput) => el.content);
  expect(content).toBe(testContent);

  // Check textarea value
  await expect(component.locator("#chatInput")).toHaveValue(testContent);
});

test("updates content when typing in the textarea", async ({ mount }) => {
  const component = await mount(SketchChatInput, {});
  const newValue = "New message";

  // Fill the textarea with new content
  await component.locator("#chatInput").fill(newValue);

  // Check that the content property was updated
  const content = await component.evaluate((el: SketchChatInput) => el.content);
  expect(content).toBe(newValue);
});

test("sends message when clicking the send button", async ({ mount }) => {
  const testContent = "Test message";
  const component = await mount(SketchChatInput, {
    props: {
      content: testContent,
    },
  });

  // Set up promise to wait for the event
  const eventPromise = component.evaluate((el) => {
    return new Promise((resolve) => {
      el.addEventListener(
        "send-chat",
        (event) => {
          resolve((event as CustomEvent).detail);
        },
        { once: true },
      );
    });
  });

  // Click the send button
  await component.locator("#sendChatButton").click();

  // Wait for the event and check its details
  const detail: any = await eventPromise;
  expect(detail.message).toBe(testContent);
});

test.skip("sends message when pressing Enter (without shift)", async ({
  mount,
}) => {
  const testContent = "Test message";
  const component = await mount(SketchChatInput, {
    props: {
      content: testContent,
    },
  });

  // Set up promise to wait for the event
  const eventPromise = component.evaluate((el) => {
    return new Promise((resolve) => {
      el.addEventListener(
        "send-chat",
        (event) => {
          resolve((event as CustomEvent).detail);
        },
        { once: true },
      );
    });
  });

  // Press Enter in the textarea
  await component.locator("#chatInput").press("Enter");

  // Wait for the event and check its details
  const detail: any = await eventPromise;
  expect(detail.message).toBe(testContent);

  // Check that content was cleared
  const content = await component.evaluate((el: SketchChatInput) => el.content);
  expect(content).toBe("");
});

test.skip("does not send message when pressing Shift+Enter", async ({
  mount,
}) => {
  const testContent = "Test message";
  const component = await mount(SketchChatInput, {
    props: {
      content: testContent,
    },
  });

  // Set up to track if event fires
  let eventFired = false;
  await component.evaluate((el) => {
    el.addEventListener("send-chat", () => {
      (window as any).__eventFired = true;
    });
    (window as any).__eventFired = false;
  });

  // Press Shift+Enter in the textarea
  await component.locator("#chatInput").press("Shift+Enter");

  // Wait a short time and check if event fired
  await new Promise((resolve) => setTimeout(resolve, 50));
  eventFired = await component.evaluate(() => (window as any).__eventFired);
  expect(eventFired).toBe(false);

  // Check that content was not cleared
  const content = await component.evaluate((el: SketchChatInput) => el.content);
  expect(content).toBe(testContent);
});

test("resizes when user enters more text than will fit", async ({ mount }) => {
  const testContent = "Test message\n\n\n\n\n\n\n\n\n\n\n\n\nends here.";
  const component = await mount(SketchChatInput, {
    props: {
      content: "",
    },
  });
  const origHeight = await component.evaluate(
    (el: SketchChatInput) => el.chatInput.style.height,
  );

  // Enter very tall text in the textarea
  await component.locator("#chatInput").fill(testContent);

  // Wait for the requestAnimationFrame to complete
  await component.evaluate(() => new Promise(requestAnimationFrame));

  // Check that textarea resized
  const newHeight = await component.evaluate(
    (el: SketchChatInput) => el.chatInput.style.height,
  );
  expect(Number.parseInt(newHeight)).toBeGreaterThan(
    Number.parseInt(origHeight),
  );
});

test("shows drop overlay when file is dragged over", async ({ mount }) => {
  const component = await mount(SketchChatInput, {});

  // Simulate dragenter event
  await component.evaluate((el: SketchChatInput) => {
    const container = el.querySelector(".chat-container");
    if (container) {
      const event = new DragEvent("dragenter", { bubbles: true });
      container.dispatchEvent(event);
    }
  });

  // Check that the isDraggingOver state is true
  const isDraggingOver = await component.evaluate(
    (el: SketchChatInput) => el.isDraggingOver,
  );
  expect(isDraggingOver).toBe(true);

  // Check that the drop zone overlay is visible
  const overlay = await component.evaluate(
    (el: SketchChatInput) => el.querySelector(".drop-zone-overlay") !== null,
  );
  expect(overlay).toBe(true);
});

test("hides drop overlay when drag leaves", async ({ mount }) => {
  const component = await mount(SketchChatInput, {});

  // First set isDraggingOver to true
  await component.evaluate((el: SketchChatInput) => {
    el.isDraggingOver = true;
  });

  // Simulate dragleave event
  await component.evaluate((el: SketchChatInput) => {
    const container = el.querySelector(".chat-container");
    if (container) {
      const event = new DragEvent("dragleave", { bubbles: true });
      Object.defineProperty(event, "target", { value: container });
      container.dispatchEvent(event);
    }
  });

  // Check that the isDraggingOver state is false
  const isDraggingOver = await component.evaluate(
    (el: SketchChatInput) => el.isDraggingOver,
  );
  expect(isDraggingOver).toBe(false);
});

// Note: Testing actual file drop and upload would require mocking the fetch API
// This is a simple test that the drop event handler exists
test("has a drop event handler", async ({ mount }) => {
  const component = await mount(SketchChatInput, {});

  // Check that the component has the _handleDrop method
  const hasDropHandler = await component.evaluate(
    (el: SketchChatInput) => typeof (el as any)._handleDrop === "function",
  );
  expect(hasDropHandler).toBe(true);
});
