import type { PlatformPublicRouteContribution, PlatformRouteContribution, PlatformWebModule } from "../types";
import { routeViewSurfaceId } from "./views";

export function uiCapability<T = unknown>(capabilityName: string, modules: PlatformWebModule[]): T | null {
  for (const module of modules) {
    const value = module.uiCapabilities?.[capabilityName];
    if (value !== undefined) return value as T;
  }
  return null;
}

export function uiCapabilities<T = unknown>(capabilityName: string, modules: PlatformWebModule[]): T[] {
  return modules.flatMap((module) => {
    const value = module.uiCapabilities?.[capabilityName];
    return value === undefined ? [] : [value as T];
  });
}

export function hasUiCapability(capabilityName: string, modules: PlatformWebModule[]): boolean {
  return uiCapability(capabilityName, modules) !== null;
}

export function moduleInstalled(moduleId: string, modules: PlatformWebModule[]): boolean {
  return modules.some((module) => module.id === moduleId);
}

export function moduleIntegrationEnabled(moduleId: string, dependencyId: string, modules: PlatformWebModule[]): boolean {
  const module = modules.find((item) => item.id === moduleId);
  if (!module) return false;
  return Boolean(module.dependencies?.includes(dependencyId) || (module.optionalDependencies?.includes(dependencyId) && moduleInstalled(dependencyId, modules)));
}

export function routeContributionsForModules(modules: PlatformWebModule[]): PlatformRouteContribution[] {
  return modules.flatMap((module) =>
    (module.routes ?? []).map((route) => ({
      ...route,
      surfaceId: route.surfaceId ?? routeViewSurfaceId(module.id, route.path)
    }))
  ).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
}

export function publicRouteContributionsForModules(modules: PlatformWebModule[]): PlatformPublicRouteContribution[] {
  return modules.flatMap((module) => module.publicRoutes ?? []).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
}
