import { sortableTable, sortValuesAttribute } from "./list_sorting.js";
function buildArchiveRows(state, { getEventName, getClassName, getTrackLayoutLabel }) {
return (state.sessions || [])
.filter((session) => session.status === "finished")
.map((session) => {
const event = state.events.find((item) => item.id === session.eventId) || null;
const result = state.resultsBySession?.[session.id] || null;
const competitors = result ? Object.values(result.competitors || {}) : [];
const winner = competitors
.slice()
.sort((left, right) => (Number(right.laps || 0) - Number(left.laps || 0)) || (Number(left.totalElapsedMs || 0) - Number(right.totalElapsedMs || 0)))[0] || null;
return {
session,
event,
result,
competitors,
eventName: event ? getEventName(event.id) : session.name,
className: event ? getClassName(event.classId) : "",
date: event?.date || (session.endedAt ? new Date(session.endedAt).toISOString().slice(0, 10) : ""),
winnerName: winner?.displayName || winner?.driverName || "",
adjustmentCount: (result?.adjustments || []).length,
trackLayoutLabel: getTrackLayoutLabel(state.trackLayouts, session.trackLayoutId),
};
})
.sort((left, right) => Number(right.session.endedAt || 0) - Number(left.session.endedAt || 0));
}
function matchesArchiveFilters(row, filters) {
const search = filters.search.trim().toLowerCase();
if (search && !`${row.eventName} ${row.session.name}`.toLowerCase().includes(search)) return false;
if (filters.classId && row.event?.classId !== filters.classId) return false;
if (filters.driverId && !row.competitors.some((competitor) => String(competitor.driverId || "") === filters.driverId)) return false;
if (filters.dateFrom && row.date && row.date < filters.dateFrom) return false;
if (filters.dateTo && row.date && row.date > filters.dateTo) return false;
return true;
}
function renderArchiveDetail(row, deps) {
const { t, escapeHtml, formatLap, formatRaceClock, renderTable, buildLeaderboard, getCompetitorPassings } = deps;
const { session, event, result } = row;
const leaderboard = buildLeaderboard(session);
const adjustments = result?.adjustments || [];
return `
${t("archive.no_standings")} ${t("archive.no_penalties")} ${t("timing.no_lap_history")} ${t("archive.no_standings")}${escapeHtml(row.eventName)} - ${escapeHtml(session.name)}${row.trackLayoutLabel ? ` ${escapeHtml(row.trackLayoutLabel)}` : ""}
${t("archive.standings")}
${leaderboard.length
? renderTable(
[t("table.pos"), t("table.driver"), t("table.laps"), t("table.best_lap"), t("timing.total_time")],
leaderboard.map((rowItem, index) => `
`)
)
: `${index + 1}
${escapeHtml(rowItem.displayName || rowItem.driverName || t("common.unknown_driver"))}
${rowItem.laps}
${formatLap(rowItem.bestLapMs)}
${escapeHtml(rowItem.resultDisplay || "-")}
${t("archive.penalties")}
${adjustments.length
? renderTable(
[t("table.time"), t("table.driver"), t("archive.action"), t("archive.detail")],
adjustments.slice().reverse().map((adjustment) => `
`)
)
: `${escapeHtml(new Date(adjustment.ts || 0).toLocaleTimeString())}
${escapeHtml(adjustment.displayName || "-")}
${escapeHtml(t(`archive.adjustment_${adjustment.category}`) || adjustment.category || "-")}
${escapeHtml(adjustment.detail || "-")}
${t("archive.lap_history")}
${leaderboard.map((rowItem) => {
const passings = getCompetitorPassings(session, rowItem);
return `
${escapeHtml(rowItem.displayName || rowItem.driverName || t("common.unknown_driver"))} - ${rowItem.laps} ${t("table.laps")}
${passings.length
? renderTable(
[t("table.lap"), t("table.time"), t("table.last_lap")],
passings.map((passing, index) => `
`)
)
: `${index + 1}
${formatRaceClock(Math.max(0, passing.timestamp - (session.startedAt || passing.timestamp)))}
${formatLap(passing.lapMs)}
${t("archive.hint")}
${t("archive.no_results")}
`}