import React, { useState, useRef, Suspense } from 'react'
import { Canvas, useFrame, useThree } from '@react-three/fiber'
import { OrbitControls, Text, Box, Plane, Line, PerspectiveCamera, Sphere, Billboard, RoundedBox } from '@react-three/drei'
import * as THREE from 'three'

// Types
interface RoomData {
  id: string
  name: string
  position: [number, number, number]
  size: [number, number, number]
  type: 'office' | 'meeting' | 'server' | 'kitchen' | 'restroom' | 'stairs' | 'elevator'
  occupants?: string[]
}

interface FloorData {
  level: number
  name: string
  rooms: RoomData[]
  height: number
}

// Dummy employee mapping
const employeeNames: Record<string, string> = {
  'emp-001': 'Max Mustermann',
  'emp-002': 'Maria Schmidt', 
  'emp-003': 'Thomas Weber',
  'emp-004': 'Sarah Fischer',
  'emp-005': 'Michael Bauer',
  'emp-006': 'Julia Wagner',
  'emp-007': 'Andreas Becker',
  'emp-008': 'Lisa Hoffmann',
}

// Room type colors
const roomColors = {
  office: '#3B82F6',
  meeting: '#10B981',
  server: '#6B7280',
  kitchen: '#F59E0B',
  restroom: '#9CA3AF',
  stairs: '#8B5CF6',
  elevator: '#EC4899',
}

// Building data with 5 floors
const buildingData: FloorData[] = [
  {
    level: 0,
    name: 'Erdgeschoss',
    height: 0,
    rooms: [
      { id: 'EG-001', name: 'Empfang', position: [-3, 0.5, 2], size: [2, 1, 2], type: 'office' },
      { id: 'EG-002', name: 'Kantine', position: [0, 0.5, 2], size: [3, 1, 2], type: 'kitchen' },
      { id: 'EG-003', name: 'Meeting 1', position: [3, 0.5, 2], size: [2, 1, 2], type: 'meeting' },
      { id: 'EG-S1', name: 'Treppe', position: [-4.5, 0.5, -2], size: [1, 1, 1], type: 'stairs' },
      { id: 'EG-E1', name: 'Aufzug', position: [4.5, 0.5, -2], size: [1, 1, 1], type: 'elevator' },
    ]
  },
  {
    level: 1,
    name: '1. OG - Verwaltung',
    height: 3,
    rooms: [
      { id: '1-101', name: 'Büro 101', position: [-3, 3.5, 2], size: [2, 1, 2], type: 'office', occupants: ['emp-001'] },
      { id: '1-102', name: 'Büro 102', position: [0, 3.5, 2], size: [2, 1, 2], type: 'office', occupants: ['emp-002'] },
      { id: '1-103', name: 'Büro 103', position: [3, 3.5, 2], size: [2, 1, 2], type: 'office', occupants: ['emp-003'] },
      { id: '1-Server', name: 'Server', position: [0, 3.5, -2], size: [2, 1, 1.5], type: 'server' },
      { id: '1-S1', name: 'Treppe', position: [-4.5, 3.5, -2], size: [1, 1, 1], type: 'stairs' },
      { id: '1-E1', name: 'Aufzug', position: [4.5, 3.5, -2], size: [1, 1, 1], type: 'elevator' },
    ]
  },
  {
    level: 2,
    name: '2. OG - Kriminalpolizei',
    height: 6,
    rooms: [
      { id: '2-201', name: 'Büro 201', position: [-3, 6.5, 2], size: [2, 1, 2], type: 'office', occupants: ['emp-004'] },
      { id: '2-202', name: 'Großraum', position: [0, 6.5, 2], size: [4, 1, 2], type: 'office', occupants: ['emp-005', 'emp-006'] },
      { id: '2-203', name: 'Einsatzzentrale', position: [0, 6.5, -2], size: [3, 1, 1.5], type: 'meeting' },
      { id: '2-S1', name: 'Treppe', position: [-4.5, 6.5, -2], size: [1, 1, 1], type: 'stairs' },
      { id: '2-E1', name: 'Aufzug', position: [4.5, 6.5, -2], size: [1, 1, 1], type: 'elevator' },
    ]
  },
  {
    level: 3,
    name: '3. OG - Staatsschutz',
    height: 9,
    rooms: [
      { id: '3-301', name: 'Büro 301', position: [-3, 9.5, 2], size: [2, 1, 2], type: 'office' },
      { id: '3-302', name: 'Büro 302', position: [0, 9.5, 2], size: [2, 1, 2], type: 'office' },
      { id: '3-303', name: 'Abhörsicher', position: [3, 9.5, 2], size: [2, 1, 2], type: 'meeting' },
      { id: '3-Server', name: 'Server', position: [0, 9.5, -2], size: [2, 1, 1.5], type: 'server' },
      { id: '3-S1', name: 'Treppe', position: [-4.5, 9.5, -2], size: [1, 1, 1], type: 'stairs' },
      { id: '3-E1', name: 'Aufzug', position: [4.5, 9.5, -2], size: [1, 1, 1], type: 'elevator' },
    ]
  },
  {
    level: 4,
    name: '4. OG - Cybercrime & IT',
    height: 12,
    rooms: [
      { id: '4-401', name: 'Cybercrime Team', position: [-2, 12.5, 2], size: [4, 1, 2], type: 'office', occupants: ['emp-007', 'emp-008'] },
      { id: '4-402', name: 'IT-Forensik', position: [3, 12.5, 2], size: [2, 1, 2], type: 'office' },
      { id: '4-Server', name: 'Hauptserver', position: [0, 12.5, -2], size: [3, 1, 1.5], type: 'server' },
      { id: '4-S1', name: 'Treppe', position: [-4.5, 12.5, -2], size: [1, 1, 1], type: 'stairs' },
      { id: '4-E1', name: 'Aufzug', position: [4.5, 12.5, -2], size: [1, 1, 1], type: 'elevator' },
    ]
  },
]

