import { dimensionLabDashboardFixture } from "$lib/dashboard-seed/dimensionlab";
import type { DashboardDocument } from "@dimensionlab/dashboard-model";
import {
  createDashboardStore,
  DashboardPersistenceValidationError,
  type DashboardStore,
} from "$lib/server/db/dashboard-store";
import { UnsupportedDashboardModelVersionError } from "$lib/server/db/model-migrations";

export type DashboardRuntimeState =
  | DashboardRuntimeEmpty
  | DashboardRuntimeInvalid
  | DashboardRuntimeLoading
  | DashboardRuntimeReady;

export interface DashboardRuntimeReady {
  state: "ready";
  document: DashboardDocument;
  schemaVersion: string;
  currentRevisionId: string;
}

export interface DashboardRuntimeEmpty {
  state: "empty";
  title: string;
  subtitle: string;
  message: string;
}

export interface DashboardRuntimeLoading {
  state: "loading";
  title: string;
  subtitle: string;
  message: string;
}

export interface DashboardRuntimeInvalid {
  state: "invalid";
  title: string;
  subtitle: string;
  message: string;
  errors: string[];
}

export interface DashboardRuntimeOptions {
  refreshSeedDocument?: boolean;
  seedIfEmpty?: boolean;
  seedDocument?: DashboardDocument;
}

export function loadDashboardRuntime(
  store?: DashboardStore,
  options: DashboardRuntimeOptions = {},
): DashboardRuntimeState {
  const dashboardStore = store || createDashboardStore();

  try {
    const seedDocument = options.seedDocument || dimensionLabDashboardFixture;
    const active = dashboardStore.getActiveDashboard();
    if (active) {
      if (
        options.refreshSeedDocument &&
        shouldRefreshSeedDashboard(active, seedDocument)
      ) {
        const refreshed = dashboardStore.commitDashboard(seedDocument, {
          actor: "initial-seed",
          message: "refresh bundled dashboard document",
        });
        return readyRuntimeState(refreshed.document, refreshed.id);
      }

      return readyRuntimeState(active.document, active.currentRevisionId);
    }

    if (!options.seedIfEmpty) {
      return {
        state: "empty",
        title: "No Dashboard Model",
        subtitle: "No active document",
        message: "No validated dashboard document is active yet.",
      };
    }

    const seeded = dashboardStore.seedDashboardIfEmpty(
      seedDocument,
      {
        actor: "initial-seed",
        message: "load initial dashboard document",
      },
    );

    return readyRuntimeState(seeded.document, seeded.id);
  } catch (error) {
    if (error instanceof DashboardPersistenceValidationError) {
      return invalidRuntimeState(error.failure.errors);
    }

    if (error instanceof UnsupportedDashboardModelVersionError) {
      return invalidRuntimeState([error.message]);
    }

    throw error;
  } finally {
    if (!store) dashboardStore.close();
  }
}

function readyRuntimeState(
  document: DashboardDocument,
  currentRevisionId: string,
): DashboardRuntimeReady {
  return {
    state: "ready",
    document,
    schemaVersion: document.schemaVersion,
    currentRevisionId,
  };
}

function invalidRuntimeState(errors: string[]): DashboardRuntimeInvalid {
  return {
    state: "invalid",
    title: "Invalid Dashboard Model",
    subtitle: "Validation failed",
    message: "The active dashboard document could not be validated.",
    errors,
  };
}

function shouldRefreshSeedDashboard(
  active: { document: DashboardDocument; revision: { actor: string } },
  seedDocument: DashboardDocument,
): boolean {
  if (active.revision.actor !== "initial-seed") return false;
  if (!isBundledDimensionLabSeed(active.document, seedDocument)) return false;
  return JSON.stringify(active.document) !== JSON.stringify(seedDocument);
}

function isBundledDimensionLabSeed(
  document: DashboardDocument,
  seedDocument: DashboardDocument,
): boolean {
  return (
    document.metadata.title === seedDocument.metadata.title &&
    document.metadata.description === seedDocument.metadata.description
  );
}
