import { expect } from "@wdio/globals";
import LoginPage from "../pageobjects/LoginPage";
import { testConfig } from "../helpers/testConfig";

describe("Authentication Flow", () => {
  beforeEach(async () => {
    // Each test starts fresh - app should redirect to login
    await LoginPage.waitForLoginPage();
  });

  describe("Server Connection", () => {
    it("should display the server connection form", async () => {
      expect(await LoginPage.isOnServerStep()).toBe(true);
      expect(await LoginPage.pageTitle.getText()).toContain("JellyTau");
    });

    it("should show server URL input field", async () => {
      const serverInput = await LoginPage.serverUrlInput;

      expect(await serverInput.isDisplayed()).toBe(true);
      expect(await serverInput.getAttribute("placeholder")).toContain("jellyfin");
    });

    it("should have a disabled connect button when URL is empty", async () => {
      const connectButton = await LoginPage.connectButton;

      // Button should be disabled when input is empty
      expect(await connectButton.isEnabled()).toBe(false);
    });

    it("should enable connect button when URL is entered", async () => {
      await LoginPage.enterServerUrl(testConfig.serverUrl);

      const connectButton = await LoginPage.connectButton;
      expect(await connectButton.isEnabled()).toBe(true);
    });

    it("should show error for invalid server URL", async () => {
      await LoginPage.enterServerUrl("not-a-valid-url");
      await LoginPage.clickConnect();

      // Wait for error to appear
      await browser.pause(2000);

      expect(await LoginPage.hasError()).toBe(true);
    });

    it("should transition to login form on successful connection", async () => {
      // Using configured test server
      await LoginPage.connectToServer(testConfig.serverUrl);

      // Should now be on login step
      expect(await LoginPage.isOnLoginStep()).toBe(true);
      expect(await LoginPage.isOnServerStep()).toBe(false);
    });
  });

  describe("User Login", () => {
    beforeEach(async () => {
      // Connect to configured test server before each login test
      await LoginPage.connectToServer(testConfig.serverUrl);
    });

    it("should display login form after server connection", async () => {
      expect(await LoginPage.usernameInput.isDisplayed()).toBe(true);
      expect(await LoginPage.passwordInput.isDisplayed()).toBe(true);
      expect(await LoginPage.signInButton.isDisplayed()).toBe(true);
    });

    it("should show server information", async () => {
      // Server name and URL should be displayed
      const serverName = await LoginPage.serverNameDisplay;
      expect(await serverName.isDisplayed()).toBe(true);
    });

    it("should have back button to return to server selection", async () => {
      expect(await LoginPage.backButton.isDisplayed()).toBe(true);

      await LoginPage.backButton.click();
      await browser.pause(500);

      // Should be back on server step
      expect(await LoginPage.isOnServerStep()).toBe(true);
    });

    it("should disable sign in button when username is empty", async () => {
      const signInButton = await LoginPage.signInButton;
      expect(await signInButton.isEnabled()).toBe(false);
    });

    it("should enable sign in button when username is entered", async () => {
      await LoginPage.enterUsername("demo");

      const signInButton = await LoginPage.signInButton;
      expect(await signInButton.isEnabled()).toBe(true);
    });

    it("should show error for invalid credentials", async () => {
      await LoginPage.login("invalid-user", "wrong-password");

      // Wait for error
      await browser.pause(2000);

      expect(await LoginPage.hasError()).toBe(true);
    });

    // Enable this test by configuring e2e/.env with valid credentials
    it.skip("should successfully login with valid credentials", async () => {
      await LoginPage.login(testConfig.username, testConfig.password);

      // Wait for redirect to home page
      await browser.pause(3000);

      // Should redirect away from login page
      const currentUrl = await browser.getUrl();
      expect(currentUrl).not.toContain("/login");
    });
  });

  describe("Full Authentication Flow", () => {
    it("should complete full auth flow with test server", async () => {
      // Test the complete flow
      await LoginPage.waitForLoginPage();

      // Step 1: Enter server URL
      expect(await LoginPage.isOnServerStep()).toBe(true);
      await LoginPage.enterServerUrl(testConfig.serverUrl);
      await LoginPage.clickConnect();

      // Wait for transition
      await browser.pause(2000);

      // Step 2: Should be on login form
      expect(await LoginPage.isOnLoginStep()).toBe(true);

      // Step 3: Enter credentials
      await LoginPage.enterUsername(testConfig.username);
      await LoginPage.enterPassword(testConfig.password);

      // Verify form is filled
      const username = await LoginPage.usernameInput.getValue();
      expect(username).toBe(testConfig.username);
    });
  });
});
