import {
  loadDashboardRuntime,
  type DashboardRuntimeOptions,
  type DashboardRuntimeState,
} from "$lib/server/dashboard";
import {
  resolveDashboardDatasources,
  resolveDashboardTile,
  type DashboardTileReference,
  type DashboardTileResolution,
  type DatasourceResolutionOptions,
} from "$lib/server/datasources";

export interface LoadDashboardResponseOptions
  extends Pick<
    DashboardRuntimeOptions,
    "refreshSeedDocument" | "seedIfEmpty" | "seedDocument"
  >,
    DatasourceResolutionOptions {
  disableLiveDatasources?: boolean;
  hydrateLiveDatasources?: boolean;
}

export async function loadDashboardResponse(
  options: LoadDashboardResponseOptions = {},
): Promise<DashboardRuntimeState> {
  const liveHydrationEnabled =
    !options.disableLiveDatasources &&
    process.env.DISABLE_LIVE_DATASOURCES !== "1";
  const dashboard = loadDashboardRuntime(undefined, {
    refreshSeedDocument: options.refreshSeedDocument ?? true,
    seedIfEmpty: options.seedIfEmpty ?? true,
    seedDocument: options.seedDocument,
  });

  if (dashboard.state !== "ready") {
    return dashboard;
  }

  if (
    !options.hydrateLiveDatasources ||
    options.disableLiveDatasources ||
    process.env.DISABLE_LIVE_DATASOURCES === "1"
  ) {
    return {
      ...dashboard,
      liveDatasourceHydration: {
        enabled: liveHydrationEnabled,
      },
    };
  }

  return {
    ...dashboard,
    document: await resolveDashboardDatasources(dashboard.document, options),
    liveDatasourceHydration: {
      enabled: false,
    },
  };
}

export async function loadDashboardTileResponse(
  tile: DashboardTileReference,
  options: LoadDashboardResponseOptions = {},
): Promise<DashboardTileResolution> {
  const dashboard = loadDashboardRuntime(undefined, {
    refreshSeedDocument: options.refreshSeedDocument ?? true,
    seedIfEmpty: options.seedIfEmpty ?? true,
    seedDocument: options.seedDocument,
  });

  if (dashboard.state !== "ready") {
    return {
      state: "not_found",
      tile,
      message: `Dashboard is not ready: ${dashboard.state}`,
    };
  }

  return resolveDashboardTile(dashboard.document, tile, options);
}

export async function handleDashboardRoute(): Promise<Response> {
  return Response.json(await loadDashboardResponse());
}

export async function handleDashboardTileRoute(pathname: string): Promise<Response> {
  const tile = parseDashboardTilePath(pathname);
  if (!tile) {
    return Response.json(
      { ok: false, message: "Invalid dashboard tile route" },
      { status: 404 },
    );
  }

  const response = await loadDashboardTileResponse(tile);
  return Response.json(response, {
    status: response.state === "ready" ? 200 : 404,
  });
}

function parseDashboardTilePath(pathname: string): DashboardTileReference | null {
  const parts = pathname.split("/").filter(Boolean);
  const [, dashboard, tileRoot, kind, firstId, secondId] = parts;
  if (dashboard !== "dashboard" || tileRoot !== "tile" || !kind || !firstId) {
    return null;
  }

  const id = decodeURIComponent(firstId);
  if (kind === "telemetry" || kind === "service" || kind === "module") {
    return { kind, id };
  }

  if (kind === "status" && secondId) {
    return {
      kind,
      stripId: id,
      id: decodeURIComponent(secondId),
    };
  }

  return null;
}
