import React, { useState, useCallback, useRef, useEffect, RefObject, useMemo } from 'react';
import { Maximize2, Minimize2, Minimize, Expand, X, SquareMinus, Maximize, ChevronDown, CommandIcon, LogOut } from 'lucide-react';
import { WindowData, WindowPosition } from '../types';
import classNames from 'clsx';
import Draggable from 'react-draggable';
import { ResizableBox } from 'react-resizable';
import { getIconForWindowType } from './WindowIcons';
import { useImperativeHandle } from 'react';
import { emitter } from '../modules';
interface WindowManagerProps {
  windows: WindowData[];
  showTaskbar?: boolean;
  onSave?: (windows: WindowData[]) => void;
  onCommand?: () => void;
}

// Minimum window dimensions
const MIN_WINDOW_WIDTH = 300;
const MIN_WINDOW_HEIGHT = 200;

const WindowManager = React.forwardRef(({ windows: initialWindows, showTaskbar = true, onSave, onCommand }: WindowManagerProps, ref) => {
  const [windows, setWindows] = useState<WindowData[]>(initialWindows);
  const [fullscreenWindow, setFullscreenWindow] = useState<string | null>(null);
  const [windowPositions, setWindowPositions] = useState<Record<string, WindowPosition>>({});
  const [activeWindow, setActiveWindow] = useState<string | null>(null);
  const [maxZIndex, setMaxZIndex] = useState(100);
  const containerRef = useRef<HTMLDivElement>(null);
  const [mount, setMount] = useState(false);
  const [update, setUpdate] = useState(0);
  // Create stable refs for each window
  const windowRefs = useRef<Record<string, React.RefObject<HTMLDivElement | null>>>({});
  const draggableRefs = useRef<Record<string, React.RefObject<HTMLDivElement | null>>>({});

  useImperativeHandle(ref, () => ({
    addWindow: (window: WindowData) => {
      addWindow(window);
    },
    getWindows: () => {
      return windows;
    },
    setWindows: (windows: WindowData[]) => {
      console.log('setWindows in manager', windows);
      setWindows(windows);
      setUpdate((prev) => prev + 1);
    },
  }));
  useEffect(() => {
    console.log('initialWindows', initialWindows);
    setWindows(initialWindows);
  }, [initialWindows]);

  // Initialize refs for all windows
  useEffect(() => {
    windows.forEach((window) => {
      if (!windowRefs.current[window.id]) {
        windowRefs.current[window.id] = React.createRef<HTMLDivElement | null>();
      }
      if (!draggableRefs.current[window.id]) {
        draggableRefs.current[window.id] = React.createRef<HTMLDivElement | null>();
      }
    });
  }, [windows]);

  // Initialize window positions
  useEffect(() => {
    const positions: Record<string, WindowPosition> = {};
    windows.forEach((window) => {
      positions[window.id] = {
        x: 0,
        y: 0,
        width: 0,
        height: 0,
        zIndex: 1000,
        ...window.position,
      };
    });

    setWindowPositions(positions);
    setMaxZIndex(1000 + windows.length);
    setMount(true);
  }, [windows.length, update]);
  useEffect(() => {
    if (mount) {
      const newWindows = windows
        .map((window) => {
          return {
            ...window,
            position: windowPositions[window.id],
          };
        })
        .sort((a, b) => a.position.zIndex - b.position.zIndex)
        .map((item, index) => {
          return {
            ...item,
            position: {
              ...item.position,
              zIndex: 1000 + index,
            },
          };
        });
      onSave?.(newWindows);
    }
  }, [mount, windowPositions]);
  const addWindow = useCallback((window: WindowData) => {
    const has = windows.find((w) => w.id === window.id);
    if (has) {
      setWindows((prev) => prev.map((w) => (w.id === window.id ? window : w)));
    } else {
      setWindows((prev) => [...prev, window]);
    }
  }, []);
  // Handle window removal
  const handleRemoveWindow = useCallback(
    (windowId: string) => {
      const window = windows.find((w) => w.id === windowId);
      const command = window?.commandList?.find((c) => c.key === 'close');
      if (command) {
        emitter.emit('window-command', { windowData: window, command });
        return;
      }
      setWindows((prev) => prev.filter((w) => w.id !== windowId));
      setWindows((prev) =>
        prev.map((w) => {
          if (w.id === windowId) {
            return { ...w, isMinimized: false };
          }
          return w;
        }),
      );
      if (fullscreenWindow === windowId) {
        setFullscreenWindow(null);
      }
    },
    [fullscreenWindow],
  );

  // Handle window minimize
  const handleMinimizeWindow = useCallback(
    (windowId: string) => {
      let needBringToFront = false;
      setWindows((prev) =>
        prev.map((w) => {
          if (w.id === windowId) {
            needBringToFront = !w.isMinimized;
            return { ...w, isMinimized: !w.isMinimized };
          }
          return w;
        }),
      );

      if (fullscreenWindow === windowId) {
        setFullscreenWindow(null);
      }

      if (needBringToFront) {
        bringToFront(windowId);
      }
    },
    [, fullscreenWindow],
  );

  // Handle window fullscreen
  const handleFullscreenWindow = useCallback((windowId: string) => {
    setFullscreenWindow((prev) => (prev === windowId ? null : windowId));

    // Ensure window is not minimized when going fullscreen
    setWindows((prev) =>
      prev.map((w) => {
        if (w.id === windowId) {
          return { ...w, isMinimized: false };
        }
        return w;
      }),
    );
    // Bring to front when going fullscreen
    bringToFront(windowId);
  }, []);

  // Bring window to front
  const bringToFront = useCallback(
    (windowId: string, e?: any) => {
      setActiveWindow(windowId);
      setMaxZIndex((prev) => prev + 1);
      setWindowPositions((prev) => ({
        ...prev,
        [windowId]: {
          ...prev[windowId],
          zIndex: maxZIndex + 1,
        },
      }));
      if (e) {
        e.stopPropagation();
        return e.target.className.includes('window-draggable');
      }
    },
    [maxZIndex],
  );

  // Handle window resize
  const handleResize = useCallback((windowId: string, e: any, { size }: { size: { width: number; height: number } }) => {
    // Ensure minimum dimensions are respected
    const width = Math.max(MIN_WINDOW_WIDTH, size.width);
    const height = Math.max(MIN_WINDOW_HEIGHT, size.height);

    setWindowPositions((prev) => ({
      ...prev,
      [windowId]: {
        ...prev[windowId],
        width,
        height,
      },
    }));
  }, []);

  // Render window controls
  const renderWindowControls = useCallback(
    (windowId: string) => {
      const isFullscreen = fullscreenWindow === windowId;
      return (
        <div className='flex items-center space-x-2'>
          <button
            onClick={(e) => {
              e.stopPropagation();
              handleMinimizeWindow(windowId);
            }}
            className='p-1 hover:bg-gray-200 rounded'>
            <SquareMinus size={16} />
          </button>
          <button
            onClick={(e) => {
              e.stopPropagation();
              handleFullscreenWindow(windowId);
            }}
            className='p-1 hover:bg-gray-200 rounded'>
            {isFullscreen ? <Minimize2 size={16} /> : <Expand size={16} />}
          </button>
          <button
            onClick={(e) => {
              e.stopPropagation();
              handleRemoveWindow(windowId);
            }}
            className='p-1 hover:bg-red-200 rounded'>
            <X size={16} />
          </button>
        </div>
      );
    },
    [handleMinimizeWindow, handleFullscreenWindow, handleRemoveWindow],
  );

  // Render the taskbar with minimized windows
  const renderTaskbar = () => {
    const showWindowsList = windows.filter((window) => window.show && window.showTaskbar);
    // if (showWindowsList.length === 0) return null;
    // useEffect(() => {
    //   const handleResize = () => {
    //     // const icons = document.querySelectorAll('.more-icon');
    //     // icons.forEach((iconEl) => {
    //     //   const icon = iconEl as HTMLElement;
    //     //   const button = icon.closest('button');
    //     //   if (button && button.offsetWidth <= 150) {
    //     //     icon.style.display = 'none';
    //     //   } else {
    //     //     icon.style.display = 'block';
    //     //   }
    //     // });
    //   };

    //   window.addEventListener('resize', handleResize);
    //   handleResize(); // Initial check

    //   return () => {
    //     window.removeEventListener('resize', handleResize);
    //   };
    // }, []);
    const showLogout = useMemo(() => {
      return localStorage.getItem('token');
    }, []);
    return (
      <div className=' pointer-events-auto  fixed w-full overflow-x-auto bottom-0 left-0 right-0 bg-gray-200 text-white p-2 flex space-x-2 z-[9000] h-[40px]'>
        {showLogout && (
          <div
          className='flex items-center  space-x-2 cursor-pointer bg-blue-600 rounded-md p-1'
          onClick={() => {
            context?.app?.call?.({
              path: 'user',
              key: 'logout',
            });
          }}>
            <LogOut size={16} />
          </div>
        )}
        <div
          className='flex items-center  space-x-2 cursor-pointer bg-blue-600 rounded-md p-1'
          onClick={() => {
            onCommand?.();
          }}>
          <CommandIcon size={16} />
        </div>
        {showWindowsList.map((window) => {
          const isMinimized = window.isMinimized;
          return (
            <button
              key={window.id}
              className={classNames(
                'px-3 py-1 rounded text-sm max-w-[200px] truncate flex items-center justify-between',
                isMinimized ? 'bg-gray-600 hover:bg-gray-500' : 'bg-blue-600 hover:bg-blue-500',
                activeWindow === window.id && 'shadow-lg',
                'bar-button',
                'cursor-pointer',
              )}
              onClick={() => handleMinimizeWindow(window.id)}>
              <span className='truncate min-w-[8px]'>{window.title}</span>
              <div className='flex items-center space-x-1 ml-2'>
                {/* {isMinimized ? <Maximize className='cursor-pointer more-icon' size={16} /> : <SquareMinus className='cursor-pointer more-icon' size={16} />} */}
                <ChevronDown className='cursor-pointer' size={16} />
                <X
                  className='cursor-pointer x-icon'
                  size={16}
                  onClick={(e) => {
                    e.stopPropagation();
                    handleRemoveWindow(window.id);
                  }}
                />
              </div>
            </button>
          );
        })}
      </div>
    );
  };

  // Add this useEffect to handle window resize

  // Render a fixed position window
  const renderFixedWindow = (windowData: WindowData) => {
    const isMinimized = windowData.isMinimized;
    const isFullscreen = fullscreenWindow === windowData.id;
    const position = windowPositions[windowData.id];
    const Icon = getIconForWindowType(windowData.type || 'welcome');
    const showRounded = windowData.showRounded ?? true;
    if (!position) return null;

    // Convert width and height to numbers for Resizable component
    const width = isFullscreen ? window.innerWidth : position.width;
    const height = isFullscreen ? window.innerHeight - 40 : position.height;

    // Get or create refs for this window
    if (!windowRefs.current[windowData.id]) {
      windowRefs.current[windowData.id] = React.createRef<HTMLDivElement | null>();
    }
    if (!draggableRefs.current[windowData.id]) {
      draggableRefs.current[windowData.id] = React.createRef<HTMLDivElement | null>();
    }

    const windowRef = windowRefs.current[windowData.id];
    const draggableRef = draggableRefs.current[windowData.id];
    const zIndex = isFullscreen ? 9999 : windowData.id == '__ai__' ? 3000 : position.zIndex;
    return (
      <div
        key={windowData.id}
        className={classNames(
          'absolute pointer-events-auto', //
          windowData.show && !isMinimized && 'block',
          (!windowData.show || isMinimized) && 'hidden',
        )}
        style={{
          left: isFullscreen ? 0 : position.x,
          top: isFullscreen ? 0 : position.y,
          width: width,
          height: height,
          zIndex: zIndex,
        }}
        ref={windowRef}>
        <div
          className={classNames('window-container', isFullscreen && 'fullscreen', showTaskbar && 'hidden-taskbar', windowData.show && !isMinimized && 'block')}
          style={{
            width: '100%',
            height: '100%',
          }}>
          <Draggable
            handle='.window-title-bar'
            position={{ x: 0, y: 0 }}
            onStart={(e) => bringToFront(windowData.id)}
            onStop={(e, data) => {
              if (!isFullscreen) {
                // Update the window's position in the state
                const newX = position.x + data.x;
                const newY = position.y + data.y;
                setWindowPositions((prev) => ({
                  ...prev,
                  [windowData.id]: {
                    ...prev[windowData.id],
                    x: newX,
                    y: newY,
                  },
                }));
              }
            }}
            nodeRef={draggableRef as RefObject<HTMLElement>}
            allowAnyClick={true}
            disabled={isFullscreen}>
            <div className='window-draggable' ref={draggableRef}>
              <ResizableBox
                width={width}
                height={height}
                onResize={(e, data) => !isFullscreen && handleResize(windowData.id, e, data)}
                // resizeHandles={isFullscreen ? [] : ['e', 's', 'se']}
                resizeHandles={windowData.resizeHandles || ['e', 's', 'se']}
                minConstraints={[MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT]}
                draggableOpts={{ disabled: isFullscreen }}>
                <div
                  className={classNames(
                    'window bg-white shadow-lg overflow-hidden border border-gray-300',
                    showRounded && 'rounded-lg',
                    isFullscreen && 'fullscreen',
                    activeWindow === windowData.id && 'active',
                  )}
                  style={{
                    width: `${width}px`,
                    height: `${height}px`,
                  }}
                  onClick={() => bringToFront(windowData.id)}>
                  <div className='window-title-bar bg-gray-100 border-b border-gray-300 px-2 py-1 flex justify-between items-center cursor-move'>
                    <div className='window-title font-medium flex items-center'>
                      {windowData.showTitle && (
                        <>
                          <Icon className='mr-2' size={20} />
                          {windowData.title}
                        </>
                      )}
                    </div>
                    <div className='window-controls'>{renderWindowControls(windowData.id)}</div>
                  </div>
                  <div className='window-content h-[calc(100%-32px)] overflow-auto'>
                    <div className='h-full flex flex-col'>
                      <WindowContent window={windowData} />
                    </div>
                  </div>
                </div>
              </ResizableBox>
            </div>
          </Draggable>
        </div>
      </div>
    );
  };
  return (
    <div className='h-screen w-screen overflow-hidden' ref={containerRef}>
      {windows.map((window) => renderFixedWindow(window))}
      {showTaskbar && renderTaskbar()}
    </div>
  );
});
WindowManager.displayName = 'WindowManager';
export const WindowContent = React.memo((props: { window: WindowData }) => {
  const { window } = props;
  const ref = useRef<HTMLDivElement>(null);
  useEffect(() => {
    emitter.emit('window-load', { windowData: window, el: ref.current });
    return () => {
      emitter.emit('window-unload', { windowData: window, el: ref.current });
    };
  }, []);
  return <div data-id={window.id} className='flex-1 overflow-auto editor-window' ref={ref}></div>;
});

export default WindowManager;
