// ... imports ...
import { useMemo } from 'react';
import { Instances, Instance } from '@react-three/drei';
import * as THREE from 'three';
import { PlantPosition, VisMode, COLORS } from './types';
import { PlantIcon, PlantStage } from './PlantIcon';

// Mock helpers
const getMockPlantHealth = (_plantId: string) => {
    const r = Math.random();
    if (r > 0.95) return 'CRITICAL';
    if (r > 0.85) return 'WARNING';
    return 'GOOD';
};

const lerpColor = (c1: string, c2: string, t: number) => {
    const c1c = new THREE.Color(c1);
    const c2c = new THREE.Color(c2);
    return '#' + c1c.lerp(c2c, Math.min(1, Math.max(0, t))).getHexString();
};

const normalizeStage = (stage?: string): PlantStage => {
    if (!stage) return 'VEGETATIVE';
    const s = stage.toUpperCase();
    if (s === 'CLONE_IN') return 'CLONE_IN';
    if (s === 'VEGETATIVE') return 'VEGETATIVE';
    if (s === 'FLOWERING') return 'FLOWERING';
    if (s === 'DRYING') return 'DRYING';
    if (s === 'CURING') return 'CURING';
    if (s === 'HARVESTED') return 'HARVESTED';
    if (s === 'FINISHED') return 'FINISHED';
    return 'VEGETATIVE';
};

/**
 * Mocks a realistic lifecycle based on plant ID seed.
 * Returns the effective stage for a given historical date.
 */
const getHistoricalStage = (plant: PlantPosition['plant'], targetDate?: Date): PlantStage | 'HIDDEN' => {
    if (!plant || !targetDate) return normalizeStage(plant?.stage ?? undefined);

    // If viewing "Now" (within last minute), just show current stage
    if (Math.abs(Date.now() - targetDate.getTime()) < 60000) {
        return normalizeStage(plant.stage ?? undefined);
    }

    // Seed logic from PlantDataCard (needs to be consistent)
    const seed = plant.id.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);

    // Assume harvest date is roughly "Next Week" if currently flowering, or earlier if younger
    const approxTotalLifeDays = 120; // 14d clone, 40d veg, 60d flower, 60? 
    // Let's model backward from "Now"
    // Current Age (days) = (seed % 60) + 10;
    const currentAgeDays = (seed % 60) + 20;

    // Calculate "Planted At" date
    const plantedAt = new Date(Date.now() - (currentAgeDays * 24 * 60 * 60 * 1000));

    // Difference between target date and planted date
    const daysSincePlanted = (targetDate.getTime() - plantedAt.getTime()) / (1000 * 60 * 60 * 24);

    if (daysSincePlanted < 0) return 'HIDDEN'; // Not planted yet
    if (daysSincePlanted < 14) return 'CLONE_IN';
    if (daysSincePlanted < 50) return 'VEGETATIVE';
    if (daysSincePlanted < 110) return 'FLOWERING';
    if (daysSincePlanted < 120) return 'DRYING';
    return 'HARVESTED'; // Or 'FINISHED' / 'HIDDEN' if sold
};


interface PlantSystemProps {
    positions: PlantPosition[];
    visMode: VisMode;
    onPlantClick: (plant: PlantPosition) => void;
    highlightedTags?: string[];
    dimMode?: boolean;
    useIcons?: boolean;
    timelineDate?: Date; // Phase 3: Time Travel
}

