import {
  AllowedModule,
  type AllowedModule as AllowedModuleCode,
} from "../../shared/api/enums";
import { tokenStore } from "../../shared/auth/tokenStore";
import { authApi, type AuthApi } from "./authApi";
import type { LoginRequest, UserSummary } from "./authTypes";

export type AuthenticatedPage = "main" | "admin" | "audit";

export interface NavigationItem {
  module: AllowedModuleCode;
  page: AuthenticatedPage;
  label: string;
}

const MODULE_PAGES: Record<AllowedModuleCode, AuthenticatedPage> = {
  [AllowedModule.DOCUMENT_BROWSER]: "main",
  [AllowedModule.BACKEND_MANAGEMENT]: "admin",
  [AllowedModule.AUDIT_LOG]: "audit",
};

const MODULE_ORDER: readonly AllowedModuleCode[] = [
  AllowedModule.DOCUMENT_BROWSER,
  AllowedModule.BACKEND_MANAGEMENT,
  AllowedModule.AUDIT_LOG,
];

export function getNavigationItems(
  allowedModules: readonly AllowedModuleCode[],
  getLabel: (module: AllowedModuleCode) => string,
): NavigationItem[] {
  const allowed = new Set(allowedModules);
  return MODULE_ORDER.flatMap((module) => {
    if (!allowed.has(module)) return [];
    return [{ module, page: MODULE_PAGES[module], label: getLabel(module) }];
  });
}

export function getFirstAllowedPage(
  allowedModules: readonly AllowedModuleCode[],
): AuthenticatedPage | null {
  const allowed = new Set(allowedModules);
  const first = MODULE_ORDER.find((module) => allowed.has(module));
  return first ? MODULE_PAGES[first] : null;
}

export function isPageAllowed(
  page: AuthenticatedPage,
  allowedModules: readonly AllowedModuleCode[],
): boolean {
  return allowedModules.some((module) => MODULE_PAGES[module] === page);
}

export async function loginSession(
  request: LoginRequest,
  api: AuthApi = authApi,
): Promise<UserSummary> {
  const response = await api.login(request);
  tokenStore.saveAccessToken(response.accessToken, request.keepSignedIn);
  return response.user;
}

export async function restoreSession(
  api: AuthApi = authApi,
): Promise<UserSummary | null> {
  if (!tokenStore.getAccessToken()) return null;
  return api.getCurrentUser();
}

export interface LogoutResult {
  serverConfirmed: boolean;
  error: unknown | null;
}

export async function logoutSession(
  api: AuthApi = authApi,
): Promise<LogoutResult> {
  try {
    await api.logout();
    return { serverConfirmed: true, error: null };
  } catch (error) {
    return { serverConfirmed: false, error };
  } finally {
    tokenStore.clearAccessToken();
  }
}
