import type { LegacyRecord, LegacyTalentChoice } from "../legacy/interop.js";
import type { AllocationState, LegacyStatRecord } from "./legacySessionTypes";

export function clamp(value: number, min: number, max: number): number {
  return Math.max(min, Math.min(max, value));
}

export function shuffleEntries<Entry>(entries: Entry[]): Entry[] {
  const shuffled = [...entries];

  for (let index = shuffled.length - 1; index > 0; index -= 1) {
    const swapIndex = Math.floor(Math.random() * (index + 1));
    const currentEntry = shuffled[index];
    shuffled[index] = shuffled[swapIndex]!;
    shuffled[swapIndex] = currentEntry!;
  }

  return shuffled;
}

export function createEmptyRecord(): LegacyStatRecord {
  return {
    CHR: 0,
    INT: 0,
    STR: 0,
    MNY: 0,
    SPR: 5,
  };
}

export function createRecordSnapshot(record: LegacyRecord): LegacyStatRecord {
  return {
    CHR: record.CHR,
    INT: record.INT,
    STR: record.STR,
    MNY: record.MNY,
    SPR: record.SPR,
  };
}

export function createAllocation(total: number): AllocationState {
  return {
    CHR: 0,
    INT: 0,
    STR: 0,
    MNY: 0,
    SPR: 5,
    total,
  };
}

export function randomizeDraftAllocation(total: number): AllocationState {
  const allocation = createAllocation(total);
  let remaining = total;
  const buckets = [10, 10, 10, 10];

  while (remaining > 0) {
    const chunk =
      Math.round(Math.random() * (Math.min(remaining, 10) - 1)) + 1;

    for (;;) {
      const index = Math.floor(Math.random() * 4) % 4;
      if (buckets[index]! - chunk < 0) {
        continue;
      }

      buckets[index]! -= chunk;
      remaining -= chunk;
      break;
    }
  }

  allocation.CHR = 10 - buckets[0]!;
  allocation.INT = 10 - buckets[1]!;
  allocation.STR = 10 - buckets[2]!;
  allocation.MNY = 10 - buckets[3]!;
  return allocation;
}

export function getRemainingPoints(allocation: AllocationState | null): number {
  if (!allocation) {
    return 0;
  }

  return (
    allocation.total -
    allocation.CHR -
    allocation.INT -
    allocation.STR -
    allocation.MNY
  );
}

export function sortLegacyExtendOptions(
  selectedTalents: LegacyTalentChoice[],
  preferredTalentId: number | null = null,
): LegacyTalentChoice[] {
  return [...selectedTalents].sort((left, right) => {
    if (left.id === preferredTalentId) {
      return -1;
    }

    if (right.id === preferredTalentId) {
      return 1;
    }

    return right.grade - left.grade;
  });
}
