export const TIMELINE_MINUTES_PER_DAY = 1440;
export const TIMELINE_STEP_MINUTES = 15;

export const parseTimelineDurationMinutes = (
  value: unknown,
): number | undefined => {
  if (typeof value !== "string") {
    return undefined;
  }

  const parts = value
    .trim()
    .split(":")
    .map((part) => Number(part));

  if (
    (parts.length !== 2 && parts.length !== 3) ||
    parts.some((part) => !Number.isFinite(part) || part < 0)
  ) {
    return undefined;
  }

  const [hours, minutes, seconds = 0] = parts;
  if (minutes >= 60 || seconds >= 60) {
    return undefined;
  }

  return hours * 60 + minutes + Math.floor(seconds / 60);
};

export const coerceTimelineDurationMinutes = (
  value: unknown,
  fallbackMinutes: number,
) => {
  const minutes = parseTimelineDurationMinutes(value);
  return minutes && minutes > 0 ? minutes : fallbackMinutes;
};

export const normalizeTimelineMinutes = (
  minutes: number | undefined,
  minTime = 0,
  maxTime = TIMELINE_MINUTES_PER_DAY,
) => {
  if (typeof minutes !== "number" || !Number.isFinite(minutes)) {
    return minTime;
  }

  return Math.min(Math.max(minutes, minTime), maxTime);
};

export const getRoundedCurrentTimelineMinutes = (
  date = new Date(),
  stepMinutes = TIMELINE_STEP_MINUTES,
  maxMinutes = TIMELINE_MINUTES_PER_DAY,
) => {
  const safeStep = stepMinutes > 0 ? stepMinutes : TIMELINE_STEP_MINUTES;
  const minutes = date.getHours() * 60 + date.getMinutes();
  return normalizeTimelineMinutes(
    Math.floor(minutes / safeStep) * safeStep,
    0,
    maxMinutes,
  );
};

export const formatTimelineTime = (
  minutes: number | undefined,
  minTime = 0,
  maxTime = TIMELINE_MINUTES_PER_DAY,
) => {
  const normalizedMinutes = normalizeTimelineMinutes(minutes, minTime, maxTime);
  const hours = Math.floor(normalizedMinutes / 60);
  const mins = normalizedMinutes % 60;
  return `${hours.toString().padStart(2, "0")}:${mins
    .toString()
    .padStart(2, "0")}`;
};

export const getTimelineDisabledRangePercentages = (
  minTime: number,
  maxTime: number,
  totalMinutes = TIMELINE_MINUTES_PER_DAY,
) => {
  const safeTotalMinutes =
    totalMinutes > 0 ? totalMinutes : TIMELINE_MINUTES_PER_DAY;
  const rangeStart = normalizeTimelineMinutes(minTime, 0, safeTotalMinutes);
  const rangeEnd = normalizeTimelineMinutes(maxTime, 0, safeTotalMinutes);

  return {
    leftWidth: (rangeStart / safeTotalMinutes) * 100,
    rightLeft: (rangeEnd / safeTotalMinutes) * 100,
    rightWidth:
      ((safeTotalMinutes - rangeEnd) / safeTotalMinutes) * 100,
  };
};
