import type {
  DashboardDocument,
  DashboardModule,
  ServiceEntry,
  ServiceGroup,
  StatusItem,
  StatusStrip,
  TelemetryCard,
} from "@dimensionlab/dashboard-model";
import type {
  UiDashboardPreview,
  UiModuleBlock,
  UiServiceGroup,
  UiServiceRow,
  UiStatusItem,
  UiTelemetryCard,
} from "@dimensionlab/ui";

export function dashboardDocumentToUiDashboard(
  document: DashboardDocument,
): UiDashboardPreview {
  return {
    eyebrow: document.schemaVersion,
    title: document.metadata.title,
    subtitle: document.metadata.subtitle,
    telemetry: orderedItems(document.layout.telemetry, document.telemetry).map(
      telemetryToUi,
    ),
    serviceGroups: orderedItems(
      document.layout.serviceGroups,
      document.serviceGroups,
    ).map(serviceGroupToUi),
    modules: orderedItems(
      document.layout.modules || [],
      document.modules || [],
    ).map(moduleToUi),
    statusItems: orderedItems(
      document.layout.statusStrips,
      document.statusStrips,
    ).flatMap(statusStripToUiItems),
    statusStripId: document.layout.statusStrips[0],
  };
}

function telemetryToUi(card: TelemetryCard): UiTelemetryCard {
  return {
    id: card.id,
    label: card.label,
    description: card.description,
    icon: card.icon,
    value: card.value,
    detail: card.detail,
    severity: card.severity,
    sparkline: card.sparkline,
  };
}

function serviceGroupToUi(group: ServiceGroup): UiServiceGroup {
  return {
    id: group.id,
    layout: group.layout,
    title: group.title,
    services: group.services.map(serviceToUi),
  };
}

function serviceToUi(service: ServiceEntry): UiServiceRow {
  return {
    id: service.id,
    label: service.label,
    description: service.description,
    icon: service.icon,
    severity: service.severity,
    detail: service.detail,
    link: service.link,
  };
}

function moduleToUi(module: DashboardModule): UiModuleBlock {
  return {
    id: module.id,
    title: module.title,
    label: module.label,
    value: module.value,
    detail: module.detail,
    icon: module.icon,
    severity: module.severity,
  };
}

function statusStripToUiItems(strip: StatusStrip): UiStatusItem[] {
  return strip.items.map((item) => statusItemToUi(strip.id, item));
}

function statusItemToUi(stripId: string, item: StatusItem): UiStatusItem {
  return {
    id: `${stripId}:${item.id}`,
    label: item.label,
    value: item.value,
    severity: item.severity,
    link: item.link,
  };
}

function orderedItems<T extends { id: string }>(ids: string[], items: T[]): T[] {
  const byId = new Map(items.map((item) => [item.id, item]));
  return ids.flatMap((id) => {
    const item = byId.get(id);
    return item ? [item] : [];
  });
}
