import { useMemo } from 'react';
import { Billboard } from '@react-three/drei';
import * as THREE from 'three';

// Stage-specific icon shapes as SVG paths (camera-facing 2D)
// These are custom illustrations optimized for clarity at small sizes

export type PlantStage = 'CLONE_IN' | 'VEGETATIVE' | 'FLOWERING' | 'DRYING' | 'CURING' | 'HARVESTED' | 'FINISHED';

interface PlantIconProps {
    stage: PlantStage;
    color: string;
    position: [number, number, number];
    scale?: number;
    isHighlighted?: boolean;
    isDimmed?: boolean;
    onClick?: () => void;
}

// Icon configurations per stage
const STAGE_ICONS: Record<PlantStage, { shape: 'circle' | 'leaf' | 'flower' | 'diamond' | 'square' | 'ring'; sides?: number }> = {
    CLONE_IN: { shape: 'circle' },      // Small seedling dot
    VEGETATIVE: { shape: 'leaf' },       // 3-point leaf shape
    FLOWERING: { shape: 'flower', sides: 5 }, // 5-petal flower
    DRYING: { shape: 'diamond' },        // Hanging diamond
    CURING: { shape: 'square' },         // Jar/container square
    HARVESTED: { shape: 'ring' },        // Empty circle
    FINISHED: { shape: 'ring' },         // Empty circle
};

// Create geometry for each shape type
function createShapeGeometry(shape: string, sides?: number): THREE.BufferGeometry {
    switch (shape) {
        case 'circle':
            return new THREE.CircleGeometry(0.15, 16);

        case 'leaf': {
            // Custom leaf shape - pointed oval
            const leafShape = new THREE.Shape();
            leafShape.moveTo(0, 0.2);
            leafShape.bezierCurveTo(0.12, 0.15, 0.15, 0.05, 0.1, -0.15);
            leafShape.lineTo(0, -0.2);
            leafShape.lineTo(-0.1, -0.15);
            leafShape.bezierCurveTo(-0.15, 0.05, -0.12, 0.15, 0, 0.2);
            return new THREE.ShapeGeometry(leafShape);
        }

        case 'flower': {
            // 5-petal flower shape
            const petalCount = sides || 5;
            const flowerShape = new THREE.Shape();
            const innerRadius = 0.06;
            const outerRadius = 0.18;

            for (let i = 0; i < petalCount; i++) {
                const angle = (i / petalCount) * Math.PI * 2 - Math.PI / 2;
                const nextAngle = ((i + 1) / petalCount) * Math.PI * 2 - Math.PI / 2;
                const midAngle = (angle + nextAngle) / 2;

                const x1 = Math.cos(angle) * innerRadius;
                const y1 = Math.sin(angle) * innerRadius;
                const xMid = Math.cos(midAngle) * outerRadius;
                const yMid = Math.sin(midAngle) * outerRadius;

                if (i === 0) {
                    flowerShape.moveTo(x1, y1);
                }
                flowerShape.quadraticCurveTo(xMid, yMid, Math.cos(nextAngle) * innerRadius, Math.sin(nextAngle) * innerRadius);
            }
            flowerShape.closePath();
            return new THREE.ShapeGeometry(flowerShape);
        }

        case 'diamond': {
            // Diamond/rhombus shape
            const diamondShape = new THREE.Shape();
            diamondShape.moveTo(0, 0.2);
            diamondShape.lineTo(0.12, 0);
            diamondShape.lineTo(0, -0.2);
            diamondShape.lineTo(-0.12, 0);
            diamondShape.closePath();
            return new THREE.ShapeGeometry(diamondShape);
        }

        case 'square':
            return new THREE.PlaneGeometry(0.25, 0.25);

        case 'ring': {
            // Ring/outline circle
            const ringShape = new THREE.Shape();
            ringShape.absarc(0, 0, 0.15, 0, Math.PI * 2, false);
            const hole = new THREE.Path();
            hole.absarc(0, 0, 0.1, 0, Math.PI * 2, true);
            ringShape.holes.push(hole);
            return new THREE.ShapeGeometry(ringShape);
        }

        default:
            return new THREE.CircleGeometry(0.15, 16);
    }
}

// Cache geometries to avoid recreation
const geometryCache = new Map<string, THREE.BufferGeometry>();

function getGeometry(shape: string, sides?: number): THREE.BufferGeometry {
    const key = `${shape}-${sides || 0}`;
    if (!geometryCache.has(key)) {
        geometryCache.set(key, createShapeGeometry(shape, sides));
    }
    return geometryCache.get(key)!;
}

export function PlantIcon({
    stage,
    color,
    position,
    scale = 1,
    isHighlighted = false,
    isDimmed = false,
    onClick
}: PlantIconProps) {
    const iconConfig = STAGE_ICONS[stage] || STAGE_ICONS.VEGETATIVE;
    const geometry = useMemo(() => getGeometry(iconConfig.shape, iconConfig.sides), [iconConfig]);

    // Adjust color for dimming/highlighting
    const finalColor = useMemo(() => {
        if (isDimmed) return '#3f3f46'; // Zinc-700
        return color;
    }, [color, isDimmed]);

    // Scale adjustments
    const finalScale = isHighlighted ? scale * 1.5 : scale;

    return (
        <Billboard position={position} follow={true} lockX={false} lockY={false} lockZ={false}>
            <mesh
                geometry={geometry}
                scale={[finalScale, finalScale, 1]}
                onClick={(e) => {
                    e.stopPropagation();
                    onClick?.();
                }}
            >
                <meshBasicMaterial
                    color={finalColor}
                    side={THREE.DoubleSide}
                    transparent={isDimmed}
                    opacity={isDimmed ? 0.4 : 1}
                />
            </mesh>

            {/* Highlight ring for selected plants */}
            {isHighlighted && (
                <mesh scale={[finalScale * 1.3, finalScale * 1.3, 1]}>
                    <ringGeometry args={[0.18, 0.22, 24]} />
                    <meshBasicMaterial color="#22d3ee" transparent opacity={0.8} />
                </mesh>
            )}
        </Billboard>
    );
}

// Batch renderer for performance with many plants
interface PlantIconBatchProps {
    plants: Array<{
        id: string;
        stage: PlantStage;
        color: string;
        position: [number, number, number];
        isHighlighted?: boolean;
        isDimmed?: boolean;
    }>;
    onPlantClick: (id: string) => void;
}

export function PlantIconBatch({ plants, onPlantClick }: PlantIconBatchProps) {
    // Group by stage for instanced rendering
    const groupedByStage = useMemo(() => {
        const groups: Record<PlantStage, typeof plants> = {
            CLONE_IN: [],
            VEGETATIVE: [],
            FLOWERING: [],
            DRYING: [],
            CURING: [],
            HARVESTED: [],
            FINISHED: [],
        };

        for (const plant of plants) {
            const stage = plant.stage || 'VEGETATIVE';
            if (groups[stage]) {
                groups[stage].push(plant);
            }
        }

        return groups;
    }, [plants]);

    // For now, render individually (can optimize to instanced later if needed)
    return (
        <group>
            {plants.map(plant => (
                <PlantIcon
                    key={plant.id}
                    stage={plant.stage}
                    color={plant.color}
                    position={plant.position}
                    isHighlighted={plant.isHighlighted}
                    isDimmed={plant.isDimmed}
                    onClick={() => onPlantClick(plant.id)}
                />
            ))}
        </group>
    );
}
