import React, { useState, useEffect, useRef, useCallback } from 'react';
import { Box, Group, Text, ActionIcon, Button, Menu, Badge } from '@mantine/core';
import {
  IconMenu2,
  IconLayoutSidebar,
  IconLayoutBottombar,
  IconDownload,
  IconUpload,
  IconTrash,
  IconX,
  IconGripVertical
} from '@tabler/icons-react';
import { DockviewReact, DockviewReadyEvent, IDockviewPanelProps } from 'dockview';
import { useDockStore, ZoneType, Panel } from '../../stores/useDockStore';
import { VSCodeLayout } from './VSCodeLayout';

// Importar componentes de dock existentes
import { TaskDock } from '../docks/TaskDock';
import { PropertiesDock } from '../docks/PropertiesDock';
import { ConsoleDock } from '../docks/ConsoleDock';
import { FileExplorerDock } from '../docks/FileExplorerDock';

import 'dockview/dist/styles/dockview.css';
import '../dockview.css';
import './VSCodeLayout.css';

// Wrappers para DockView optimizados
const TaskDockWrapper = React.memo((props: IDockviewPanelProps) => <TaskDock />);
const PropertiesDockWrapper = React.memo((props: IDockviewPanelProps) => <PropertiesDock />);
const ConsoleDockWrapper = React.memo((props: IDockviewPanelProps) => <ConsoleDock />);
const FileExplorerDockWrapper = React.memo((props: IDockviewPanelProps) => <FileExplorerDock />);

// Componentes disponibles
const dockComponents = {
  tasks: TaskDockWrapper,
  properties: PropertiesDockWrapper,
  console: ConsoleDockWrapper,
  fileExplorer: FileExplorerDockWrapper,
} as const;

// Interfaces
interface DropZoneIndicatorProps {
  position: 'top' | 'bottom' | 'left' | 'right' | 'center';
  active: boolean;
}

interface ZoneDockViewProps {
  zone: ZoneType;
  className?: string;
}

// Componente para indicadores de drop zone mejorados
function DropZoneIndicator({ position, active }: DropZoneIndicatorProps) {
  if (!active) return null;

  const positionClasses = {
    top: 'vscode-drop-indicator-top',
    bottom: 'vscode-drop-indicator-bottom',
    left: 'vscode-drop-indicator-left',
    right: 'vscode-drop-indicator-right',
    center: 'vscode-drop-indicator-center'
  };

  return (
    <div className={`vscode-drop-indicator ${positionClasses[position]}`}>
      <div className="vscode-drop-indicator-content">
        <Box p="md" style={{
          background: 'rgba(0, 123, 255, 0.1)',
          border: '2px dashed #007bff',
          borderRadius: '4px',
          textAlign: 'center'
        }}>
          <Text size="sm" c="blue" fw={500}>
            {position === 'center' ? 'Soltar aquí para agregar pestañas' : `Soltar aquí para dividir ${position}`}
          </Text>
        </Box>
      </div>
    </div>
  );
}

