import { WebStorageStateStore, type User, type UserManagerSettings } from 'oidc-client-ts'
import type { AuthProviderProps } from 'react-oidc-context'

const KC_URL = import.meta.env.VITE_KEYCLOAK_URL ?? 'https://auth.nstart.space'
const KC_REALM = import.meta.env.VITE_KEYCLOAK_REALM ?? 'nstart'
const KC_CLIENT_ID = import.meta.env.VITE_KEYCLOAK_CLIENT_ID ?? 'ordinis'

const authority = `${KC_URL}/realms/${KC_REALM}`

const baseSettings: UserManagerSettings = {
  authority,
  client_id: KC_CLIENT_ID,
  redirect_uri: typeof window !== 'undefined' ? window.location.origin + '/' : '/',
  post_logout_redirect_uri:
    typeof window !== 'undefined' ? window.location.origin + '/' : '/',
  scope: 'openid profile email',
  response_type: 'code',
  automaticSilentRenew: true,
  loadUserInfo: false,
  // sessionStorage вместо localStorage: уменьшает XSS persistent reach на
  // access_token + id_token. Trade-off: токен не переживает закрытие вкладки —
  // на повторном открытии будет SSO redirect к Keycloak (но без user input
  // если SSO session в Keycloak ещё жива, т.е. UX impact минимальный).
  // Долгосрочное правильное решение — BFF + httpOnly cookie с refresh token,
  // но это отдельный epic (server-side OIDC handler).
  // См. также {@code apiClient}: access_token держится в in-memory holder'е,
  // не читается из storage на каждый request.
  userStore:
    typeof window !== 'undefined'
      ? new WebStorageStateStore({ store: window.sessionStorage })
      : undefined,
}

/**
 * Конфиг для {@code <AuthProvider>}. PKCE flow, public client — secret не нужен.
 *
 * <p>{@code onSigninCallback} удаляет {@code ?code=...&state=...} из URL после
 * успешного login, чтобы TanStack Router не запутался.
 */
export const oidcAuthConfig: AuthProviderProps = {
  ...baseSettings,
  onSigninCallback: (_user: User | void) => {
    if (typeof window !== 'undefined') {
      window.history.replaceState({}, document.title, window.location.pathname)
    }
  },
}

// TOKEN_STORAGE_KEY (legacy 'ordinis.token' в localStorage) удалён вместе с
// fix дублирующих 401-interceptor'ов. Access token больше не дублируется
// в localStorage из приложения — он живёт в memory holder'е (см. apiClient
// setAccessToken) и oidc-client-ts userStore (sessionStorage, fix #12).
//
// Cleanup: на первый mount old клиенты могут иметь старый ключ — TokenSync
// его удаляет.
export const LEGACY_TOKEN_STORAGE_KEY = 'ordinis.token'