export function PlantSystem({
    positions,
    visMode,
    onPlantClick,
    highlightedTags = [],
    dimMode = false,
    useIcons = true,
    timelineDate
}: PlantSystemProps) {
    if (!positions || positions.length === 0) return null;

    const plants = positions.filter(p => p.plant);
    const emptySlots = positions.filter(p => !p.plant);

    if (plants.length > 5000) return null;

    const highlightSet = useMemo(() => new Set(highlightedTags), [highlightedTags]);
    const hasHighlights = highlightedTags.length > 0;

    const plantData = useMemo(() => {
        return plants.map(pos => {
            const isHighlighted = pos.plant && highlightSet.has(pos.plant.tagNumber);
            const shouldDim = dimMode && hasHighlights && !isHighlighted;

            // Phase 3: Check history
            const stage = getHistoricalStage(pos.plant, timelineDate);

            let color: string;
            // If historical stage is HIDDEN, we don't render it (handled in return)

            switch (visMode) {
                case 'STANDARD':
                    color = (stage === 'FLOWERING') ? COLORS.FLOWER :
                        (stage === 'DRYING') ? COLORS.DRY :
                            (stage === 'CURING') ? COLORS.CURE :
                                (stage === 'CLONE_IN') ? '#3b82f6' :
                                    (stage === 'HARVESTED') ? '#6b7280' : // Gray for harvested
                                        COLORS.VEG;
                    break;
                case 'HEALTH':
                    const status = getMockPlantHealth(pos.plant!.id);
                    color = status === 'CRITICAL' ? COLORS.HEALTH_CRIT :
                        status === 'WARNING' ? COLORS.HEALTH_WARN : COLORS.HEALTH_GOOD;
                    break;
                case 'YIELD':
                    color = lerpColor('#86efac', '#14532d', Math.random());
                    break;
                default:
                    color = '#555';
            }

            return { pos, color, isHighlighted, shouldDim, stage };
        }).filter(p => p.stage !== 'HIDDEN' && p.stage !== 'FINISHED'); // Filter out plants that don't exist at this time
    }, [plants, visMode, highlightSet, dimMode, hasHighlights, timelineDate]);

    // New icon-based rendering
    if (useIcons) {
        return (
            <group>
                {plantData.map(({ pos, color, isHighlighted, shouldDim, stage }, i) => (
                    <PlantIcon
                        key={pos.id || i}
                        stage={stage as PlantStage}
                        color={color}
                        position={[pos.x, pos.y + 0.3, pos.z]}
                        scale={1.2}
                        isHighlighted={isHighlighted || false}
                        isDimmed={shouldDim}
                        onClick={() => onPlantClick(pos)}
                    />
                ))}

                {/* Empty slot markers - small dots */}
                {emptySlots.length > 0 && visMode === 'STANDARD' && !dimMode && !timelineDate && (
                    <Instances range={emptySlots.length}>
                        <circleGeometry args={[0.05, 8]} />
                        <meshBasicMaterial color={COLORS.EMPTY_SLOT} transparent opacity={0.3} />
                        {emptySlots.map((pos, i) => (
                            <Instance
                                key={pos.id || i}
                                position={[pos.x, pos.y + 0.05, pos.z]}
                                rotation={[-Math.PI / 2, 0, 0]}
                            />
                        ))}
                    </Instances>
                )}
            </group>
        );
    }

    // Legacy sphere-based rendering (fallback)
    return (
        <group>
            {plantData.length > 0 && (
                <Instances
                    range={plantData.length}
                    onClick={(e) => {
                        e.stopPropagation();
                        // Need to map instance ID back to filtered plantData index, not original plants array
                        const index = e.instanceId;
                        if (index !== undefined && plantData[index]) {
                            onPlantClick(plantData[index].pos);
                        }
                    }}
                >
                    <sphereGeometry args={[0.2, 12, 8]} />
                    <meshStandardMaterial roughness={0.5} />
                    {plantData.map(({ pos, color, isHighlighted, shouldDim }, i) => (
                        <Instance
                            key={pos.id || i}
                            position={[pos.x, pos.y + 0.25, pos.z]}
                            color={shouldDim ? '#3f3f46' : color}
                            scale={isHighlighted ? 2.0 : (shouldDim ? 1.0 : 1.5)}
                        />
                    ))}
                </Instances>
            )}
        </group>
    );
}

