/**
 * RackVisualizer - 2D SVG visualization of a rack/section with plant slots
 * Intuitive grid-based layout with drag-drop targets
 */

import { useMemo, useState } from 'react';
import { Table, Server, Box, GripVertical, Square, Settings } from 'lucide-react';
import { cn } from '../../lib/utils';
import type { LayoutPlantType } from '../../lib/layoutApi';

export interface PlantSlotData {
    id: string;
    row: number;
    column: number;
    tier: number;
    status: 'EMPTY' | 'OCCUPIED' | 'RESERVED' | 'DAMAGED';
    plantType?: LayoutPlantType;
    tagNumber?: string;
    plant?: {
        id: string;
        tagNumber?: string;
    };
}

export interface RackData {
    id: string;
    name: string;
    code: string;
    subtype: 'TABLE' | 'RACK' | 'TRAY' | 'HANGER' | 'FLOOR';
    rows: number;
    columns: number;
    tiers: number;
    slots: PlantSlotData[];
}

interface RackVisualizerProps {
    rack: RackData;
    selectedTier?: number;
    onSlotClick?: (slot: PlantSlotData) => void;
    onSlotDrop?: (slot: PlantSlotData, plantType: LayoutPlantType) => void;
    onConfigClick?: (rack: RackData) => void;
    highlightedSlots?: Set<string>;
    className?: string;
}

const SLOT_SIZE = 40; // pixels
const SLOT_GAP = 4;
const TIER_TAB_HEIGHT = 24;

// Subtype visual styles - clean, neutral, no cream/tan colors
const SUBTYPE_STYLES = {
    TABLE: { bg: 'bg-background/50', border: 'border-border/60', Icon: Table },
    RACK: { bg: 'bg-background/50', border: 'border-border/60', Icon: Server },
    TRAY: { bg: 'bg-background/30', border: 'border-border/40', Icon: Box },
    HANGER: { bg: 'bg-background/30', border: 'border-border/40', Icon: GripVertical },
    FLOOR: { bg: 'bg-background/20', border: 'border-border/30', Icon: Square },
};

export function RackVisualizer({
    rack,
    selectedTier = 1,
    onSlotClick,
    onSlotDrop,
    onConfigClick,
    highlightedSlots,
    className
}: RackVisualizerProps) {
    const style = SUBTYPE_STYLES[rack.subtype] || SUBTYPE_STYLES.RACK;

    // Filter slots for selected tier
    const tierSlots = useMemo(() => {
        return rack.slots.filter(s => s.tier === selectedTier);
    }, [rack.slots, selectedTier]);

    // Create grid lookup
    const slotGrid = useMemo(() => {
        const grid = new Map<string, PlantSlotData>();
        for (const slot of tierSlots) {
            grid.set(`${slot.row}-${slot.column}`, slot);
        }
        return grid;
    }, [tierSlots]);

    const gridWidth = rack.columns * (SLOT_SIZE + SLOT_GAP) + SLOT_GAP;
    const gridHeight = rack.rows * (SLOT_SIZE + SLOT_GAP) + SLOT_GAP;

    const handleDrop = (slot: PlantSlotData, e: React.DragEvent) => {
        e.preventDefault();
        const data = e.dataTransfer.getData('application/json');
        if (data && onSlotDrop) {
            try {
                const plantType = JSON.parse(data) as LayoutPlantType;
                onSlotDrop(slot, plantType);
            } catch {
                // Invalid data
            }
        }
    };

    return (
        <div className={cn('inline-block group', className)}>
            {/* Rack header */}
            <div className={cn('flex items-center gap-2 px-3 py-2 rounded-t-xl border-b-0', style.bg, style.border, 'border')}>
                <style.Icon className="w-4 h-4 text-muted-foreground" />
                <span className="text-sm font-medium text-foreground">{rack.name}</span>
                <span className="text-xs text-muted-foreground font-mono">({rack.code})</span>
                <div className="ml-auto flex items-center gap-2">
                    {rack.tiers > 1 && (
                        <span className="text-xs text-muted-foreground font-mono">T{selectedTier}/{rack.tiers}</span>
                    )}
                    {onConfigClick && (
                        <button
                            onClick={() => onConfigClick(rack)}
                            className="opacity-0 group-hover:opacity-100 p-1 text-muted-foreground hover:text-foreground hover:bg-secondary rounded transition-all"
                            title="Configure section"
                        >
                            <Settings className="w-3.5 h-3.5" />
                        </button>
                    )}
                </div>
            </div>

            {/* Tier tabs (if multi-tier) */}
            {rack.tiers > 1 && (
                <div className="flex border-l border-r border-border" style={{ borderColor: style.border.replace('border-', '') }}>
                    {Array.from({ length: rack.tiers }, (_, i) => i + 1).map(tier => (
                        <button
                            key={tier}
                            className={cn(
                                'flex-1 text-[10px] py-1 transition-colors font-mono',
                                tier === selectedTier
                                    ? 'bg-primary/20 text-primary font-bold'
                                    : 'bg-secondary/50 text-muted-foreground hover:bg-secondary'
                            )}
                        >
                            T{tier}
                        </button>
                    ))}
                </div>
            )}

            {/* Grid */}
            <div
                className={cn('p-2 rounded-b-xl border', style.bg, style.border)}
                style={{ width: gridWidth + 16, minHeight: gridHeight + 16 }}
            >
                <div
                    className="relative"
                    style={{
                        display: 'grid',
                        gridTemplateColumns: `repeat(${rack.columns}, ${SLOT_SIZE}px)`,
                        gridTemplateRows: `repeat(${rack.rows}, ${SLOT_SIZE}px)`,
                        gap: SLOT_GAP,
                    }}
                >
                    {Array.from({ length: rack.rows }, (_, rowIdx) =>
                        Array.from({ length: rack.columns }, (_, colIdx) => {
                            const row = rowIdx + 1;
                            const col = colIdx + 1;
                            const slot = slotGrid.get(`${row}-${col}`);
                            const isHighlighted = highlightedSlots?.has(slot?.id || '');

                            return (
                                <PlantSlot
                                    key={`${row}-${col}`}
                                    slot={slot || { id: `empty-${row}-${col}`, row, column: col, tier: selectedTier, status: 'EMPTY' }}
                                    isHighlighted={isHighlighted}
                                    onClick={onSlotClick}
                                    onDrop={(s, e) => handleDrop(s, e)}
                                />
                            );
                        })
                    )}
                </div>
            </div>
        </div>
    );
}

