export type TightTextboxWidthOptions = {
  minWidth?: number;
  maxWidth?: number;
  padding?: number;
};

const finiteNumber = (value: unknown, fallback: number): number => {
  const parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : fallback;
};

export const isFabricTextboxObject = (target: any): boolean => {
  if (!target) return false;

  const types = [target.type, target?.constructor?.type, target?.constructor?.name]
    .map((value) => String(value ?? '').trim().toLowerCase());
  if (types.includes('textbox')) return true;

  try {
    return Boolean(target.isType?.('Textbox') || target.isType?.('textbox'));
  } catch {
    return false;
  }
};

export const computeTightTextboxWidth = (
  measuredWidth: number,
  options: TightTextboxWidthOptions = {},
): number => {
  const padding = Math.max(0, finiteNumber(options.padding, 2));
  const minWidth = Math.max(2, finiteNumber(options.minWidth, 20));
  const requestedMax = finiteNumber(options.maxWidth, Number.POSITIVE_INFINITY);
  const maxWidth = Math.max(minWidth, requestedMax);
  const contentWidth = Math.max(0, finiteNumber(measuredWidth, 0));

  return Math.max(minWidth, Math.min(maxWidth, Math.ceil(contentWidth + padding)));
};
