```ts
export function orderSkeinHands(hands: any[]): any {
  if (!Array.isArray(hands) || hands.length === 0) {
    throw new Error("Invalid input: must be a non-empty array of hands.");
  }

  const grades = hands.map(hand => gradeHand(hand));
  const orderedIndices = Array.from({ length: hands.length }, (_, i) => i);

  orderedIndices.sort((a, b) => {
    if (grades[a] !== grades[b]) {
      return compareGrades(grades[a], grades[b]);
    }
    return compareHands(hands[a], hands[b]);
  });

  return {
    grades,
    order: orderedIndices
  };
}

function gradeHand(hand: any): string {
  if (!Array.isArray(hand) || hand.length !== 5) {
    throw new Error("Invalid hand: must be an array of exactly five cards.");
  }

  const cardSet = new Set(hand);
  if (cardSet.size !== 5) {
    throw new Error("Invalid hand: contains duplicate cards.");
  }

  const pips = hand.map(card => parseInt(card[0], 10));
  const houses = hand.map(card => card[1]);

  const uniquePips = [...new Set(pips)];
  const uniqueHouses = [...new Set(houses)];

  if (uniquePips.length === 2) {
    return "monolith";
  } else if (uniquePips.length === 5 && uniqueHouses.length === 4) {
    return "prism";
  } else if (uniquePips.length === 5 && Math.max(...pips) - Math.min(...pips) === 4) {
    return "chain";
  } else if (uniquePips.length === 3) {
    return "echo";
  } else if (uniquePips.length === 4) {
    return "twin";
  } else {
    return "drift";
  }
}

function compareGrades(gradeA: string, gradeB: string): number {
  const gradesOrder = ["monolith", "prism", "chain", "echo", "twin", "drift"];
  return gradesOrder.indexOf(gradeA) - gradesOrder.indexOf(gradeB);
}

function compareHands(handA: any[], handB: any[]): number {
  const ladderA = getLadder(handA);
  const ladderB = getLadder(handB);

  for (let i = 0; i < ladderA.length; i++) {
    if (ladderA[i] !== ladderB[i]) {
      return ladderB[i] - ladderA[i];
    }
  }

  const weightA = handA.map(card => getHouseWeight(card[1])).sort((a, b) => b - a);
  const weightB = handB.map(card => getHouseWeight(card[1])).sort((a, b) => b - a);

  for (let i = 0; i < weightA.length; i++) {
    if (weightA[i] !== weightB[i]) {
      return weightB[i] - weightA[i];
    }
  }

  return 0;
}

function getLadder(hand: any[]): number[] {
  const pipCounts = hand.reduce((acc, card) => {
    acc[parseInt(card[0], 10)]++;
    return acc;
  }, Array(11).fill(0));

  return pipCounts
    .map((count, index) => ({ count, pip: index }))
    .filter(item => item.count > 0)
    .sort((a, b) => {
      if (b.count === a