import { create } from 'zustand';
import { persist, subscribeWithSelector } from 'zustand/middleware';

// Tipos para el sistema de paneles
export interface Panel {
  id: string;
  title: string;
  component: string; // Nombre del componente en lugar del componente directamente
  props?: any;
  closable?: boolean;
  icon?: React.ReactNode;
}

export interface Zone {
  id: string;
  name: string;
  panels: Panel[];
  activePanel?: string;
  visible: boolean;
}

export type ZoneType = 'navbar' | 'sidebar' | 'asidebar' | 'bottom' | 'center';

export interface DraggedPanel {
  panel: Panel;
  fromZone: ZoneType;
}

interface DockState {
  zones: Record<ZoneType, Zone>;
  draggedPanel: DraggedPanel | null;

  // Acciones
  movePanel: (panelId: string, fromZone: ZoneType, toZone: ZoneType) => void;
  reorderPanel: (zone: ZoneType, panelId: string, newIndex: number) => void;
  addPanel: (zone: ZoneType, panel: Panel) => void;
  removePanel: (zone: ZoneType, panelId: string) => void;
  setActivePanel: (zone: ZoneType, panelId: string) => void;
  toggleZone: (zone: ZoneType) => void;

  // Drag & Drop
  startDrag: (panel: Panel, fromZone: ZoneType) => void;
  endDrag: () => void;
  dropPanel: (toZone: ZoneType, position?: 'top' | 'bottom' | 'left' | 'right' | 'center') => void;

  // Group Management
  splitPanel: (zone: ZoneType, panelId: string, direction: 'horizontal' | 'vertical') => void;
  mergeGroups: (fromZone: ZoneType, toZone: ZoneType) => void;

  // Utilidades
  getPanel: (zone: ZoneType, panelId: string) => Panel | undefined;
  getAllPanels: () => Panel[];
  resetZones: () => void;
}

// Estado inicial de las zonas
const initialZones: Record<ZoneType, Zone> = {
  navbar: {
    id: 'navbar',
    name: 'Navigation Bar',
    panels: [],
    visible: true,
  },
  sidebar: {
    id: 'sidebar',
    name: 'Sidebar',
    panels: [
      {
        id: 'file-explorer',
        title: 'Explorador',
        component: 'fileExplorer',
        closable: false,
      },
      {
        id: 'sidebar-tasks',
        title: 'Tareas',
        component: 'tasks',
        closable: true,
      }
    ],
    activePanel: 'file-explorer',
    visible: true,
  },
  asidebar: {
    id: 'asidebar',
    name: 'Right Panel',
    panels: [
      {
        id: 'properties',
        title: 'Propiedades',
        component: 'properties',
        closable: true,
      }
    ],
    activePanel: 'properties',
    visible: true,
  },
  bottom: {
    id: 'bottom',
    name: 'Bottom Panel',
    panels: [
      {
        id: 'console',
        title: 'Consola',
        component: 'console',
        closable: true,
      }
    ],
    activePanel: 'console',
    visible: true,
  },
  center: {
    id: 'center',
    name: 'Main Area',
    panels: [
      {
        id: 'main-editor',
        title: 'Editor Principal',
        component: 'tasks',
        closable: false,
      }
    ],
    activePanel: 'main-editor',
    visible: true,
  },
};

