import { provideHttpClient, withInterceptors } from '@angular/common/http';
import {
  HttpTestingController,
  provideHttpClientTesting,
} from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { TwitchAuthService } from '../twitch/twitch-auth.service';
import { authInterceptor } from './auth.interceptor';
import { EbsApiService, EBS_BASE_URL } from './ebs-api.service';

function makeJwt(): string {
  const payload = btoa(JSON.stringify({ opaque_user_id: 'U123', channel_id: 'ch1', role: 'viewer', exp: 9999999999 }))
    .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
  return `eyJhbGciOiJIUzI1NiJ9.${payload}.sig`;
}

describe('authInterceptor', () => {
  let controller: HttpTestingController;
  let authService: TwitchAuthService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        provideHttpClient(withInterceptors([authInterceptor])),
        provideHttpClientTesting(),
        { provide: EBS_BASE_URL, useValue: 'https://test.local' },
      ],
    });
    controller = TestBed.inject(HttpTestingController);
    authService = TestBed.inject(TwitchAuthService);
  });

  afterEach(() => controller.verify());

  it('omits Authorization header when not yet authorized', () => {
    const svc = TestBed.inject(EbsApiService);
    svc.getMissionState().subscribe();

    const req = controller.expectOne('https://test.local/missions/state');
    expect(req.request.headers.has('Authorization')).toBe(false);
    req.flush(null);
  });

  it('attaches Bearer token after onAuthorized fires', () => {
    const jwt = makeJwt();
    (window as Window & { Twitch?: unknown }).Twitch = {
      ext: {
        onAuthorized: (cb: (a: TwitchAuth) => void) =>
          cb({ channelId: 'ch1', clientId: 'c1', token: jwt, userId: 'U123' }),
        onContext: () => undefined,
        onVisibilityChanged: () => undefined,
        listen: () => undefined,
        unlisten: () => undefined,
        send: () => undefined,
      },
    };
    authService.init();

    const svc = TestBed.inject(EbsApiService);
    svc.getMissionState().subscribe();

    const req = controller.expectOne('https://test.local/missions/state');
    expect(req.request.headers.get('Authorization')).toBe(`Bearer ${jwt}`);
    req.flush(null);

    delete (window as Window & { Twitch?: unknown }).Twitch;
  });
});