// Navbar personalizada mejorada
function EnhancedNavbar() {
  const { toggleZone, zones, resetZones } = useDockStore();

  const handleExportLayout = useCallback(() => {
    const layout = JSON.stringify(zones, null, 2);
    const blob = new Blob([layout], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'vscode-layout.json';
    a.click();
    URL.revokeObjectURL(url);
  }, [zones]);

  const handleImportLayout = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        const layout = JSON.parse(e.target?.result as string);
        // Aquí implementarías la lógica para importar el layout
        console.log('Layout importado:', layout);
      } catch (error) {
        console.error('Error al importar layout:', error);
      }
    };
    reader.readAsText(file);
  }, []);

  return (
    <Group justify="space-between" style={{ width: '100%' }}>
      <Group>
        <Text size="sm" fw={600} c="dark">
          VSCode Layout Consolidado
        </Text>
        <Badge size="xs" variant="light" color="blue">
          Drag & Drop Mejorado
        </Badge>
        <Text size="xs" c="dimmed">
          Arrastra pestañas para reordenar, dividir y mover entre zonas
        </Text>
      </Group>

      <Group gap="xs">
        <Menu shadow="md" width={200}>
          <Menu.Target>
            <ActionIcon variant="light" size="sm">
              <IconMenu2 size={14} />
            </ActionIcon>
          </Menu.Target>

          <Menu.Dropdown>
            <Menu.Label>Layout</Menu.Label>
            <Menu.Item leftSection={<IconDownload size={14} />} onClick={handleExportLayout}>
              Exportar Layout
            </Menu.Item>
            <Menu.Item leftSection={<IconUpload size={14} />}>
              <input
                type="file"
                accept=".json"
                style={{ display: 'none' }}
                onChange={handleImportLayout}
                id="import-layout"
              />
              <label htmlFor="import-layout" style={{ cursor: 'pointer' }}>
                Importar Layout
              </label>
            </Menu.Item>
            <Menu.Item leftSection={<IconTrash size={14} />} color="red" onClick={resetZones}>
              Resetear Layout
            </Menu.Item>
          </Menu.Dropdown>
        </Menu>

        <ActionIcon
          variant={zones.sidebar.visible ? 'filled' : 'light'}
          onClick={() => toggleZone('sidebar')}
          size="sm"
          title="Toggle Sidebar"
        >
          <IconLayoutSidebar size={14} />
        </ActionIcon>

        <ActionIcon
          variant={zones.asidebar.visible ? 'filled' : 'light'}
          onClick={() => toggleZone('asidebar')}
          size="sm"
          title="Toggle Right Panel"
        >
          <IconLayoutSidebar size={14} style={{ transform: 'scaleX(-1)' }} />
        </ActionIcon>

        <ActionIcon
          variant={zones.bottom.visible ? 'filled' : 'light'}
          onClick={() => toggleZone('bottom')}
          size="sm"
          title="Toggle Bottom Panel"
        >
          <IconLayoutBottombar size={14} />
        </ActionIcon>
      </Group>
    </Group>
  );
}