export const useDockStore = create<DockState>()(
  subscribeWithSelector(
    persist(
      (set, get) => ({
        zones: initialZones,
        draggedPanel: null,

        movePanel: (panelId: string, fromZone: ZoneType, toZone: ZoneType) => {
          console.log(`🔄 [movePanel] Moving ${panelId} from ${fromZone} to ${toZone}`);

          if (fromZone === toZone) {
            console.log(`⚠️ [movePanel] Same zone, skipping`);
            return;
          }

          set((state) => {
            const panel = state.zones[fromZone].panels.find(p => p.id === panelId);
            if (!panel) {
              console.log(`❌ [movePanel] Panel ${panelId} not found in ${fromZone}`);
              return state;
            }

            console.log(`✅ [movePanel] Found panel:`, panel);

            const newZones = { ...state.zones };

            // ✅ Remover del origen
            const fromPanels = newZones[fromZone].panels.filter(p => p.id !== panelId);
            newZones[fromZone] = {
              ...newZones[fromZone],
              panels: fromPanels,
              activePanel: newZones[fromZone].activePanel === panelId
                ? fromPanels[0]?.id
                : newZones[fromZone].activePanel,
            };

            // ✅ Agregar al destino (conservar ID original)
            newZones[toZone] = {
              ...newZones[toZone],
              panels: [...newZones[toZone].panels, panel],
              activePanel: panel.id,
            };

            console.log(`✅ [movePanel] Moved successfully. From panels:`, fromPanels.length, `To panels:`, newZones[toZone].panels.length);

            return { zones: newZones };
          });
        },

        reorderPanel: (zone: ZoneType, panelId: string, newIndex: number) => {
          console.log(`🔄 [reorderPanel] Reordering ${panelId} in ${zone} to index ${newIndex}`);

          set((state) => {
            const panels = [...state.zones[zone].panels];
            const currentIndex = panels.findIndex(p => p.id === panelId);

            if (currentIndex === -1) {
              console.log(`❌ [reorderPanel] Panel ${panelId} not found in ${zone}`);
              return state;
            }

            if (currentIndex === newIndex) {
              console.log(`⚠️ [reorderPanel] Same position, skipping`);
              return state;
            }

            // ✅ Reordenar array
            const [panel] = panels.splice(currentIndex, 1);
            panels.splice(newIndex, 0, panel);

            console.log(`✅ [reorderPanel] Reordered successfully. New order:`, panels.map(p => p.id));

            return {
              zones: {
                ...state.zones,
                [zone]: {
                  ...state.zones[zone],
                  panels,
                }
              }
            };
          });
        },

        addPanel: (zone: ZoneType, panel: Panel) => {
          set((state) => {
            // Verificar si el panel ya existe en esa zona
            const existingPanel = state.zones[zone].panels.find(p => p.component === panel.component);
            if (existingPanel) {
              // Solo cambiar el panel activo
              return {
                zones: {
                  ...state.zones,
                  [zone]: {
                    ...state.zones[zone],
                    activePanel: existingPanel.id,
                  }
                }
              };
            }

            return {
              zones: {
                ...state.zones,
                [zone]: {
                  ...state.zones[zone],
                  panels: [...state.zones[zone].panels, panel],
                  activePanel: panel.id,
                }
              }
            };
          });
        },

        removePanel: (zone: ZoneType, panelId: string) => {
          set((state) => {
            const newPanels = state.zones[zone].panels.filter(p => p.id !== panelId);
            const newActivePanel = state.zones[zone].activePanel === panelId
              ? newPanels[0]?.id
              : state.zones[zone].activePanel;

            return {
              zones: {
                ...state.zones,
                [zone]: {
                  ...state.zones[zone],
                  panels: newPanels,
                  activePanel: newActivePanel,
                }
              }
            };
          });
        },

        setActivePanel: (zone: ZoneType, panelId: string) => {
          set((state) => ({
            zones: {
              ...state.zones,
              [zone]: {
                ...state.zones[zone],
                activePanel: panelId,
              }
            }
          }));
        },

        toggleZone: (zone: ZoneType) => {
          set((state) => ({
            zones: {
              ...state.zones,
              [zone]: {
                ...state.zones[zone],
                visible: !state.zones[zone].visible,
              }
            }
          }));
        },

        startDrag: (panel: Panel, fromZone: ZoneType) => {
          console.log(`🎯 [startDrag] Starting drag:`, { panelId: panel.id, fromZone });
          set({ draggedPanel: { panel, fromZone } });
        },

        endDrag: () => {
          console.log(`🏁 [endDrag] Ending drag`);
          set({ draggedPanel: null });
        },

        dropPanel: (toZone: ZoneType, position = 'center') => {
          const { draggedPanel } = get();
          if (!draggedPanel) {
            console.log(`❌ [dropPanel] No dragged panel found`);
            return;
          }

          const { panel, fromZone } = draggedPanel;
          console.log(`📥 [dropPanel] Dropping ${panel.id} from ${fromZone} to ${toZone} at ${position}`);

          if (fromZone === toZone) {
            console.log(`⚠️ [dropPanel] Same zone, no action needed`);
            get().endDrag();
            return;
          }

          // ✅ Usar la función movePanel corregida
          get().movePanel(panel.id, fromZone, toZone);

          if (position !== 'center') {
            console.log(`🔗 [dropPanel] Split position ${position} - for future implementation`);
            // TODO: Implementar splitting avanzado en futuras versiones
          }

          // ✅ Limpiar estado de drag
          get().endDrag();
        },

        splitPanel: (zone: ZoneType, panelId: string, direction: 'horizontal' | 'vertical') => {
          console.log(`Dividiendo panel ${panelId} en zona ${zone} en dirección ${direction}`);
          // Implementación futura para splitting avanzado
        },

        mergeGroups: (fromZone: ZoneType, toZone: ZoneType) => {
          set((state) => {
            const fromPanels = state.zones[fromZone].panels;

            return {
              zones: {
                ...state.zones,
                [toZone]: {
                  ...state.zones[toZone],
                  panels: [...state.zones[toZone].panels, ...fromPanels],
                },
                [fromZone]: {
                  ...state.zones[fromZone],
                  panels: [],
                  activePanel: undefined,
                }
              }
            };
          });
        },

        getPanel: (zone: ZoneType, panelId: string) => {
          return get().zones[zone].panels.find(p => p.id === panelId);
        },

        getAllPanels: () => {
          const { zones } = get();
          return Object.values(zones).flatMap(zone => zone.panels);
        },

        resetZones: () => {
          set({ zones: initialZones, draggedPanel: null });
        },
      }),
      {
        name: 'dock-store',
        partialize: (state) => ({
          zones: state.zones
        }),
      }
    )
  )
);