// Production UI: Compact Facility Card (HTML Mount and Fine-grained DOM update)
// High-density overview cards with photographic thumbnail, live rates, bottleneck status, and quick-actions
import { getProduct, getNextMilestone, getUnitMilestoneMultiplier, SECTORS } from '../../data/products.js';
import { fmtCurrency, fmtNum } from '../../core/formatters.js';
import { calculateMultiCost, getProductOutputRates } from './ratesCalculator.js';
export function renderCompactFacilityCardHtml(p, pState, state, buyMode) {
const sector = SECTORS.find(s => s.id === p.sector);
const isSelected = state.selectedProductId === p.id;
const productImgPath = `assets/images/products/${p.id}_product.jpg`;
if (!pState.unlocked) {
const canAffordUnlock = state.cash >= p.unlockCost;
return `
${sector?.name || 'Industry'} • T${p.tier}
Permit Needed
${p.name}
${p.facilityName} • Wholesale: ${fmtCurrency(p.basePrice)}
`;
}
const nextM = getNextMilestone(pState.lines || 0);
const rates = getProductOutputRates(p, pState, state);
const milestoneMult = rates.milestoneMult || getUnitMilestoneMultiplier(pState.lines || 0);
const calc = calculateMultiCost(p.baseFacilityCost, pState.lines || 0, buyMode);
const canAffordBuy = state.cash >= calc.cost;
const currentThrottle = pState.productionTarget !== undefined ? pState.productionTarget : 1.0;
let statusClass = 'badge-success';
let statusLabel = `${milestoneMult}x Speed`;
let statusIcon = 'lucide:check-circle';
if (currentThrottle <= 0.0) {
statusClass = 'badge-idle';
statusLabel = 'Paused (0%)';
statusIcon = 'lucide:pause-circle';
} else if (pState.isBottlenecked) {
statusClass = 'badge-warning';
statusLabel = 'Starved';
statusIcon = 'lucide:alert-triangle';
} else if (!pState.lines || pState.lines === 0) {
statusClass = 'badge-idle';
statusLabel = '0 Lines';
statusIcon = 'lucide:circle-slash';
}
const progressPct = Math.min(100, Math.floor((pState.cycleProgress || 0) * 100));
return `
T${p.tier}
${sector?.name}
${statusLabel}
${p.name}
${pState.lines} lines
${fmtNum(pState.stock || 0, 0)}
•
${rates.isBottlenecked ? '0.0/s' : `${fmtNum(rates.prodRate || 0, 1)}/s`}
•
+$${fmtNum(rates.revRate || 0, 2)}/s
`;
}
export function updateCompactFacilityCardDom(p, pState, state, engine) {
if (!pState.unlocked) {
const canAfford = state.cash >= p.unlockCost;
const btn = document.getElementById(`btn-compact-unlock-${p.id}`);
if (btn && btn.disabled === canAfford) {
btn.disabled = !canAfford;
}
return;
}
const buyMode = state.buyMode || '1';
const rates = getProductOutputRates(p, pState, state);
const calc = calculateMultiCost(p.baseFacilityCost, pState.lines || 0, buyMode);
const canAffordBuy = state.cash >= calc.cost;
const currentThrottle = pState.productionTarget !== undefined ? pState.productionTarget : 1.0;
// Progress bar
const elProg = document.getElementById(`compact-progress-${p.id}`);
if (elProg) {
const pct = Math.min(100, Math.floor((pState.cycleProgress || 0) * 100));
elProg.style.width = `${pct}%`;
}
// Lines
const elLines = document.getElementById(`compact-lines-${p.id}`);
if (elLines) {
const txt = `${pState.lines || 0} lines`;
if (elLines.innerHTML !== txt) elLines.innerHTML = txt;
}
// Stock
const elStock = document.getElementById(`compact-stock-${p.id}`);
if (elStock) {
const val = fmtNum(pState.stock || 0, 0);
if (elStock.textContent !== val) elStock.textContent = val;
}
// Production Rate
const elUnits = document.getElementById(`compact-rate-units-${p.id}`);
if (elUnits) {
const txt = rates.isBottlenecked ? '0.0/s' : `${fmtNum(rates.prodRate || 0, 1)}/s`;
if (elUnits.textContent !== txt) elUnits.textContent = txt;
elUnits.className = `compact-stat-item ${rates.isBottlenecked ? 'text-warning' : 'text-profit'}`;
}
// Logistics Revenue Rate
const elRev = document.getElementById(`compact-rate-rev-${p.id}`);
if (elRev) {
const txt = `+$${fmtNum(rates.revRate || 0, 2)}/s`;
if (elRev.textContent !== txt) elRev.textContent = txt;
}
// Status Badge
const elBadge = document.getElementById(`compact-badge-${p.id}`);
const elBadgeText = document.getElementById(`compact-badge-text-${p.id}`);
if (elBadge && elBadgeText) {
let statusClass = 'badge-success';
let statusLabel = `${rates.milestoneMult}x Speed`;
let statusIcon = 'lucide:check-circle';
if (currentThrottle <= 0.0) {
statusClass = 'badge-idle';
statusLabel = 'Paused';
statusIcon = 'lucide:pause-circle';
} else if (rates.isBottlenecked) {
statusClass = 'badge-warning';
statusLabel = 'Starved';
statusIcon = 'lucide:alert-triangle';
} else if (!pState.lines || pState.lines === 0) {
statusClass = 'badge-idle';
statusLabel = '0 Lines';
statusIcon = 'lucide:circle-slash';
}
if (elBadgeText.textContent !== statusLabel) elBadgeText.textContent = statusLabel;
elBadge.className = `compact-status-badge ${statusClass}`;
const iconEl = elBadge.querySelector('iconify-icon');
if (iconEl && iconEl.getAttribute('icon') !== statusIcon) {
iconEl.setAttribute('icon', statusIcon);
}
}
// Buy Button
const btnExpand = document.getElementById(`btn-compact-expand-${p.id}`);
const spanExpand = document.getElementById(`compact-expand-text-${p.id}`);
if (btnExpand) {
if (btnExpand.disabled === canAffordBuy) {
btnExpand.disabled = !canAffordBuy;
}
if (spanExpand) {
const expText = `+${calc.count} (${fmtCurrency(calc.cost)})`;
if (spanExpand.textContent !== expText) spanExpand.textContent = expText;
}
}
}