import { useMemo } from 'react'; import { Text } from '@react-three/drei'; import * as THREE from 'three'; import type { Section3D, Position3D } from '../../lib/layoutApi'; import { PlantPosition, VisMode } from './types'; import { PlantSystem } from './PlantSystem'; // Convert pixel coordinates to world units (DB stores pixels, 3D uses meters/units) const SCALE = 0.1; // 1 pixel = 0.1 world units (so 700px = 70 units) interface SmartRackProps { section: Section3D; visMode: VisMode; onPlantClick: (plant: PlantPosition) => void; highlightedTags?: string[]; dimMode?: boolean; roomName?: string; // For breadcrumb } export function SmartRack({ section, visMode, onPlantClick, highlightedTags, dimMode, roomName }: SmartRackProps) { // Scale section dimensions to world units // Section posX/posY are RELATIVE to room, so we scale them for placement within room group const scaledSection = { posX: section.posX * SCALE, posY: section.posY * SCALE, width: section.width * SCALE, height: section.height * SCALE, }; // Calculate plant positions RELATIVE to section position (within room group) const positions: PlantPosition[] = useMemo(() => { const plantSpacing = 0.5; // Spacing between plants in world units // Calculate how many columns/rows fit based on section dimensions const maxCols = Math.max(...section.positions.map(p => p.column)) || 1; const maxRows = Math.max(...section.positions.map(p => p.row)) || 1; // Calculate actual spacing based on section dimensions const colSpacing = scaledSection.width / (maxCols + 1); const rowSpacing = scaledSection.height / (maxRows + 1); const actualSpacing = Math.min(colSpacing, rowSpacing, plantSpacing); return section.positions.map((pos: Position3D) => ({ ...pos, // Position plants within the scaled section bounds x: scaledSection.posX + (pos.column * actualSpacing), z: scaledSection.posY + (pos.row * actualSpacing), y: 0.4 + (pos.tier * 0.6), // Add breadcrumb data breadcrumb: { section: section.code || section.name, room: roomName, }, })); }, [section, scaledSection, roomName]); const distinctTiers = [...new Set(positions.map(p => p.tier))].sort((a, b) => a - b); const distinctRows = [...new Set(positions.map(p => p.row))].sort((a, b) => a - b); const distinctCols = [...new Set(positions.map(p => p.column))].sort((a, b) => a - b); const plantSpacing = 0.5; return ( {/* Section/Table Label */} {visMode === 'STANDARD' && ( {section.code || section.name} )} {/* Shelf/Tier surfaces */} {distinctTiers.map(tier => ( ))} {/* Support posts */} {[0, 1].map(xOffset => [0, 1].map(zOffset => ( )) )} {/* Row labels */} {visMode === 'STANDARD' && distinctRows.map(row => ( R{row} ))} {/* Column labels */} {visMode === 'STANDARD' && distinctCols.map(col => ( C{col} ))} ); }