import { fireEvent, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { MemoryRouter } from "react-router-dom";
import { beforeEach, describe, expect, test, vi } from "vitest";
import ChangePasswordPage from "./ChangePasswordPage.jsx";

const auth = vi.hoisted(() => ({
  changePassword: vi.fn(),
  logout: vi.fn(),
  session: {
    account: "fami-manager",
    appCode: "fami",
    appName: "Fami",
    logoUrl: "https://media.example.com/apps/fami.png",
    passwordChangeRequired: true
  }
}));

vi.mock("../auth/ExternalAuthProvider.jsx", () => ({ useExternalAuth: () => auth }));

describe("ChangePasswordPage", () => {
  beforeEach(() => {
    auth.changePassword.mockReset().mockResolvedValue({});
    auth.logout.mockReset().mockResolvedValue(undefined);
    auth.session = {
      account: "fami-manager",
      appCode: "fami",
      appName: "Fami",
      logoUrl: "https://media.example.com/apps/fami.png",
      passwordChangeRequired: true
    };
  });

  test("shows the App brand resolved by the authenticated session", () => {
    auth.session = {
      ...auth.session,
      account: "lalu-manager",
      appCode: "lalu",
      appName: "Lalu",
      logoUrl: "https://media.example.com/apps/lalu.png"
    };
    const view = render(<MemoryRouter><ChangePasswordPage /></MemoryRouter>);

    expect(screen.getByText("Lalu")).toBeInTheDocument();
    expect(view.container.querySelector("img")).toHaveAttribute("src", "https://media.example.com/apps/lalu.png");
    expect(document.title).toBe("Lalu");
    expect(document.head.querySelector('link[data-external-app-favicon="true"]')).toHaveAttribute("href", "https://media.example.com/apps/lalu.png");
  });

  test("blocks a whitespace-only new password", async () => {
    const user = userEvent.setup();
    const { container } = render(<MemoryRouter><ChangePasswordPage /></MemoryRouter>);
    const [newPassword, confirmPassword] = container.querySelectorAll('input[autocomplete="new-password"]');

    fireEvent.change(container.querySelector('input[autocomplete="current-password"]'), { target: { value: "old-password" } });
    fireEvent.change(newPassword, { target: { value: "        " } });
    fireEvent.change(confirmPassword, { target: { value: "        " } });
    await user.click(screen.getByRole("button", { name: "Save password" }));

    expect(screen.getByText("The new password cannot be empty or contain only whitespace")).toBeInTheDocument();
    expect(auth.changePassword).not.toHaveBeenCalled();
  });

  test("preserves password bytes instead of trimming before submission", async () => {
    const user = userEvent.setup();
    const { container } = render(<MemoryRouter><ChangePasswordPage /></MemoryRouter>);
    const [newPassword, confirmPassword] = container.querySelectorAll('input[autocomplete="new-password"]');

    fireEvent.change(container.querySelector('input[autocomplete="current-password"]'), { target: { value: " current-password " } });
    fireEvent.change(newPassword, { target: { value: " pass word " } });
    fireEvent.change(confirmPassword, { target: { value: " pass word " } });
    await user.click(screen.getByRole("button", { name: "Save password" }));

    expect(auth.changePassword).toHaveBeenCalledWith({ newPassword: " pass word ", oldPassword: " current-password " });
  });
});
