import { createAppAuth, type DefaultAuthUser } from '@nstart/auth'
import { createContext, type ReactNode, useContext, useEffect } from 'react'
import { setApiAuthToken } from '../api/apiFetch'
import { env } from '../config/env'

export type AppUser = DefaultAuthUser

// Состояние, совместимое с AuthState из @nstart/auth (headless-ядро). Используем
// ТОЛЬКО headless-слой пакета: createAppAuth/useAppAuth дают токен, login, logout,
// loading и коды ошибок — без единого компонента @nstart/ui (их UI: ProfilePage/
// UserPanel — намеренно не подключаем).
interface AppAuthState {
  user: AppUser | null
  token: string | null
  loading: boolean
  errorCode: 'notAuthenticated' | 'initFailed' | null
  errorDetails: string | null
  login: () => void
  logout: () => void
}

// Anonymous-режим: фейковый контекст, чтобы useAppAuth() работал везде в коде
// без условий. Токен null → apiFetch не добавляет Authorization, поведение как у
// исходного сервиса (открывается сразу, без Keycloak).
const ANONYMOUS_STATE: AppAuthState = {
  user: null,
  token: null,
  loading: false,
  errorCode: null,
  errorDetails: null,
  login: () => undefined,
  logout: () => undefined,
}

const AnonymousAuthContext = createContext<AppAuthState>(ANONYMOUS_STATE)

function AnonymousAuthProvider({ children }: { children: ReactNode }) {
  return (
    <AnonymousAuthContext.Provider value={ANONYMOUS_STATE}>
      {children}
    </AnonymousAuthContext.Provider>
  )
}

function useAnonymousAuth(): AppAuthState {
  return useContext(AnonymousAuthContext)
}

const newStartIdAuth = createAppAuth({
  url: env.newStartIdUrl,
  realm: env.newStartIdRealm,
  clientId: env.newStartIdClientId,
  loginMode: 'redirect',
})

export const { AppAuthProvider, useAppAuth } =
  env.authMode === 'new-start-id'
    ? newStartIdAuth
    : { AppAuthProvider: AnonymousAuthProvider, useAppAuth: useAnonymousAuth }

/**
 * Прокидывает токен из useAppAuth() в сетевой слой (держатель apiFetch). Ничего
 * не рендерит; монтируется внутри AppAuthProvider. В режиме anonymous token === null,
 * поэтому заголовок Authorization не выставляется и поведение запросов не меняется.
 *
 * @returns Ничего не отображает (null).
 */
export function AuthTokenBridge(): null {
  const { token } = useAppAuth()
  useEffect(() => {
    setApiAuthToken(token ?? null)
  }, [token])
  return null
}