// Componente principal para cada zona con funcionalidad mejorada
function EnhancedZoneDockView({ zone, className }: ZoneDockViewProps) {
  const [api, setApi] = useState<DockviewReadyEvent>();
  const [dragOverPosition, setDragOverPosition] = useState<'top' | 'bottom' | 'left' | 'right' | 'center' | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const dragOverlayRef = useRef<HTMLDivElement>(null);

  const {
    zones,
    movePanel,
    reorderPanel,
    removePanel,
    setActivePanel,
    draggedPanel,
    startDrag,
    endDrag,
    dropPanel,
    addPanel
  } = useDockStore();

  const zoneData = zones[zone];

  // Configuración inicial de DockView
  const onReady = useCallback((event: DockviewReadyEvent) => {
    setApi(event);

    // Limpiar paneles existentes
    event.api.clear();

    // Agregar paneles con configuración mejorada
    let lastPanel: any = null;

    zoneData.panels.forEach((panel, index) => {
      const panelConfig: any = {
        id: panel.id,
        component: panel.component,
        title: panel.title,
        params: { ...panel.props, panelId: panel.id, zone }
      };

      // Configurar posicionamiento para crear splits inteligentes
      if (lastPanel && index > 0) {
        const directions = zone === 'center' ? ['right', 'below'] : ['below', 'right'];
        const direction = directions[index % directions.length];

        panelConfig.position = {
          direction,
          referencePanel: lastPanel,
        };
      }

      const newPanel = event.api.addPanel(panelConfig);
      lastPanel = newPanel;
    });

    // Activar panel inicial
    if (zoneData.activePanel) {
      const activePanel = event.api.getPanel(zoneData.activePanel);
      activePanel?.api.setActive();
    }
  }, [zoneData.panels, zoneData.activePanel, zone]);

  // Eventos mejorados de DockView con logs de depuración
  useEffect(() => {
    if (!api) return;

    console.log(`🎮 [${zone}] Setting up DockView event listeners`);

    // Manejar cambios de pestañas activas
    const handleActiveChange = (event: any) => {
      console.log(`🎯 [${zone}] Active panel change:`, { newPanel: event?.panel?.id, currentActive: zoneData.activePanel });
      if (event?.panel?.id && event.panel.id !== zoneData.activePanel) {
        setActivePanel(zone, event.panel.id);
      }
    };

    // Manejar cierre de paneles
    const handlePanelRemove = (event: any) => {
      console.log(`❌ [${zone}] Panel remove:`, event?.panel?.id);
      if (event?.panel?.id) {
        removePanel(zone, event.panel.id);
      }
    };

    // Manejar inicio de drag
    const handleDragStart = (event: any) => {
      console.log(`🎯 [${zone}] Drag start:`, event?.panel?.id);
      if (event?.panel?.id) {
        const panel = zoneData.panels.find(p => p.id === event.panel.id);
        if (panel) {
          startDrag(panel, zone);
        }
      }
    };

    // Manejar drop interno (para futuras mejoras)
    const handleDrop = (event: any) => {
      console.log(`📥 [${zone}] Drop event:`, event);
      // No hacer endDrag aquí, se hace en dropPanel
    };

    // ✅ Manejar movimiento/reordenamiento de paneles dentro de la zona
    const handlePanelMove = (event: any) => {
      console.log(`🔄 [${zone}] Panel move event:`, {
        panelId: event?.panel?.id,
        fromIndex: event?.fromIndex,
        toIndex: event?.toIndex
      });

      if (event?.panel?.id && typeof event?.toIndex === 'number') {
        reorderPanel(zone, event.panel.id, event.toIndex);
      }
    };

    // ✅ Registrar todos los eventos con verificación
    const unsubscribers: Array<{ dispose?: () => void }> = [];

    try {
      unsubscribers.push(api.api.onDidActivePanelChange(handleActiveChange));
      unsubscribers.push(api.api.onDidRemovePanel(handlePanelRemove));
      unsubscribers.push(api.api.onWillDragPanel(handleDragStart));
      unsubscribers.push(api.api.onDidDrop(handleDrop));

      // Verificar si onDidMovePanel existe antes de usarlo
      if (typeof api.api.onDidMovePanel === 'function') {
        unsubscribers.push(api.api.onDidMovePanel(handlePanelMove));
        console.log(`✅ [${zone}] onDidMovePanel registered`);
      } else {
        console.log(`⚠️ [${zone}] onDidMovePanel not available`);
      }
    } catch (error) {
      console.error(`❌ [${zone}] Error setting up event listeners:`, error);
    }

    return () => {
      console.log(`🧹 [${zone}] Cleaning up event listeners`);
      unsubscribers.forEach(unsubscribe => {
        try {
          unsubscribe?.dispose?.();
        } catch (error) {
          console.warn(`⚠️ [${zone}] Error disposing listener:`, error);
        }
      });
    };
  }, [api, zone, zoneData.panels, zoneData.activePanel, setActivePanel, removePanel, startDrag, endDrag, reorderPanel]);

  // Lógica mejorada de drag & drop entre zonas
  const calculateDropPosition = useCallback((e: React.DragEvent, container: HTMLElement) => {
    const rect = container.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    const centerX = rect.width / 2;
    const centerY = rect.height / 2;
    const threshold = 0.25; // 25% del área para detectar bordes

    // Detectar posición basada en dónde está el cursor
    if (y < rect.height * threshold) return 'top';
    if (y > rect.height * (1 - threshold)) return 'bottom';
    if (x < rect.width * threshold) return 'left';
    if (x > rect.width * (1 - threshold)) return 'right';

    return 'center';
  }, []);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    if (!draggedPanel || !containerRef.current) return;

    e.preventDefault();
    e.stopPropagation();

    const position = calculateDropPosition(e, containerRef.current);
    setDragOverPosition(position);
  }, [draggedPanel, calculateDropPosition]);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    // Solo ocultar si realmente salimos del contenedor
    if (!containerRef.current?.contains(e.relatedTarget as Node)) {
      setDragOverPosition(null);
    }
  }, []);

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();

    console.log(`📥 [${zone}] Handle drop - draggedPanel:`, draggedPanel, 'position:', dragOverPosition);

    if (!draggedPanel || !dragOverPosition) {
      console.log(`❌ [${zone}] Drop cancelled - missing draggedPanel or position`);
      setDragOverPosition(null);
      return;
    }

    // ✅ Usar dropPanel con la posición detectada
    dropPanel(zone, dragOverPosition);

    // ✅ Limpiar indicadores
    setDragOverPosition(null);
  }, [draggedPanel, dragOverPosition, dropPanel, zone]);

  // Componente para agregar paneles rápidamente
  const QuickAddButtons = () => (
    <Box p="xs">
      <Text size="xs" mb="xs" fw={500} c="dimmed">Agregar:</Text>
      <Group gap="xs">
        <Button
          size="xs"
          variant="subtle"
          onClick={() => addPanel(zone, {
            id: `tasks-${Date.now()}`,
            title: 'Tareas',
            component: 'tasks',
            closable: true,
          })}
        >
          Tareas
        </Button>
        <Button
          size="xs"
          variant="subtle"
          onClick={() => addPanel(zone, {
            id: `explorer-${Date.now()}`,
            title: 'Explorador',
            component: 'fileExplorer',
            closable: true,
          })}
        >
          Explorador
        </Button>
      </Group>
    </Box>
  );

  if (!zoneData.visible) {
    return null;
  }

  return (
    <Box
      ref={containerRef}
      className={`vscode-zone-container ${className || ''}`}
      style={{
        height: '100%',
        width: '100%',
        position: 'relative',
        minHeight: '200px'
      }}
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
    >
      {zoneData.panels.length === 0 ? (
        <Box
          style={{
            height: '100%',
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'center',
            background: 'var(--mantine-color-gray-0)',
            border: '1px dashed var(--mantine-color-gray-4)',
            borderRadius: '4px'
          }}
        >
          <Text size="sm" c="dimmed" mb="md">
            Zona {zone} vacía
          </Text>
          <QuickAddButtons />
        </Box>
      ) : (
        <Box style={{ height: '100%', width: '100%' }}>
          <DockviewReact
            onReady={onReady}
            components={dockComponents}
            className="dockview-theme-light vscode-dockview-enhanced"
          />
        </Box>
      )}

      {/* Indicadores de drop zone mejorados */}
      <DropZoneIndicator position="top" active={dragOverPosition === 'top'} />
      <DropZoneIndicator position="bottom" active={dragOverPosition === 'bottom'} />
      <DropZoneIndicator position="left" active={dragOverPosition === 'left'} />
      <DropZoneIndicator position="right" active={dragOverPosition === 'right'} />
      <DropZoneIndicator position="center" active={dragOverPosition === 'center'} />
    </Box>
  );
}

// Componente principal consolidado
export function VSCodeDockViewConsolidated() {
  const { zones } = useDockStore();

  const layoutState = {
    navbarHeight: 40,
    sidebarWidth: 280,
    asidebarWidth: 320,
    bottomHeight: 220,
    sidebarVisible: zones.sidebar.visible,
    asidebarVisible: zones.asidebar.visible,
    bottomVisible: zones.bottom.visible,
  };

  return (
    <VSCodeLayout
      initialLayout={layoutState}
      navbar={<EnhancedNavbar />}
      sidebar={
        <EnhancedZoneDockView zone="sidebar" className="vscode-sidebar" />
      }
      asidebar={
        <EnhancedZoneDockView zone="asidebar" className="vscode-asidebar" />
      }
      bottom={
        <EnhancedZoneDockView zone="bottom" className="vscode-bottom" />
      }
      onLayoutChange={(layout) => {
        console.log('Layout changed:', layout);
        // Persistir cambios si es necesario
      }}
    >
      <EnhancedZoneDockView zone="center" className="vscode-center" />
    </VSCodeLayout>
  );
}