/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import { useMemo } from 'react' import { type ColumnDef } from '@tanstack/react-table' import { AlertTriangle } from 'lucide-react' import { useTranslation } from 'react-i18next' import { Checkbox } from '@/components/ui/checkbox' import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '@/components/ui/tooltip' import { StatusBadge } from '@/components/status-badge' import type { RatioType } from '../types' import { getOrderedRatioTypes, getPreferredSyncField, getSyncFieldLabel, isSelectableUpstreamValue, type ModelRow, type ResolutionsMap, } from './upstream-ratio-sync-helpers' export function useUpstreamRatioSyncColumns( upstreamNames: string[], resolutions: ResolutionsMap, ratioTypeFilter: string, isDisabled: boolean, onSelectValue: ( model: string, ratioType: RatioType, value: number | string, sourceName: string ) => void, onUnselectValue: (model: string, ratioType: RatioType) => void, onBulkSelect: (upstreamName: string, rows: ModelRow[]) => void, onBulkUnselect: (upstreamName: string, rows: ModelRow[]) => void ): ColumnDef[] { const { t } = useTranslation() return useMemo[]>(() => { const baseColumns: ColumnDef[] = [ { accessorKey: 'model', header: t('Model'), cell: ({ row }) => { const model = row.original.model return (
{model} {row.original.billingConflict && (

{t( 'This model has both fixed price and ratio billing conflicts' )}

)}
) }, }, { id: 'current', header: t('Current Price'), cell: ({ row }) => { const fields = getOrderedRatioTypes( row.original.ratioTypes, ratioTypeFilter ) return (
{fields.map((ratioType) => { const current = row.original.ratioTypes[ratioType]?.current return (
{current === null || current === undefined ? ( ) : ( } >

{String(current)}

)}
) })}
) }, }, ] const upstreamColumns: ColumnDef[] = upstreamNames.map( (upstreamName) => ({ id: `upstream_${upstreamName}`, header: ({ table }) => { const rows = table.getFilteredRowModel().rows.map((r) => r.original) let selectableCount = 0 let selectedCount = 0 rows.forEach((row) => { getOrderedRatioTypes(row.ratioTypes, ratioTypeFilter).forEach( (ratioType) => { const upstreamVal = row.ratioTypes[ratioType]?.upstreams?.[upstreamName] const preferredField = getPreferredSyncField( row.ratioTypes, ratioType, upstreamName ) if ( preferredField === ratioType && isSelectableUpstreamValue(upstreamVal) ) { selectableCount++ if (resolutions[row.model]?.[ratioType] === upstreamVal) { selectedCount++ } } } ) }) const allSelected = selectableCount > 0 && selectedCount === selectableCount const someSelected = selectedCount > 0 && selectedCount < selectableCount return (
{selectableCount > 0 && ( { if (checked) { onBulkSelect(upstreamName, rows) } else { onBulkUnselect(upstreamName, rows) } }} /> )} {upstreamName}
) }, cell: ({ row }) => { const fields = getOrderedRatioTypes( row.original.ratioTypes, ratioTypeFilter ).filter( (ratioType) => getPreferredSyncField( row.original.ratioTypes, ratioType, upstreamName ) === ratioType ) return (
{fields.map((ratioType) => { const diff = row.original.ratioTypes[ratioType] const upstreamVal = diff?.upstreams?.[upstreamName] const isConfident = diff?.confidence?.[upstreamName] !== false return (
{renderUpstreamValue({ upstreamVal, isConfident, isSelected: resolutions[row.original.model]?.[ratioType] === upstreamVal, isDisabled, t, onSelect: () => onSelectValue( row.original.model, ratioType, upstreamVal as number | string, upstreamName ), onUnselect: () => onUnselectValue(row.original.model, ratioType), })}
) })}
) }, }) ) return [...baseColumns, ...upstreamColumns] }, [ upstreamNames, resolutions, ratioTypeFilter, isDisabled, onSelectValue, onUnselectValue, onBulkSelect, onBulkUnselect, t, ]) } type RenderUpstreamValueArgs = { upstreamVal: number | string | 'same' | null | undefined isConfident: boolean isSelected: boolean isDisabled: boolean t: (key: string) => string onSelect: () => void onUnselect: () => void } function renderUpstreamValue(args: RenderUpstreamValueArgs) { const { upstreamVal, isConfident, isSelected, isDisabled, t } = args if (upstreamVal === null || upstreamVal === undefined) { return ( ) } if (upstreamVal === 'same') { return ( ) } const text = String(upstreamVal) return (
{ if (checked) { args.onSelect() } else { args.onUnselect() } }} /> } > {text}

{text}

{!isConfident && (

{t('This data may be unreliable, use with caution')}

)}
) }