/**
 * Imperial ↔ metric conversion + display helpers for yacht dimensions.
 * The schema stores both `*Ft` and `*M` separately so the rep can edit
 * either unit without losing precision; this module is the single source
 * for the formulas and rendering.
 */

const FT_PER_M = 3.28084;

export function feetToMeters(ft: number | string | null | undefined): number | null {
  const n = typeof ft === 'string' ? Number.parseFloat(ft) : ft;
  if (n === null || n === undefined || !Number.isFinite(n)) return null;
  return n / FT_PER_M;
}

export function metersToFeet(m: number | string | null | undefined): number | null {
  const n = typeof m === 'string' ? Number.parseFloat(m) : m;
  if (n === null || n === undefined || !Number.isFinite(n)) return null;
  return n * FT_PER_M;
}

/** One decimal place is enough for marina-scale dimensions; trailing
 *  zero stripped for cleaner display. Returns null when input is null. */
export function formatNumber1dp(n: number | null | undefined): string | null {
  if (n === null || n === undefined || !Number.isFinite(n)) return null;
  return n.toFixed(1).replace(/\.0$/, '');
}

export interface YachtDimensions {
  lengthFt: string | number | null;
  widthFt: string | number | null;
  draftFt: string | number | null;
  lengthM: string | number | null;
  widthM: string | number | null;
  draftM: string | number | null;
}

/**
 * Returns the dimension in the requested unit, deriving from the other
 * unit when the requested one is unset. Lets the UI render both units
 * side-by-side without the rep having to enter both.
 */
export function dimInFeet(value: {
  ft: number | string | null;
  m: number | string | null;
}): string | null {
  const direct = parseNum(value.ft);
  if (direct !== null) return formatNumber1dp(direct);
  return formatNumber1dp(metersToFeet(value.m));
}
export function dimInMeters(value: {
  ft: number | string | null;
  m: number | string | null;
}): string | null {
  const direct = parseNum(value.m);
  if (direct !== null) return formatNumber1dp(direct);
  return formatNumber1dp(feetToMeters(value.ft));
}

function parseNum(v: number | string | null | undefined): number | null {
  if (v === null || v === undefined) return null;
  const n = typeof v === 'string' ? Number.parseFloat(v) : v;
  return Number.isFinite(n) ? n : null;
}

/**
 * One-line summary used in the detail header. Shows both units when
 * any dimension is known, deriving missing values via the formulas
 * above. Returns null only when the yacht has no dimensions at all.
 */
export function formatYachtDimensionsBothUnits(yacht: YachtDimensions): string | null {
  const lFt = dimInFeet({ ft: yacht.lengthFt, m: yacht.lengthM });
  const wFt = dimInFeet({ ft: yacht.widthFt, m: yacht.widthM });
  const dFt = dimInFeet({ ft: yacht.draftFt, m: yacht.draftM });
  const lM = dimInMeters({ ft: yacht.lengthFt, m: yacht.lengthM });
  const wM = dimInMeters({ ft: yacht.widthFt, m: yacht.widthM });
  const dM = dimInMeters({ ft: yacht.draftFt, m: yacht.draftM });

  const ftParts: string[] = [];
  if (lFt) ftParts.push(`${lFt} ft`);
  if (wFt) ftParts.push(`${wFt} ft`);
  const mParts: string[] = [];
  if (lM) mParts.push(`${lM} m`);
  if (wM) mParts.push(`${wM} m`);

  if (ftParts.length === 0 && !dFt) return null;

  const ftSummary = ftParts.join(' × ');
  const mSummary = mParts.join(' × ');
  const head = ftSummary && mSummary ? `${ftSummary} (${mSummary})` : ftSummary || mSummary;

  if (dFt && dM) return `${head} (draft ${dFt} ft / ${dM} m)`;
  if (dFt) return `${head} (draft ${dFt} ft)`;
  if (dM) return `${head} (draft ${dM} m)`;
  return head;
}
