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

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

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

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

describe('Home', () => {
  it('renders the "no session" state with a Sign in button when anonymous', async () => {
    const { fixture } = await setup({ onBootstrap: 'anonymous' });
    const root = fixture.nativeElement as HTMLElement;
    expect(root.querySelector('.status-line')?.textContent).toContain('No admin session');
    expect(root.querySelector('.btn--primary')?.textContent?.trim()).toBe('Sign in via Entra');
  });

  it('renders the signed-in payload (display name + tenant + oid) when authenticated', async () => {
    const { fixture } = await setup({ onBootstrap: 'authenticated' });
    const root = fixture.nativeElement as HTMLElement;
    expect(root.querySelector('.status-line--ok')?.textContent).toContain('Admin Smith');
    const dds = Array.from(root.querySelectorAll<HTMLElement>('.session-detail dd')).map((el) =>
      el.textContent?.trim(),
    );
    expect(dds).toContain('admin@apf.example');
    expect(dds).toContain('tenant-1');
    expect(dds).toContain('admin-oid');
  });

  it('navigates to the admin login URL on Sign in click', async () => {
    const { fixture, navigate } = await setup({ onBootstrap: 'anonymous' });
    (fixture.nativeElement as HTMLElement)
      .querySelector<HTMLButtonElement>('.btn--primary')
      ?.click();
    expect(navigate).toHaveBeenCalledWith(`${BFF_BASE}/admin/auth/login`);
  });

  it('lists the roadmap items (audit log, CMS, menu, user list)', async () => {
    const { fixture } = await setup({ onBootstrap: 'anonymous' });
    const items = Array.from(
      (fixture.nativeElement as HTMLElement).querySelectorAll<HTMLElement>('.roadmap-list li'),
    ).map((li) => li.textContent ?? '');
    expect(items.some((t) => t.includes('Audit log viewer'))).toBe(true);
    expect(items.some((t) => t.includes('CMS pages'))).toBe(true);
    expect(items.some((t) => t.includes('Menu management'))).toBe(true);
    expect(items.some((t) => t.includes('User list'))).toBe(true);
  });
});