// Room Component
function Room({ room, isSelected, isStart, isEnd, onSelect }: { 
  room: RoomData
  isSelected: boolean
  isStart?: boolean
  isEnd?: boolean
  onSelect: () => void
}) {
  const meshRef = useRef<THREE.Mesh>(null)
  const [hovered, setHovered] = useState(false)
  
  useFrame((state) => {
    if (meshRef.current) {
      // Gentle floating animation for selected room
      if (isSelected) {
        meshRef.current.position.y = room.position[1] + Math.sin(state.clock.elapsedTime * 2) * 0.05
      }
    }
  })

  const color = isStart ? '#10B981' : isEnd ? '#EF4444' : isSelected ? '#FCD34D' : (hovered ? '#FCA5A5' : roomColors[room.type])
  
  return (
    <group>
      <Box
        ref={meshRef}
        args={room.size}
        position={room.position}
        onClick={onSelect}
        onPointerOver={() => setHovered(true)}
        onPointerOut={() => setHovered(false)}
      >
        <meshStandardMaterial 
          color={color} 
          transparent 
          opacity={isStart || isEnd ? 0.9 : 0.7}
          emissive={isStart ? '#10B981' : isEnd ? '#EF4444' : isSelected ? '#FCD34D' : '#000000'}
          emissiveIntensity={isStart || isEnd ? 0.3 : isSelected ? 0.2 : 0}
        />
      </Box>
      
      {/* Room label with billboard and background */}
      <Billboard
        follow={true}
        lockX={false}
        lockY={false}
        lockZ={false}
        position={[room.position[0], room.position[1] + room.size[1]/2 + 0.2, room.position[2]]}
      >
        <RoundedBox args={[room.name.length * 0.08, 0.25, 0.01]} radius={0.02}>
          <meshBasicMaterial color="#1F2937" opacity={0.9} transparent />
        </RoundedBox>
        <Text
          fontSize={0.15}
          color="white"
          anchorX="center"
          anchorY="middle"
          position={[0, 0, 0.01]}
        >
          {room.name}
        </Text>
      </Billboard>
      
      {/* Occupant count with billboard and background */}
      {room.occupants && room.occupants.length > 0 && !isStart && !isEnd && (
        <Billboard
          follow={true}
          lockX={false}
          lockY={false}
          lockZ={false}
          position={[room.position[0], room.position[1] - room.size[1]/2 - 0.2, room.position[2]]}
        >
          <RoundedBox args={[1.0, 0.2, 0.01]} radius={0.02}>
            <meshBasicMaterial color="#1F2937" opacity={0.8} transparent />
          </RoundedBox>
          <Text
            fontSize={0.12}
            color="#FFD700"
            anchorX="center"
            anchorY="middle"
            position={[0, 0, 0.01]}
          >
            {room.occupants.length} Person(en)
          </Text>
        </Billboard>
      )}
      
      {/* Start/End markers with billboard and background */}
      {isStart && (
        <Billboard
          follow={true}
          lockX={false}
          lockY={false}
          lockZ={false}
          position={[room.position[0], room.position[1] + room.size[1]/2 + 0.5, room.position[2]]}
        >
          <RoundedBox args={[0.8, 0.35, 0.01]} radius={0.05}>
            <meshBasicMaterial color="#10B981" opacity={0.9} transparent />
          </RoundedBox>
          <Text
            fontSize={0.25}
            color="white"
            anchorX="center"
            anchorY="middle"
            position={[0, 0, 0.01]}
            outlineWidth={0.02}
            outlineColor="#065F46"
          >
            START
          </Text>
        </Billboard>
      )}
      {isEnd && (
        <Billboard
          follow={true}
          lockX={false}
          lockY={false}
          lockZ={false}
          position={[room.position[0], room.position[1] + room.size[1]/2 + 0.5, room.position[2]]}
        >
          <RoundedBox args={[0.6, 0.35, 0.01]} radius={0.05}>
            <meshBasicMaterial color="#EF4444" opacity={0.9} transparent />
          </RoundedBox>
          <Text
            fontSize={0.25}
            color="white"
            anchorX="center"
            anchorY="middle"
            position={[0, 0, 0.01]}
            outlineWidth={0.02}
            outlineColor="#7F1D1D"
          >
            ZIEL
          </Text>
        </Billboard>
      )}
    </group>
  )
}

