import type { DashboardReportEefRow, DashboardReportFcrRow } from '../types/dashboardReport.ts'; type ScalesKpiRow = { food_total?: number; iot_weight?: number; chicken_life?: number; harvest_weight_total?: number; iot_fcr?: number; chicken_life_percentage?: number; iot_average_harvest_bw?: number; iot_average_day_weight?: number; iot_eef?: number; }; const toValidRatio = (value: number | undefined): number | null => value !== undefined && value > 0 ? value : null; const toNullableNumber = (value: number | undefined | null): number | null => value !== undefined && value !== null ? value : null; const isKpiMap = (value: unknown): value is Record => !!value && typeof value === 'object' && !Array.isArray(value); const kpiDaysInRange = ( kpi: unknown, upToDay: number ): Array<[number, ScalesKpiRow]> => { if (!isKpiMap(kpi)) return []; return Object.entries(kpi) .map(([dayKey, row]) => [Number(dayKey), row || {}] as [number, ScalesKpiRow]) .filter(([day]) => Number.isFinite(day) && day >= 0 && day <= upToDay) .sort((a, b) => a[0] - b[0]); }; export function mapKpiToFcrRows(kpi: unknown, upToDay: number): DashboardReportFcrRow[] { return kpiDaysInRange(kpi, upToDay).map(([day, row]) => ({ day, feedTotal: row.food_total ?? 0, iotWeight: toNullableNumber(row.iot_weight), chickenLife: row.chicken_life ?? 0, harvestWeightTotal: row.harvest_weight_total ?? 0, iotFcr: toValidRatio(row.iot_fcr), })); } export function mapKpiToEefRows(kpi: unknown, upToDay: number): DashboardReportEefRow[] { return kpiDaysInRange(kpi, upToDay).map(([day, row]) => ({ day, chickenLifePercentage: toNullableNumber(row.chicken_life_percentage), iotAverageHarvestBw: toNullableNumber(row.iot_average_harvest_bw), iotAverageDayWeight: toNullableNumber(row.iot_average_day_weight), iotFcr: toValidRatio(row.iot_fcr), iotEef: toValidRatio(row.iot_eef), })); } export function latestValidRatio( rows: T[] | null | undefined, key: keyof T ): number | null { if (!rows?.length) return null; for (let i = rows.length - 1; i >= 0; i--) { const value = rows[i]?.[key]; if (typeof value === 'number' && Number.isFinite(value) && value > 0) { return value; } } return null; }