please review the following code of my next.js frontend: // src/components/WebSocketManager.tsx
"use client";

import React, { useEffect, useState, useCallback, useRef } from "react";
import dynamic from 'next/dynamic';
import { 
  BarData, 
  WebSocketMessage, 
  MT5AccountInfo, 
  ConnectionStatus,
  WebSocketSubscription
} from "../lib/types";
import { fetchConfig } from '../lib/api';

// Optimize dynamic imports with proper loading states and SSR configuration
const Chart = dynamic(
  () => import("./Chart"),
  {
    ssr: false,
    loading: () => (
      <div className="flex items-center justify-center h-[500px] bg-gray-50 rounded">
        <div className="text-center">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mx-auto mb-4"></div>
          <p className="text-gray-500">Loading chart...</p>
        </div>
      </div>
    )
  }
);

const TradingForm = dynamic(
  () => import("./TradingForm"),
  {
    ssr: false,
    loading: () => (
      <div className="animate-pulse space-y-4">
        <div className="h-12 bg-gray-200 rounded"></div>
        <div className="h-32 bg-gray-200 rounded"></div>
      </div>
    )
  }
);

const AccountStatus = dynamic(
  () => import("./AccountStatus"),
  {
    ssr: false,
    loading: () => (
      <div className="animate-pulse space-y-2">
        <div className="h-6 bg-gray-200 rounded w-3/4"></div>
        <div className="h-4 bg-gray-200 rounded w-1/2"></div>
      </div>
    )
  }
);

const WS_URL = process.env.NEXT_PUBLIC_WS_URL || "ws://192.168.8.114:8005/ws";
const RECONNECT_INTERVAL = 5000;

