import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { ApiConfigService } from '../core/config/api-config.service';
import { LocationService } from '../services/location.service';
import { LanguageService } from '../services/language.service';
import { AuthService } from '@marketplaces/auth';

/** Map internal language codes to API header values */
const LANG_HEADER_MAP: Record<string, string> = {
  'ru': 'RU',
  'en': 'EN',
  'hy': 'AM',
};

/** Map region IDs to API header values */
const REGION_HEADER_MAP: Record<string, string> = {
  'moscow': 'Moscow',
  'spb': 'ST. Petersburg',
  'yerevan': 'Yerevan',
};

const SESSION_STORAGE_KEY = 'web_session_id';

/** Generate a 32-char hex string (GUID without dashes) */
function generateSessionId(): string {
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);
  return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
}

/** Get or create a persistent anonymous session ID */
function getAnonymousSessionId(): string {
  let id = localStorage.getItem(SESSION_STORAGE_KEY);
  if (!id || id.length !== 32) {
    id = generateSessionId();
    localStorage.setItem(SESSION_STORAGE_KEY, id);
  }
  return id;
}

/**
 * @marketplaces/auth's AuthService checks for a persisted session in its own
 * constructor (a synchronous HTTP call to GET /users/sessions/:id before the
 * constructor returns). If this interceptor injects AuthService for that
 * exact call, Angular sees AuthService requesting itself mid-construction
 * and throws NG0200 (circular dependency) - silently, since it's swallowed
 * by TelegramSessionApiService's catchError(() => of(null)), which reads as
 * "session invalid" and logs the user straight back out on every load.
 * These endpoints are the identity mechanism itself (the session id is
 * already the URL/body), so they never needed a WebSessionID header from an
 * existing session in the first place - skipping AuthService injection here
 * is correct, not a workaround.
 */
const AUTH_SESSION_PATH = '/users/sessions';

export const apiHeadersInterceptor: HttpInterceptorFn = (req, next) => {
  const apiConfig = inject(ApiConfigService);
  if (!apiConfig.isApiRequest(req.url)) {
    return next(req);
  }

  const locationService = inject(LocationService);
  const languageService = inject(LanguageService);

  const regionId = locationService.regionId();
  const lang = languageService.currentLanguage();
  const currency = languageService.currentCurrency();

  let headers = req.headers;

  if (regionId) {
    headers = headers.set('X-Region', REGION_HEADER_MAP[regionId] ?? regionId);
  }
  if (lang) {
    headers = headers.set('X-Language', LANG_HEADER_MAP[lang] ?? lang.toUpperCase());
  }
  headers = headers.set('Currency', currency || 'RUB');

  if (!req.url.includes(AUTH_SESSION_PATH)) {
    const authService = inject(AuthService);
    const session = authService.session();
    headers = headers.set('WebSessionID', session?.sessionId || getAnonymousSessionId());
  }

  return next(req.clone({ headers }));
};