// Floor Component
function Floor({ floor, visible, opacity, selectedRoom, startRoom, endRoom, onSelectRoom }: {
  floor: FloorData
  visible: boolean
  opacity: number
  selectedRoom: string | null
  startRoom: string | null
  endRoom: string | null
  onSelectRoom: (roomId: string) => void
}) {
  if (!visible) return null
  
  return (
    <group>
      {/* Floor plate */}
      <Plane 
        args={[12, 8]} 
        rotation={[-Math.PI / 2, 0, 0]} 
        position={[0, floor.height, 0]}
      >
        <meshStandardMaterial 
          color="#E5E7EB" 
          transparent 
          opacity={opacity * 0.3}
          side={THREE.DoubleSide}
        />
      </Plane>
      
      {/* Floor label with billboard and background */}
      <Billboard
        follow={true}
        lockX={false}
        lockY={false}
        lockZ={false}
        position={[-7, floor.height + 0.5, 5]}
      >
        <RoundedBox args={[floor.name.length * 0.11, 0.4, 0.02]} radius={0.05}>
          <meshBasicMaterial color="#111827" opacity={0.95} transparent />
        </RoundedBox>
        <Text
          fontSize={0.25}
          color="white"
          anchorX="center"
          anchorY="middle"
          position={[0, 0, 0.02]}
          outlineWidth={0.015}
          outlineColor="#000000"
        >
          {floor.name}
        </Text>
      </Billboard>
      
      {/* Rooms */}
      {floor.rooms.map(room => (
        <Room
          key={room.id}
          room={room}
          isSelected={selectedRoom === room.id}
          isStart={startRoom === room.id}
          isEnd={endRoom === room.id}
          onSelect={() => onSelectRoom(room.id)}
        />
      ))}
    </group>
  )
}