const WebSocketManager: React.FC = () => {
  // Client-side rendering check
  const [isClient, setIsClient] = useState(false);

  // WebSocket and connection management
  const wsRef = useRef<WebSocket | null>(null);
  const connectionAttemptRef = useRef<boolean>(false);
  const [ws, setWs] = useState<WebSocket | null>(null);

  // Application state
  const [historicalData, setHistoricalData] = useState<BarData[]>([]);
  const [symbols, setSymbols] = useState<string[]>([]);
  const [trades, setTrades] = useState<any[]>([]);
  const [accountInfo, setAccountInfo] = useState<MT5AccountInfo | null>(null);
  const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>({
    connected: false,
    last_update: Math.floor(Date.now() / 1000),
    message: "Initializing connection..."
  });

  // Chart control state
  const [chartSymbol, setChartSymbol] = useState<string>("");
  const [chartTimeframe, setChartTimeframe] = useState<string>("");
  const [availableSymbols, setAvailableSymbols] = useState<string[]>([]);
  const [availableTimeframes, setAvailableTimeframes] = useState<string[]>([]);
  const [chartError, setChartError] = useState<string | null>(null);
  const [configLoading, setConfigLoading] = useState(true);

  // Refs for data management
  const latestDataRef = useRef<BarData[]>([]);
  const currentSubscriptionRef = useRef<WebSocketSubscription | null>(null);

  // Add new state for config loading
  const [configLoaded, setConfigLoaded] = useState(false);

  // Set client-side rendering flag
  useEffect(() => {
    setIsClient(true);
  }, []);

  // WebSocket message handler
  const handleWebSocketMessage = useCallback((event: MessageEvent) => {
    try {
      const message = JSON.parse(event.data) as WebSocketMessage;
      
      switch (message.action) {
        case 'historical_data':
          if (message.data && Array.isArray(message.data)) {
            console.log("Received historical data:", message.data.length, "bars");
            setHistoricalData(message.data as BarData[]);
            latestDataRef.current = message.data as BarData[];
            setChartError(null);
          }
          break;
        
        case 'ohlc_update':
          if (message.data && !Array.isArray(message.data)) {
            const updateData = message.data as BarData;
            console.log("Received OHLC update for:", message.symbol);
            setHistoricalData(prevData => {
              const newData = [...prevData];
              const lastIndex = newData.length - 1;
              
              if (lastIndex >= 0 && newData[lastIndex].time === updateData.time) {
                // Update existing candle
                newData[lastIndex] = updateData;
              } else {
                // Add new candle
                newData.push(updateData);
                // Optional: Limit the number of candles to prevent memory issues
                if (newData.length > 1000) {
                  newData.shift();
                }
              }
              
              latestDataRef.current = newData;
              return newData;
            });
          }
          break;
  
        case 'account_update':
          if (message.account_info) {
            console.log("Received account update");
            setAccountInfo(message.account_info);
            setConnectionStatus(prev => ({
              ...prev,
              last_update: Math.floor(Date.now() / 1000)
            }));
          }
          break;
  
        case 'connection_status':
          if (message.status) {
            console.log("Received connection status update:", message.status);
            setConnectionStatus(message.status);
            if (!message.status.connected) {
              setAccountInfo(null);
            }
          }
          break;
  
        case 'error':
          console.error("Received error message:", message.error);
          setChartError(message.error || 'Unknown error occurred');
          break;
      }
    } catch (error) {
      console.error('Error processing WebSocket message:', error);
      setChartError('Failed to process data');
    }
  }, []);
  

  // Subscription management
  const subscribeToSymbol = useCallback((symbol: string, timeframe: string) => {
    if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
      console.warn('Cannot subscribe: WebSocket is not connected');
      return;
    }

    try {
      // Only unsubscribe if the subscription is different
      if (currentSubscriptionRef.current && 
          (currentSubscriptionRef.current.symbol !== symbol || 
           currentSubscriptionRef.current.timeframe !== timeframe)) {
        console.log(`Unsubscribing from ${currentSubscriptionRef.current.symbol}:${currentSubscriptionRef.current.timeframe}`);
        const unsubscribeMessage: WebSocketMessage = {
          action: 'unsubscribe',
          symbol: currentSubscriptionRef.current.symbol,
          timeframe: currentSubscriptionRef.current.timeframe,
        };
        wsRef.current.send(JSON.stringify(unsubscribeMessage));
      }

      console.log(`Subscribing to ${symbol}:${timeframe}`);
      const subscribeMessage: WebSocketMessage = {
        action: 'subscribe',
        symbol,
        timeframe,
      };
      wsRef.current.send(JSON.stringify(subscribeMessage));
      
      currentSubscriptionRef.current = { symbol, timeframe };
    } catch (error) {
      console.error('Error during subscription change:', error);
      setChartError('Failed to change subscription');
    }
  }, []);

  // Chart symbol change handler
  const handleChartSymbolChange = useCallback((newSymbol: string) => {
    console.log(`Changing symbol to ${newSymbol}`);
    setChartError(null);
    setChartSymbol(newSymbol);
    
    if (wsRef.current?.readyState === WebSocket.OPEN) {
      try {
        const historyMessage: WebSocketMessage = {
          action: 'get_data',
          symbol: newSymbol,
          timeframe: chartTimeframe,
        };
        wsRef.current.send(JSON.stringify(historyMessage));
        
        subscribeToSymbol(newSymbol, chartTimeframe);
      } catch (error) {
        console.error('Error changing symbol:', error);
        setChartError(`Failed to request data for ${newSymbol}`);
      }
    } else {
      setChartError('WebSocket connection not available');
    }
  }, [chartTimeframe, subscribeToSymbol]);

  // Chart timeframe change handler
  const handleChartTimeframeChange = useCallback((newTimeframe: string) => {
    console.log(`Changing timeframe to ${newTimeframe}`);
    setChartError(null);
    setChartTimeframe(newTimeframe);
    
    if (wsRef.current?.readyState === WebSocket.OPEN) {
      try {
        // Request historical data
        const historyMessage: WebSocketMessage = {
          action: 'get_data',
          symbol: chartSymbol,
          timeframe: newTimeframe,
        };
        wsRef.current.send(JSON.stringify(historyMessage));
        
        // Update subscription
        subscribeToSymbol(chartSymbol, newTimeframe);
      } catch (error) {
        console.error('Error changing timeframe:', error);
        setChartError(`Failed to request data for timeframe ${newTimeframe}`);
      }
    } else {
      setChartError('WebSocket connection not available');
    }
  }, [chartSymbol, subscribeToSymbol]);

  // WebSocket connection management
  useEffect(() => {
    if (!isClient) return;

    let isComponentMounted = true;
    let reconnectTimeout: NodeJS.Timeout;

    const connectWebSocket = () => {
      if (wsRef.current?.readyState === WebSocket.OPEN) {
        return;
      }

      try {
        console.log("Initiating WebSocket connection...");
        
        const socket = new WebSocket(WS_URL);
        wsRef.current = socket;
        setWs(socket);

        socket.onopen = () => {
          if (!isComponentMounted) return;
          
          console.log("WebSocket connected successfully");
          setConnectionStatus({
            connected: true,
            last_update: Math.floor(Date.now() / 1000),
            message: "Connected"
          });

          if (chartSymbol && chartTimeframe) {
            const message: WebSocketMessage = {
              action: 'get_data',
              symbol: chartSymbol,
              timeframe: chartTimeframe,
            };
            socket.send(JSON.stringify(message));
            subscribeToSymbol(chartSymbol, chartTimeframe);
          }
        };

        socket.onmessage = handleWebSocketMessage;
        
        socket.onclose = (event) => {
          if (!isComponentMounted) return;
          
          console.log("WebSocket disconnected:", event.reason);
          wsRef.current = null;
          
          setConnectionStatus({
            connected: false,
            last_update: Math.floor(Date.now() / 1000),
            message: "Disconnected - attempting to reconnect..."
          });

          if (isComponentMounted) {
            reconnectTimeout = setTimeout(connectWebSocket, RECONNECT_INTERVAL);
          }
        };

        socket.onerror = (error) => {
          if (!isComponentMounted) return;
          
          console.error("WebSocket error:", error);
          setChartError('WebSocket connection error');
          wsRef.current = null;
        };
      } catch (error) {
        console.error("Failed to create WebSocket connection:", error);
        if (isComponentMounted) {
          setChartError('Failed to establish WebSocket connection');
        }
        wsRef.current = null;
      }
    };

    connectWebSocket();

    return () => {
      console.log("Cleaning up WebSocket connection...");
      isComponentMounted = false;
      clearTimeout(reconnectTimeout);
      
      if (wsRef.current?.readyState === WebSocket.OPEN) {
        if (currentSubscriptionRef.current) {
          const unsubscribeMessage: WebSocketMessage = {
            action: 'unsubscribe',
            symbol: currentSubscriptionRef.current.symbol,
            timeframe: currentSubscriptionRef.current.timeframe,
          };
          wsRef.current.send(JSON.stringify(unsubscribeMessage));
        }
        wsRef.current.close();
        wsRef.current = null;
      }
    };
  }, [isClient, chartSymbol, chartTimeframe]);

  // Configuration loading
  useEffect(() => {
    if (!isClient || configLoaded) return;

    let isComponentMounted = true;

    const loadConfig = async () => {
      try {
        console.log("Loading configuration...");
        const config = await fetchConfig();
        
        if (!isComponentMounted) return;
        
        setAvailableSymbols(config.symbols);
        setAvailableTimeframes(config.timeframes);
        
        // Set initial values if not already set
        if (!chartSymbol && config.symbols.length > 0) {
          setChartSymbol(config.symbols[0]);
        }
        if (!chartTimeframe && config.timeframes.length > 0) {
          setChartTimeframe(config.timeframes[0]);
        }
        
        setSymbols(config.symbols);
        setConfigLoading(false);
        setConfigLoaded(true);
      } catch (error) {
        console.error('Failed to load configuration:', error);
        if (isComponentMounted) {
          setChartError('Failed to load configuration');
          setConfigLoading(false);
        }
      }
    };

    loadConfig();

    return () => {
      isComponentMounted = false;
    };
  }, [isClient, chartSymbol, chartTimeframe, configLoaded]);

  // Handle new trades
  const handleNewTrade = useCallback((trade: any) => {
    setTrades(prevTrades => [...prevTrades, trade]);
    console.log("Trade executed:", trade);
  }, []);

  // Don't render anything during SSR
  if (!isClient) {
    return null;
  }

  // Render component
  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Trading Platform</h1>
      
      <AccountStatus 
        accountInfo={accountInfo}
        connectionStatus={connectionStatus}
      />
      
      {configLoading ? (
        <div className="text-center py-4">
          <p>Loading configuration...</p>
        </div>
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <div className="md:col-span-2">
            {chartError && (
              <div className="mb-4 p-2 bg-red-100 border border-red-400 text-red-700 rounded">
                {chartError}
              </div>
            )}
            {historicalData.length > 0 ? (
              <Chart
                symbol={chartSymbol}
                timeframe={chartTimeframe}
                historicalData={historicalData}
                trades={trades}
                availableSymbols={availableSymbols}
                availableTimeframes={availableTimeframes}
                onSymbolChange={handleChartSymbolChange}
                onTimeframeChange={handleChartTimeframeChange}
              />
            ) : (
              <div className="flex items-center justify-center h-[500px] bg-gray-50 rounded">
                <p className="text-gray-500">Loading data...</p>
              </div>
            )}
          </div>
          <div>
            <TradingForm 
              symbols={symbols} 
              onTradeExecuted={handleNewTrade}
              disabled={!connectionStatus.connected}
            />
          </div>
        </div>
      )}
    </div>
  );
};

export default WebSocketManager;