import { APIRequestContext, test as base, request as playwrightRequest } from '@playwright/test';
import { readFileSync } from 'node:fs';

interface ManagerApiWorkerFixtures {
  managerApiRequest: APIRequestContext;
}

interface StorageStateFile {
  origins: { localStorage: { value: string }[] }[];
}

const STORAGE_STATE_PATH = '.auth/manager-admin-user.json';
const DEFAULT_BASE_URL = 'https://manager-api-test.kinnovis.com';

export const test = base.extend<object, ManagerApiWorkerFixtures>({
  managerApiRequest: [
    // oxlint-disable-next-line no-empty-pattern -- Playwright reads fixture dependencies from the destructured parameter
    async ({}, use) => {
      const token = readBearerTokenFromStorageState(STORAGE_STATE_PATH);
      const ctx = await playwrightRequest.newContext({
        baseURL: process.env.MANAGER_API_URL ?? DEFAULT_BASE_URL,
        extraHTTPHeaders: {
          Authorization: `Bearer ${token}`,
          Accept: 'application/json',
        },
      });

      await use(ctx);
      await ctx.dispose();
    },
    { scope: 'worker' },
  ],
});

export { expect } from '@playwright/test';

// Scans every localStorage value for an `access_token` string — key- and nesting-agnostic
// so SPA refactors that rename the persist key or re-nest the token don't break us.
function readBearerTokenFromStorageState(path: string): string {
  const state = JSON.parse(readFileSync(path, 'utf8')) as StorageStateFile;

  for (const origin of state.origins) {
    for (const { value } of origin.localStorage) {
      const match = value.match(/"access_token":"([^"]+)"/);

      if (match) {
        return match[1];
      }
    }
  }

  throw new Error(`No access_token found in localStorage entries of ${path}`);
}
