import { requestContextMiddleware } from '@adapters/http/RequestContext';
import { Result } from '@core/shared/domain/Result';
import { describe, expect, it, vi } from 'vitest';
import { requireLeagueAdminOrOwner } from '../league/LeagueAuthorization';
import { getActorFromRequestContext } from './getActorFromRequestContext';

async function withRequestContext<T>(req: Record<string, unknown>, fn: () => Promise<T>): Promise<T> {
  const res = {};

  return await new Promise<T>((resolve, reject) => {
    requestContextMiddleware(req as never, res as never, () => {
      fn().then(resolve, reject);
    });
  });
}

describe('ActorFromSession', () => {
  it('derives actor from authenticated session (request.user), not request payload', async () => {
    const req: unknown = {
      user: { userId: 'driver-from-session' },
      body: { driverId: 'driver-from-body' },
    };

    await withRequestContext(req as Record<string, unknown>, async () => {
      const actor = getActorFromRequestContext();
      expect(actor).toEqual({ userId: 'driver-from-session', driverId: 'driver-from-session' });
    });
  });

  it('permission helper invokes league admin check using session-derived actor (ignores payload)', async () => {
    const getLeagueAdminPermissionsUseCase = {
      execute: vi.fn(async () => Result.ok(undefined)),
    };

    const req: unknown = {
      user: { userId: 'driver-from-session' },
      body: { performerDriverId: 'driver-from-body' },
    };

    await withRequestContext(req as Record<string, unknown>, async () => {
      await expect(
        requireLeagueAdminOrOwner('league-1', getLeagueAdminPermissionsUseCase as never),
      ).resolves.toBeUndefined();
    });

    expect(getLeagueAdminPermissionsUseCase.execute).toHaveBeenCalledWith({
      leagueId: 'league-1',
      performerDriverId: 'driver-from-session',
    });
  });

  it('permission helper rejects when league admin check fails', async () => {
    const getLeagueAdminPermissionsUseCase = {
      execute: vi.fn(async () =>
        Result.err({ code: 'USER_NOT_MEMBER', details: { message: 'nope' } } as never),
      ),
    };

    const req: unknown = { user: { userId: 'driver-from-session' } };

    await withRequestContext(req as Record<string, unknown>, async () => {
      await expect(
        requireLeagueAdminOrOwner('league-1', getLeagueAdminPermissionsUseCase as never),
      ).rejects.toThrow('Forbidden');
    });
  });
});