// Camera Controller Component - removed to allow free orbit controls

// Main 3D Office Map Component
interface OfficeMap3DProps {
  targetEmployeeId?: string
  targetRoom?: string
  currentUserRoom?: string // Room of logged-in user
  onClose?: () => void
}

export default function OfficeMap3D({ targetEmployeeId, targetRoom, currentUserRoom, onClose }: OfficeMap3DProps) {
  const [selectedFloor, setSelectedFloor] = useState(0)
  const [selectedRoom, setSelectedRoom] = useState<string | null>(null)
  const [viewMode, setViewMode] = useState<'all' | 'single'>('all')
  const [startRoom, setStartRoom] = useState<string | null>(currentUserRoom || null)
  const [endRoom, setEndRoom] = useState<string | null>(null)
  
  // Find target room/floor
  React.useEffect(() => {
    if (targetEmployeeId || targetRoom) {
      for (const floor of buildingData) {
        for (const room of floor.rooms) {
          if (targetRoom === room.id || room.occupants?.includes(targetEmployeeId || '')) {
            setEndRoom(room.id)
            setSelectedFloor(floor.level)
            setSelectedRoom(room.id)
            setViewMode('single')
            break
          }
        }
      }
    }
  }, [targetEmployeeId, targetRoom])

  const handleSelectFloor = (level: number) => {
    setSelectedFloor(level)
    setViewMode('single')
  }

  const getRoomDetails = () => {
    if (!selectedRoom) return null
    for (const floor of buildingData) {
      const room = floor.rooms.find(r => r.id === selectedRoom)
      if (room) {
        return {
          ...room,
          floorName: floor.name,
          occupantNames: room.occupants?.map(id => employeeNames[id] || id)
        }
      }
    }
    return null
  }

  const roomDetails = getRoomDetails()

  return (
    <div className="bg-gray-900 rounded-lg flex flex-col" style={{ height: '700px' }}>
      {/* Top bar with horizontal floor controls */}
      <div className="p-4 pb-2">
        <div className="flex justify-between items-center">
          <div className="flex gap-2">
            {/* Floor buttons - horizontal */}
            <button
              onClick={() => setViewMode('all')}
              className={`px-3 py-1 rounded ${viewMode === 'all' ? 'bg-blue-600 text-white' : 'bg-gray-700 text-gray-300'}`}
            >
              Alle Etagen
            </button>
            {buildingData.map(floor => (
              <button
                key={floor.level}
                onClick={() => handleSelectFloor(floor.level)}
                className={`px-3 py-1 rounded ${
                  viewMode === 'single' && selectedFloor === floor.level
                    ? 'bg-blue-600 text-white'
                    : 'bg-gray-700 text-gray-300'
                }`}
              >
                {floor.level === 0 ? 'EG' : `${floor.level}. OG`}
              </button>
            ))}
          </div>
          
          <div className="text-white text-sm">
            Maus zum Drehen/Zoomen | Klick für Details
          </div>
        </div>
      </div>
      
      {/* Main content - room details left, 3D canvas right */}
      <div className="flex-1 flex gap-4 px-4 pb-4" style={{ minHeight: 0 }}>
        {/* Left side - Room details */}
        <div className="flex-shrink-0" style={{ width: '250px' }}>
          {roomDetails ? (
            <div className="p-3 bg-gray-800 rounded text-white h-full">
              <div className="flex justify-between items-start mb-2">
                <h4 className="font-semibold">{roomDetails.name}</h4>
                <span className={`px-2 py-1 rounded text-xs bg-opacity-20 ${
                  roomDetails.type === 'office' ? 'bg-blue-500 text-blue-300' :
                  roomDetails.type === 'meeting' ? 'bg-green-500 text-green-300' :
                  roomDetails.type === 'server' ? 'bg-gray-500 text-gray-300' :
                  'bg-yellow-500 text-yellow-300'
                }`}>
                  {roomDetails.type}
                </span>
              </div>
              <p className="text-sm text-gray-400">{roomDetails.floorName}</p>
              {roomDetails.occupantNames && roomDetails.occupantNames.length > 0 && (
                <div className="mt-2">
                  <p className="text-sm text-gray-400">Mitarbeitende:</p>
                  {roomDetails.occupantNames.map((name, i) => (
                    <p key={i} className="text-sm">• {name}</p>
                  ))}
                </div>
              )}
            </div>
          ) : (
            <div className="p-3 bg-gray-800 rounded text-gray-400 text-sm h-full">
              Klicken Sie auf einen Raum für Details
            </div>
          )}
        </div>
        
        {/* Right side - 3D Canvas */}
        <div className="flex-1 bg-gray-800 rounded overflow-hidden">
          <Canvas shadows camera={{ position: [20, 20, 20], fov: 50 }}>
            <Suspense fallback={null}>
              
              {/* Lighting */}
              <ambientLight intensity={0.5} />
              <pointLight position={[10, 20, 10]} intensity={1} castShadow />
              <directionalLight position={[0, 10, 5]} intensity={0.5} castShadow />
              
              {/* Grid */}
              <gridHelper args={[20, 20]} position={[0, 0, 0]} />
              
              {/* Building floors */}
              {buildingData.map(floor => (
                <Floor
                  key={floor.level}
                  floor={floor}
                  visible={viewMode === 'all' || floor.level === selectedFloor}
                  opacity={viewMode === 'all' ? (floor.level === selectedFloor ? 1 : 0.3) : 1}
                  selectedRoom={selectedRoom}
                  startRoom={startRoom}
                  endRoom={endRoom}
                  onSelectRoom={setSelectedRoom}
                />
              ))}
              
              {/* Connecting elements (stairs/elevator shafts) */}
              {viewMode === 'all' && (
                <group>
                  {/* Elevator shaft */}
                  <Line
                    points={[[4.5, 0, -2], [4.5, 13, -2]]}
                    color="#EC4899"
                    lineWidth={3}
                  />
                  {/* Stair shaft */}
                  <Line
                    points={[[-4.5, 0, -2], [-4.5, 13, -2]]}
                    color="#8B5CF6"
                    lineWidth={3}
                  />
                </group>
              )}
              
              {/* Path visualization between start and end */}
              {startRoom && endRoom && (() => {
                let startPos: [number, number, number] | null = null
                let endPos: [number, number, number] | null = null
                let startFloor = -1
                let endFloor = -1
                
                // Find positions
                for (const floor of buildingData) {
                  for (const room of floor.rooms) {
                    if (room.id === startRoom) {
                      startPos = room.position
                      startFloor = floor.level
                    }
                    if (room.id === endRoom) {
                      endPos = room.position
                      endFloor = floor.level
                    }
                  }
                }
                
                if (startPos && endPos) {
                  const points: [number, number, number][] = []
                  
                  if (startFloor === endFloor) {
                    // Same floor - direct path
                    points.push(startPos)
                    points.push(endPos)
                  } else {
                    // Different floors - path through elevator
                    points.push(startPos)
                    // Go to elevator on start floor
                    points.push([4.5, startPos[1], -2])
                    // Move to destination floor
                    points.push([4.5, endPos[1], -2])
                    // Go to destination
                    points.push(endPos)
                  }
                  
                  return (
                    <group>
                      <Line
                        points={points}
                        color="#FCD34D"
                        lineWidth={4}
                        dashed
                        dashScale={5}
                        dashSize={0.5}
                        gapSize={0.5}
                      />
                      {/* Animated sphere along path */}
                      <Sphere args={[0.2]} position={startPos}>
                        <meshBasicMaterial color="#FCD34D" />
                      </Sphere>
                    </group>
                  )
                }
                return null
              })()}
              
              <OrbitControls 
                enablePan={true}
                enableZoom={true}
                enableRotate={true}
                minDistance={3}
                maxDistance={50}
                maxPolarAngle={Math.PI / 2.5}
                zoomToCursor={true}
                panSpeed={0.8}
                rotateSpeed={0.8}
              />
            </Suspense>
          </Canvas>
        </div>
      </div>
    </div>
  )
}
