import { provideHttpClient } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { provideRouter } from '@angular/router';
import {
  AUTH_BFF_BASE_URL,
  AUTH_NAVIGATOR,
  AUTH_PATH_PREFIX,
  type CurrentUser,
} from 'feature-auth';
import { ProfilePage } from './profile';

const BFF_BASE = 'http://bff.test/api';
const ADMIN_ME_URL = `${BFF_BASE}/admin/auth/me`;

const USER: CurrentUser = {
  oid: 'admin-oid-abc',
  tid: 'tenant-1',
  username: 'admin@apf.example',
  displayName: 'Admin Smith',
  roles: ['Portal.Admin'],
};

async function setup(user: CurrentUser | null) {
  TestBed.configureTestingModule({
    imports: [ProfilePage],
    providers: [
      provideRouter([]),
      provideHttpClient(),
      provideHttpClientTesting(),
      { provide: AUTH_BFF_BASE_URL, useValue: BFF_BASE },
      { provide: AUTH_PATH_PREFIX, useValue: '/admin/auth' },
      { provide: AUTH_NAVIGATOR, useValue: vi.fn() },
    ],
  });
  const fixture = TestBed.createComponent(ProfilePage);
  const http = TestBed.inject(HttpTestingController);
  const req = http.expectOne(ADMIN_ME_URL);
  if (user) {
    req.flush(user);
  } else {
    req.flush({}, { status: 401, statusText: 'Unauthorized' });
  }
  await Promise.resolve();
  fixture.detectChanges();
  await fixture.whenStable();
  return { fixture, http };
}

describe('ProfilePage (portal-admin)', () => {
  beforeEach(() => TestBed.resetTestingModule());

  it('renders the identity card with displayName, username, oid, tid', async () => {
    const { fixture } = await setup(USER);
    const root = fixture.nativeElement as HTMLElement;
    expect(root.querySelector('[data-testid="profile-displayname"]')?.textContent?.trim()).toBe(
      'Admin Smith',
    );
    expect(root.querySelector('[data-testid="profile-username"]')?.textContent?.trim()).toBe(
      'admin@apf.example',
    );
    expect(root.querySelector('[data-testid="profile-oid"]')?.textContent?.trim()).toBe(
      'admin-oid-abc',
    );
    expect(root.querySelector('[data-testid="profile-tid"]')?.textContent?.trim()).toBe('tenant-1');
  });

  it('renders the App roles card with one chip per role when present', async () => {
    const { fixture } = await setup({ ...USER, roles: ['Portal.Admin', 'Portal.Auditor'] });
    const root = fixture.nativeElement as HTMLElement;
    const chips = Array.from(root.querySelectorAll('[data-testid="profile-roles"] .role-chip'));
    expect(chips.map((el) => el.textContent?.trim())).toEqual(['Portal.Admin', 'Portal.Auditor']);
  });

  it('omits the App roles card entirely when the session carries no roles', async () => {
    const { fixture } = await setup({ ...USER, roles: [] });
    const root = fixture.nativeElement as HTMLElement;
    expect(root.querySelector('[data-testid="profile-roles"]')).toBeNull();
  });

  it('renders nothing when the user is anonymous (template @if guard)', async () => {
    const { fixture } = await setup(null);
    const root = fixture.nativeElement as HTMLElement;
    expect(root.querySelector('.profile')).toBeNull();
  });
});
