/// <reference types="cypress" />

Cypress.env("AUTO_LOGIN", false);

describe("sign-in page", () => {
  after(() => {
    Cypress.env("AUTO_LOGIN", true);
  });

  beforeEach(() => {
    cy.clearCookies();
    cy.clearLocalStorage();

    cy.intercept("POST", "**/api/proxy/profile/login*", (req) => {
      req.reply({
        delay: 2500,
        statusCode: 200,
        body: {
          success: true,
          message: "ok",
          data: {
            access_token: "e2e-access-token",
            refresh_token: "e2e-refresh-token",
            expires_at: Date.now() + 60_000,
            user: {
              id: "507f1f77bcf86cd799439011",
              username: "tester",
              email: "tester@example.com",
              role: "admin",
            },
          },
        },
      });
    }).as("loginRequest");

    cy.visit("/auth/sign-in");
    cy.location("pathname").should("eq", "/auth/sign-in");
  });

  it("keeps the sign-in box centered and visible in viewport", () => {
    cy.get("div[class*='max-w-'][class*='shadow-theme-xs'][class*='rounded-2xl']")
      .first()
      .should("be.visible")
      .then(($card) => {
        const rect = $card[0].getBoundingClientRect();

        cy.window().then((win) => {
          const viewportCenterX = win.innerWidth / 2;
          const viewportCenterY = win.innerHeight / 2;
          const cardCenterX = rect.left + rect.width / 2;
          const cardCenterY = rect.top + rect.height / 2;

          expect(rect.top).to.be.gte(0);
          expect(rect.left).to.be.gte(0);
          expect(rect.bottom).to.be.lte(win.innerHeight);
          expect(rect.right).to.be.lte(win.innerWidth);
          expect(Math.abs(cardCenterX - viewportCenterX)).to.be.lessThan(80);
          expect(Math.abs(cardCenterY - viewportCenterY)).to.be.lessThan(100);
        });
      });
  });

  it("toggles theme correctly", () => {
    cy.get("html").should("not.have.class", "dark");
    cy.contains("button", "Switch to dark mode").click();
    cy.get("html").should("have.class", "dark");

    cy.contains("button", "Switch to light mode").click();
    cy.get("html").should("not.have.class", "dark");
  });

  it("shows required errors under each field and does not call login API", () => {
    cy.contains('button[type="submit"]', "Sign in").click();

    cy.get("p.text-error")
      .should("have.length", 2)
      .each(($message) => {
        expect($message.text().trim()).to.eq("This field is required");
      });
    cy.get("@loginRequest.all").should("have.length", 0);
  });

  it("shows and hides password value when lock icon is clicked", () => {
    cy.get('input[name="password"]').as("passwordInput");
    cy.get("@passwordInput").should("have.attr", "type", "password");

    cy.get('button[aria-label="Show password"]').click();
    cy.get("@passwordInput").should("have.attr", "type", "text");

    cy.get('button[aria-label="Hide password"]').click();
    cy.get("@passwordInput").should("have.attr", "type", "password");
  });

  it("shows default button text first, then spinner while submitting", () => {
    cy.contains('button[type="submit"]', "Sign in")
      .as("submitButton")
      .should("be.visible")
      .and("not.be.disabled");

    cy.get('input[name="username"]').type("tester");
    cy.get('input[name="password"]').type("Secret123!");

    cy.get("@submitButton").click();
    cy.get('button[type="submit"]')
      .find("div.animate-spin", { timeout: 10000 })
      .should("exist");
    cy.get('button[type="submit"]').should("not.contain", "Sign in");
  });

});
