import { type APIRequestContext, type Page } from '@playwright/test';

export const AUTH_TOKENS_STORAGE_KEY = 'metoyou.authTokens';
export const SIGNAL_SERVER_CREDENTIALS_STORAGE_KEY = 'metoyou.signalServerCredentials';

export interface AuthSession {
  id: string;
  username: string;
  displayName: string;
  token: string;
  expiresAt: number;
}

export function authHeaders(token: string): Record<string, string> {
  return {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json'
  };
}

export async function registerTestUser(
  request: APIRequestContext,
  baseUrl: string,
  username: string,
  password: string,
  displayName?: string
): Promise<AuthSession> {
  const response = await request.post(`${baseUrl}/api/users/register`, {
    data: {
      username,
      password,
      displayName: displayName ?? username
    }
  });

  if (!response.ok()) {
    throw new Error(`Failed to register test user ${username}: ${response.status()} ${await response.text()}`);
  }

  return await response.json() as AuthSession;
}

export async function loginTestUser(
  request: APIRequestContext,
  baseUrl: string,
  username: string,
  password: string
): Promise<AuthSession> {
  const response = await request.post(`${baseUrl}/api/users/login`, {
    data: { username, password }
  });

  if (!response.ok()) {
    throw new Error(`Failed to login test user ${username}: ${response.status()} ${await response.text()}`);
  }

  return await response.json() as AuthSession;
}

export async function readSignalServerCredentialFromPage(
  page: Page,
  serverUrl: string
): Promise<{ userId: string; token: string; username: string } | null> {
  return await page.evaluate(({ storageKey, url }) => {
    try {
      const store = JSON.parse(localStorage.getItem(storageKey) || '{}') as Record<string, {
        userId: string;
        token: string;
        username: string;
        expiresAt: number;
      }>;
      const normalizedUrl = url.trim().replace(/\/+$/, '');
      const entry = store[normalizedUrl];

      if (!entry || entry.expiresAt <= Date.now()) {
        return null;
      }

      return {
        userId: entry.userId,
        token: entry.token,
        username: entry.username
      };
    } catch {
      return null;
    }
  }, { storageKey: SIGNAL_SERVER_CREDENTIALS_STORAGE_KEY, url: serverUrl });
}

export async function readAuthTokenFromPage(page: Page, serverUrl: string): Promise<string | null> {
  return await page.evaluate(({ storageKey, url }) => {
    try {
      const store = JSON.parse(localStorage.getItem(storageKey) || '{}') as Record<string, { token: string; expiresAt: number }>;
      const normalizedUrl = url.trim().replace(/\/+$/, '');
      const entry = store[normalizedUrl];

      if (!entry || entry.expiresAt <= Date.now()) {
        return null;
      }

      return entry.token;
    } catch {
      return null;
    }
  }, { storageKey: AUTH_TOKENS_STORAGE_KEY, url: serverUrl });
}
