import { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { Polyline, Marker, Popup, Circle, useMapEvents } from 'react-leaflet';
import L from 'leaflet';
import { mapItemService } from '../../services/mapItemService';
import { CABLE_COLORS, type MapItem, type CableType } from '../../types/mapItem';
import { ItemContextMenu } from './ItemContextMenu';
import { useDrawingStore } from '../../stores/drawingStore';

interface MapItemsLayerProps {
  mapId: string;
  refreshTrigger: number;
  readOnly?: boolean;
}

// Custom marker icons for devices using CSS
const switchIcon = new L.DivIcon({
  html: `<div class="device-icon switch-icon">
    <svg viewBox="0 0 24 24" fill="currentColor">
      <rect x="2" y="4" width="20" height="16" rx="2" fill="none" stroke="currentColor" stroke-width="2"/>
      <circle cx="6" cy="10" r="1.5"/>
      <circle cx="10" cy="10" r="1.5"/>
      <circle cx="14" cy="10" r="1.5"/>
      <circle cx="18" cy="10" r="1.5"/>
      <circle cx="6" cy="14" r="1.5"/>
      <circle cx="10" cy="14" r="1.5"/>
      <circle cx="14" cy="14" r="1.5"/>
      <circle cx="18" cy="14" r="1.5"/>
    </svg>
  </div>`,
  className: 'custom-device-marker',
  iconSize: [40, 40],
  iconAnchor: [20, 40],
});

const indoorApIcon = new L.DivIcon({
  html: `<div class="device-icon ap-indoor-icon">
    <svg viewBox="0 0 24 24" fill="currentColor">
      <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" opacity="0.3"/>
      <circle cx="12" cy="12" r="3"/>
      <path d="M12 6c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm0 10c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"/>
    </svg>
  </div>`,
  className: 'custom-device-marker',
  iconSize: [40, 40],
  iconAnchor: [20, 40],
});

const outdoorApIcon = new L.DivIcon({
  html: `<div class="device-icon ap-outdoor-icon">
    <svg viewBox="0 0 24 24" fill="currentColor">
      <path d="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.08 2.93 1 9z"/>
      <path d="M9 17l3 3 3-3c-1.65-1.66-4.34-1.66-6 0z"/>
      <path d="M5 13l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z"/>
    </svg>
  </div>`,
  className: 'custom-device-marker',
  iconSize: [40, 40],
  iconAnchor: [20, 40],
});

export function MapItemsLayer({ mapId, refreshTrigger, readOnly = false }: MapItemsLayerProps) {
  const [items, setItems] = useState<MapItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [contextMenu, setContextMenu] = useState<{
    item: MapItem;
    position: { x: number; y: number };
  } | null>(null);
  const { activeTool } = useDrawingStore();

  // Check if we're in drawing mode (should suppress popups)
  const isCableTool = ['fiber', 'cat6', 'cat6_poe'].includes(activeTool);
  const isWirelessTool = activeTool === 'wireless_mesh';
  const shouldSuppressPopups = isCableTool || isWirelessTool;

  useEffect(() => {
    loadItems();
  }, [mapId, refreshTrigger]);

  const loadItems = async () => {
    try {
      setLoading(true);
      const data = await mapItemService.getMapItems(mapId);
      console.log('Loaded items:', data);
      // Log devices with their connections
      data.forEach(item => {
        if (['switch', 'indoor_ap', 'outdoor_ap'].includes(item.type)) {
          console.log(`Device ${item.type} (${item.id}): ${item.properties.connections?.length || 0} / ${item.properties.port_count} ports`);
        }
      });
      setItems(data);
    } catch (error) {
      console.error('Failed to load map items:', error);
    } finally {
      setLoading(false);
    }
  };

  // Close context menu on any map click
  useMapEvents({
    click: () => setContextMenu(null),
    contextmenu: () => {}, // Prevent default map context menu
  });

  const getDeviceIcon = (type: string) => {
    switch (type) {
      case 'switch':
        return switchIcon;
      case 'indoor_ap':
        return indoorApIcon;
      case 'outdoor_ap':
        return outdoorApIcon;
      default:
        return undefined;
    }
  };

  if (loading) return null;

  return (
    <>
      {items.map((item) => {
        // Render cables
        if (item.type === 'cable' && item.geometry.type === 'LineString') {
          const positions = item.geometry.coordinates.map(
            ([lng, lat]) => [lat, lng] as [number, number]
          );
          const cableType = item.properties.cable_type as CableType;
          const color = CABLE_COLORS[cableType] || '#6B7280';

          // Find connected devices
          const startDevice = item.properties.start_device_id
            ? items.find(i => i.id === item.properties.start_device_id)
            : null;
          const endDevice = item.properties.end_device_id
            ? items.find(i => i.id === item.properties.end_device_id)
            : null;

          return (
            <div key={item.id}>
              <Polyline
                positions={positions}
                color={color}
                weight={3}
                opacity={0.8}
                eventHandlers={{
                  contextmenu: (e) => {
                    L.DomEvent.stopPropagation(e);
                    if (!readOnly) {
                      setContextMenu({
                        item,
                        position: { x: e.originalEvent.clientX, y: e.originalEvent.clientY }
                      });
                    }
                  },
                }}
              >
                {!shouldSuppressPopups && (
                  <Popup>
                    <div className="text-sm dark:bg-gray-800 dark:text-white" style={{ minWidth: '200px' }}>
                      <div className="font-semibold text-gray-900 dark:text-white">{item.properties.name || 'Cable'}</div>
                      <div className="text-gray-600 dark:text-gray-400">Type: {cableType}</div>
                      {startDevice && (
                        <div className="text-gray-600 dark:text-gray-400 mt-1">
                          From: {startDevice.properties.name || startDevice.type}
                        </div>
                      )}
                      {endDevice && (
                        <div className="text-gray-600 dark:text-gray-400">
                          To: {endDevice.properties.name || endDevice.type}
                        </div>
                      )}
                      {item.properties.notes && (
                        <div className="text-gray-600 dark:text-gray-400 mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
                          {item.properties.notes}
                        </div>
                      )}
                      {item.properties.image && (
                        <div className="mt-2">
                          <img
                            src={item.properties.image}
                            alt="Attachment"
                            className="w-full rounded border border-gray-200 dark:border-gray-700"
                            style={{ maxHeight: '150px', objectFit: 'contain' }}
                          />
                        </div>
                      )}
                    </div>
                  </Popup>
                )}
              </Polyline>

              {/* Show circles at cable bend points (not first/last) */}
              {positions.slice(1, -1).map((pos, idx) => (
                <Circle
                  key={`${item.id}-bend-${idx}`}
                  center={pos}
                  radius={1}
                  pathOptions={{
                    color: color,
                    fillColor: color,
                    fillOpacity: 0.3,
                    weight: 2,
                  }}
                />
              ))}
            </div>
          );
        }

        // Render wireless mesh
        if (item.type === 'wireless_mesh' && item.geometry.type === 'LineString') {
          const positions = item.geometry.coordinates.map(
            ([lng, lat]) => [lat, lng] as [number, number]
          );

          // Find connected APs
          const startAp = item.properties.start_ap_id
            ? items.find(i => i.id === item.properties.start_ap_id)
            : null;
          const endAp = item.properties.end_ap_id
            ? items.find(i => i.id === item.properties.end_ap_id)
            : null;

          return (
            <Polyline
              key={item.id}
              positions={positions}
              color="#10B981"
              weight={3}
              opacity={0.8}
              dashArray="10, 10"
              eventHandlers={{
                contextmenu: (e) => {
                  L.DomEvent.stopPropagation(e);
                  if (!readOnly) {
                    setContextMenu({
                      item,
                      position: { x: e.originalEvent.clientX, y: e.originalEvent.clientY }
                    });
                  }
                },
              }}
            >
              {!shouldSuppressPopups && (
                <Popup>
                  <div className="text-sm dark:bg-gray-800 dark:text-white" style={{ minWidth: '200px' }}>
                    <div className="font-semibold text-gray-900 dark:text-white">{item.properties.name || 'Wireless Mesh'}</div>
                    {startAp && (
                      <div className="text-gray-600 dark:text-gray-400 mt-1">
                        From: {startAp.properties.name || startAp.type}
                      </div>
                    )}
                    {endAp && (
                      <div className="text-gray-600 dark:text-gray-400">
                        To: {endAp.properties.name || endAp.type}
                      </div>
                    )}
                    {item.properties.notes && (
                      <div className="text-gray-600 dark:text-gray-400 mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
                        {item.properties.notes}
                      </div>
                    )}
                    {item.properties.image && (
                      <div className="mt-2">
                        <img
                          src={item.properties.image}
                          alt="Attachment"
                          className="w-full rounded border border-gray-200 dark:border-gray-700"
                          style={{ maxHeight: '150px', objectFit: 'contain' }}
                        />
                      </div>
                    )}
                  </div>
                </Popup>
              )}
            </Polyline>
          );
        }

        // Render devices
        if (
          ['switch', 'indoor_ap', 'outdoor_ap'].includes(item.type) &&
          item.geometry.type === 'Point'
        ) {
          const [lng, lat] = item.geometry.coordinates;
          const position: [number, number] = [lat, lng];
          const icon = getDeviceIcon(item.type);

          return (
            <Marker
              key={item.id}
              position={position}
              icon={icon}
              eventHandlers={{
                contextmenu: (e) => {
                  L.DomEvent.stopPropagation(e);
                  if (!readOnly) {
                    setContextMenu({
                      item,
                      position: { x: e.originalEvent.clientX, y: e.originalEvent.clientY }
                    });
                  }
                },
              }}
            >
              {!shouldSuppressPopups && (
                <Popup>
                  <div className="text-sm dark:bg-gray-800 dark:text-white" style={{ minWidth: '200px' }}>
                    <div className="font-semibold text-gray-900 dark:text-white">{item.properties.name || item.type}</div>
                    <div className="text-gray-600 dark:text-gray-400">Type: {item.type}</div>
                    {item.properties.port_count && (
                      <div className="text-gray-600 dark:text-gray-400">
                        Ports: {item.properties.connections?.length || 0} / {item.properties.port_count}
                      </div>
                    )}

                    {/* Show port connections details */}
                    {item.properties.connections && item.properties.connections.length > 0 && (
                      <div className="mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
                        <div className="font-semibold text-gray-700 dark:text-gray-300 mb-1">Port Connections:</div>
                        {item.properties.connections
                          .sort((a: any, b: any) => a.port_number - b.port_number)
                          .map((conn: any) => {
                            const cable = items.find(i => i.id === conn.cable_id);
                            if (!cable) return null;

                            // Find the other device connected to this cable
                            const otherDeviceId = cable.properties.start_device_id === item.id
                              ? cable.properties.end_device_id
                              : cable.properties.start_device_id;

                            const otherDevice = otherDeviceId
                              ? items.find(i => i.id === otherDeviceId)
                              : null;

                            const cableType = cable.properties.cable_type;

                            return (
                              <div key={conn.cable_id} className="text-xs text-gray-600 dark:text-gray-400 ml-2">
                                Port {conn.port_number} → {otherDevice
                                  ? `${otherDevice.properties.name || otherDevice.type} (${cableType})`
                                  : `${cableType} cable`}
                              </div>
                            );
                          })}
                      </div>
                    )}

                    {/* Show wireless mesh count for APs */}
                    {['indoor_ap', 'outdoor_ap'].includes(item.type) && (
                      <div className="text-gray-600 dark:text-gray-400">
                        Wireless mesh: {items.filter(i =>
                          i.type === 'wireless_mesh' &&
                          (i.properties.start_ap_id === item.id || i.properties.end_ap_id === item.id)
                        ).length} / 4
                      </div>
                    )}

                    {/* Show wireless mesh connections details for APs */}
                    {['indoor_ap', 'outdoor_ap'].includes(item.type) && (() => {
                      const meshLinks = items.filter(i =>
                        i.type === 'wireless_mesh' &&
                        (i.properties.start_ap_id === item.id || i.properties.end_ap_id === item.id)
                      );

                      if (meshLinks.length > 0) {
                        return (
                          <div className="mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
                            <div className="font-semibold text-gray-700 dark:text-gray-300 mb-1">Mesh Connections:</div>
                            {meshLinks.map((mesh) => {
                              const otherApId = mesh.properties.start_ap_id === item.id
                                ? mesh.properties.end_ap_id
                                : mesh.properties.start_ap_id;

                              const otherAp = otherApId
                                ? items.find(i => i.id === otherApId)
                                : null;

                              return (
                                <div key={mesh.id} className="text-xs text-gray-600 dark:text-gray-400 ml-2">
                                  → {otherAp ? (otherAp.properties.name || otherAp.type) : 'Unknown AP'}
                                </div>
                              );
                            })}
                          </div>
                        );
                      }
                      return null;
                    })()}

                    {item.properties.notes && (
                      <div className="text-gray-600 dark:text-gray-400 mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
                        {item.properties.notes}
                      </div>
                    )}
                    {item.properties.image && (
                      <div className="mt-2">
                        <img
                          src={item.properties.image}
                          alt="Attachment"
                          className="w-full rounded border border-gray-200 dark:border-gray-700"
                          style={{ maxHeight: '150px', objectFit: 'contain' }}
                        />
                      </div>
                    )}
                  </div>
                </Popup>
              )}
            </Marker>
          );
        }

        return null;
      })}

      {/* Context menu rendered outside map using portal */}
      {contextMenu && createPortal(
        <ItemContextMenu
          item={contextMenu.item}
          position={contextMenu.position}
          onClose={() => setContextMenu(null)}
          onUpdate={loadItems}
        />,
        document.body
      )}
    </>
  );
}
