import {
  DASHBOARD_SCHEMA_VERSION,
  validateDashboardDocument,
  type DashboardDocument,
  type DashboardValidationFailure,
} from "@dimensionlab/dashboard-model";

export interface DashboardModelMigrationSuccess {
  valid: true;
  document: DashboardDocument;
  fromVersion: string;
  toVersion: typeof DASHBOARD_SCHEMA_VERSION;
  migrated: boolean;
}

export interface DashboardModelMigrationFailure {
  valid: false;
  failure: DashboardValidationFailure;
}

export type DashboardModelMigrationResult =
  | DashboardModelMigrationFailure
  | DashboardModelMigrationSuccess;

export class UnsupportedDashboardModelVersionError extends Error {
  constructor(
    readonly fromVersion: string,
    readonly toVersion: string,
  ) {
    super(`No dashboard model migration from ${fromVersion} to ${toVersion}`);
    this.name = "UnsupportedDashboardModelVersionError";
  }
}

export function migrateDashboardDocumentForPersistence(
  value: unknown,
): DashboardModelMigrationResult {
  const version = readSchemaVersion(value);
  if (version && version !== DASHBOARD_SCHEMA_VERSION) {
    throw new UnsupportedDashboardModelVersionError(version, DASHBOARD_SCHEMA_VERSION);
  }

  const validation = validateDashboardDocument(value);
  if (!validation.valid) {
    return { valid: false, failure: validation };
  }

  return {
    valid: true,
    document: validation.data,
    fromVersion: DASHBOARD_SCHEMA_VERSION,
    toVersion: DASHBOARD_SCHEMA_VERSION,
    migrated: false,
  };
}

function readSchemaVersion(value: unknown): string | null {
  if (!value || typeof value !== "object") return null;

  const schemaVersion = (value as { schemaVersion?: unknown }).schemaVersion;
  return typeof schemaVersion === "string" ? schemaVersion : null;
}