interface PlantSlotProps {
    slot: PlantSlotData;
    isHighlighted?: boolean;
    onClick?: (slot: PlantSlotData) => void;
    onDrop: (slot: PlantSlotData, e: React.DragEvent) => void;
}

function PlantSlot({ slot, isHighlighted, onClick, onDrop }: PlantSlotProps) {
    const [isDragOver, setIsDragOver] = useState(false);
    const isOccupied = slot.status === 'OCCUPIED' && slot.plantType;
    const isDamaged = slot.status === 'DAMAGED';
    const isReserved = slot.status === 'RESERVED';
    const canDrop = slot.status === 'EMPTY';

    const handleDragOver = (e: React.DragEvent) => {
        if (canDrop) {
            e.preventDefault();
            e.dataTransfer.dropEffect = 'copy';
        }
    };

    const handleDragEnter = (e: React.DragEvent) => {
        e.preventDefault();
        if (canDrop) setIsDragOver(true);
    };

    const handleDragLeave = () => {
        setIsDragOver(false);
    };

    const handleDrop = (e: React.DragEvent) => {
        setIsDragOver(false);
        onDrop(slot, e);
    };

    return (
        <div
            onClick={() => onClick?.(slot)}
            onDragOver={handleDragOver}
            onDragEnter={handleDragEnter}
            onDragLeave={handleDragLeave}
            onDrop={handleDrop}
            className={cn(
                'rounded flex items-center justify-center cursor-pointer transition-all duration-150',
                'border',
                // Empty slot styles
                slot.status === 'EMPTY' && !isDragOver && 'border-dashed border-border/50 bg-card/20 hover:border-border hover:bg-card/40',
                // Drag over state - highlight
                isDragOver && 'border-solid border-primary bg-primary/20 scale-105 shadow-[0_0_10px_rgba(37,99,235,0.3)]',
                // Occupied
                isOccupied && 'border-solid border-transparent shadow-sm',
                // Damaged
                isDamaged && 'border-destructive bg-destructive/10',
                // Reserved
                isReserved && 'border-warning bg-warning/10 border-solid',
                // Highlighted (searched)
                isHighlighted && 'ring-2 ring-primary ring-offset-1 ring-offset-background'
            )}
            style={{
                width: SLOT_SIZE,
                height: SLOT_SIZE,
                backgroundColor: isOccupied ? slot.plantType?.colour : undefined,
            }}
            title={isOccupied ? `${slot.plantType?.name} (${slot.tagNumber || 'No tag'})` : `Empty - R${slot.row}C${slot.column}`}
        >
            {isOccupied && (
                <span className="text-white text-xs font-bold font-mono drop-shadow-md tracking-tighter">
                    {slot.plantType?.strain?.substring(0, 3) || '•'}
                </span>
            )}
            {isDamaged && <span className="text-destructive">✕</span>}
            {isReserved && <span className="text-warning text-xs">◆</span>}
            {isDragOver && !isOccupied && (
                <span className="text-primary text-lg animate-pulse">+</span>
            )}
        </div>
    );
}

export default RackVisualizer;
