'use client';

import { useState, useCallback, useEffect } from 'react';
import { VirtualCanvas } from '../components/canvas/VirtualCanvas';
import { CooldownTimer } from '../components/ui/CooldownTimer';
import { PixelConfirmModal } from '../components/ui/PixelConfirmModal';
import { StatsOverlay } from '../components/ui/StatsOverlay';
import { CoordinateDisplay } from '../components/ui/CoordinateDisplay';
import { UsernameModal } from '../components/ui/UsernameModal';
import { SettingsButton } from '../components/ui/SettingsButton';
import { ZoomControls } from '../components/ui/ZoomControls';
import { useWebSocket } from '../hooks/useWebSocket';
import { useCanvasStore } from '../store/canvasStore';
import { ErrorBoundary } from '../components/ErrorBoundary';
import type { PixelPlacedMessage, ChunkDataMessage } from '@gaplace/shared';

export default function HomePage() {
  const [selectedColor, setSelectedColor] = useState('#FF0000');
  const [pendingPixel, setPendingPixel] = useState<{ x: number; y: number } | null>(null);
  const [isCooldownActive, setIsCooldownActive] = useState(false);
  const [onlineUsers, setOnlineUsers] = useState(1);
  const [totalPixels, setTotalPixels] = useState(0);
  const [hoverCoords, setHoverCoords] = useState<{ x: number; y: number; pixelInfo: { color: string; userId?: string; username?: string } | null } | null>(null);
  const [username, setUsername] = useState('');
  const [showUsernameModal, setShowUsernameModal] = useState(false);

  // Generate userId once and keep it stable, store in localStorage
  const [userId] = useState(() => {
    if (typeof window !== 'undefined') {
      let storedUserId = localStorage.getItem('gaplace-user-id');
      if (!storedUserId) {
        storedUserId = 'guest-' + Math.random().toString(36).substr(2, 9);
        localStorage.setItem('gaplace-user-id', storedUserId);
      }
      return storedUserId;
    }
    return 'guest-' + Math.random().toString(36).substr(2, 9);
  });

  // Load username from localStorage and show modal if none exists
  useEffect(() => {
    if (typeof window !== 'undefined') {
      const storedUsername = localStorage.getItem('gaplace-username');
      if (storedUsername) {
        setUsername(storedUsername);
      } else {
        setShowUsernameModal(true);
      }
    }
  }, []);

  // Canvas store
  const { setPixel, loadChunk: loadChunkToStore, viewport, setZoom, setViewport } = useCanvasStore();

  const handlePixelPlaced = useCallback((message: PixelPlacedMessage & { username?: string }) => {
    console.log('Pixel placed:', message);
    setPixel(message.x, message.y, message.color, message.userId, message.username);
  }, [setPixel]);

  const handleChunkData = useCallback((message: ChunkDataMessage) => {
    console.log('Chunk data received:', message);
    loadChunkToStore(message.chunkX, message.chunkY, message.pixels);
  }, [loadChunkToStore]);

  const handleUserList = useCallback((users: string[]) => {
    setOnlineUsers(users.length);
  }, []);

  const handleCanvasStats = useCallback((stats: { totalPixels?: number; activeUsers?: number; lastActivity?: number }) => {
    setTotalPixels(stats.totalPixels || 0);
  }, []);

  const { isConnected, placePixel, loadChunk, moveCursor } = useWebSocket({
    canvasId: 'main',
    userId,
    username,
    onPixelPlaced: handlePixelPlaced,
    onChunkData: handleChunkData,
    onUserList: handleUserList,
    onCanvasStats: handleCanvasStats,
  });

  const handlePixelClick = useCallback((x: number, y: number) => {
    if (isCooldownActive) return;
    setPendingPixel({ x, y });
  }, [isCooldownActive]);

  const handleConfirmPixel = useCallback(() => {
    if (!pendingPixel) return;
    
    // Immediately place pixel locally for instant feedback
    setPixel(pendingPixel.x, pendingPixel.y, selectedColor, userId, username);
    
    // Send to server
    placePixel(pendingPixel.x, pendingPixel.y, selectedColor);
    setPendingPixel(null);
    setIsCooldownActive(true);
  }, [pendingPixel, selectedColor, placePixel, setPixel, userId, username]);

  const handleCancelPixel = useCallback(() => {
    setPendingPixel(null);
  }, []);

  const handleCooldownComplete = useCallback(() => {
    setIsCooldownActive(false);
  }, []);

  const handleCursorMove = useCallback((x: number, y: number) => {
    moveCursor(x, y, 'pixel');
  }, [moveCursor]);

  const handleChunkNeeded = useCallback((chunkX: number, chunkY: number) => {
    loadChunk(chunkX, chunkY);
  }, [loadChunk]);

  const handleHoverChange = useCallback((x: number, y: number, pixelInfo: { color: string; userId?: string } | null) => {
    setHoverCoords({ x, y, pixelInfo });
  }, []);

  const handleUsernameChange = useCallback((newUsername: string) => {
    setUsername(newUsername);
    if (typeof window !== 'undefined') {
      localStorage.setItem('gaplace-username', newUsername);
    }
  }, []);

  const handleZoomIn = useCallback(() => {
    const newZoom = Math.min(viewport.zoom * 1.2, 5.0);
    
    // Zoom towards center of viewport (canvas center)
    if (typeof window !== 'undefined') {
      const screenCenterX = window.innerWidth / 2;
      const screenCenterY = window.innerHeight / 2;
      
      // Calculate what canvas coordinate is currently at screen center
      const BASE_PIXEL_SIZE = 32;
      const currentPixelSize = BASE_PIXEL_SIZE * viewport.zoom;
      const newPixelSize = BASE_PIXEL_SIZE * newZoom;
      
      const canvasCenterX = (screenCenterX + viewport.x) / currentPixelSize;
      const canvasCenterY = (screenCenterY + viewport.y) / currentPixelSize;
      
      // Calculate new viewport to keep same canvas point at screen center
      const newViewportX = canvasCenterX * newPixelSize - screenCenterX;
      const newViewportY = canvasCenterY * newPixelSize - screenCenterY;
      
      setViewport({
        zoom: newZoom,
        x: newViewportX,
        y: newViewportY,
      });
    } else {
      setZoom(newZoom);
    }
  }, [setZoom, setViewport, viewport]);

  const handleZoomOut = useCallback(() => {
    const newZoom = Math.max(viewport.zoom / 1.2, 0.1);
    
    // Zoom towards center of viewport (canvas center)
    if (typeof window !== 'undefined') {
      const screenCenterX = window.innerWidth / 2;
      const screenCenterY = window.innerHeight / 2;
      
      // Calculate what canvas coordinate is currently at screen center
      const BASE_PIXEL_SIZE = 32;
      const currentPixelSize = BASE_PIXEL_SIZE * viewport.zoom;
      const newPixelSize = BASE_PIXEL_SIZE * newZoom;
      
      const canvasCenterX = (screenCenterX + viewport.x) / currentPixelSize;
      const canvasCenterY = (screenCenterY + viewport.y) / currentPixelSize;
      
      // Calculate new viewport to keep same canvas point at screen center
      const newViewportX = canvasCenterX * newPixelSize - screenCenterX;
      const newViewportY = canvasCenterY * newPixelSize - screenCenterY;
      
      setViewport({
        zoom: newZoom,
        x: newViewportX,
        y: newViewportY,
      });
    } else {
      setZoom(newZoom);
    }
  }, [setZoom, setViewport, viewport]);

  return (
    <ErrorBoundary>
      <div className="relative w-full h-screen overflow-hidden">
        {/* Fullscreen Canvas */}
        <ErrorBoundary fallback={
          <div className="w-full h-full bg-gray-900 flex items-center justify-center">
            <div className="text-white text-center">
              <div className="text-4xl mb-4">🎨</div>
              <div>Canvas failed to load</div>
              <button 
                onClick={() => window.location.reload()} 
                className="mt-4 px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
              >
                Reload
              </button>
            </div>
          </div>
        }>
          <VirtualCanvas
            onPixelClick={handlePixelClick}
            onCursorMove={handleCursorMove}
            onChunkNeeded={handleChunkNeeded}
            onHoverChange={handleHoverChange}
            selectedColor={selectedColor}
          />
        </ErrorBoundary>

        {/* Overlay UI Components */}
        <ErrorBoundary>
          <StatsOverlay
            onlineUsers={onlineUsers}
            totalPixels={totalPixels}
            zoom={viewport.zoom}
          />
        </ErrorBoundary>

        {/* Zoom Controls */}
        <ErrorBoundary>
          <ZoomControls
            zoom={viewport.zoom}
            onZoomIn={handleZoomIn}
            onZoomOut={handleZoomOut}
          />
        </ErrorBoundary>

        {/* Username Settings Button - Only show when no stats are visible */}
        {username && (
          <ErrorBoundary>
            <SettingsButton
              username={username}
              onOpenSettings={() => setShowUsernameModal(true)}
            />
          </ErrorBoundary>
        )}

        <ErrorBoundary>
          <CooldownTimer
            isActive={isCooldownActive}
            duration={10}
            onComplete={handleCooldownComplete}
          />
        </ErrorBoundary>

        <ErrorBoundary>
          <PixelConfirmModal
            isOpen={!!pendingPixel}
            x={pendingPixel?.x || 0}
            y={pendingPixel?.y || 0}
            color={selectedColor}
            onColorChange={setSelectedColor}
            onConfirm={handleConfirmPixel}
            onCancel={handleCancelPixel}
          />
        </ErrorBoundary>

        {/* Coordinate Display */}
        {hoverCoords && (
          <ErrorBoundary>
            <CoordinateDisplay
              x={hoverCoords.x}
              y={hoverCoords.y}
              pixelColor={hoverCoords.pixelInfo?.color || null}
              pixelOwner={hoverCoords.pixelInfo?.username || hoverCoords.pixelInfo?.userId || null}
              zoom={viewport.zoom}
            />
          </ErrorBoundary>
        )}

        {/* Username Modal */}
        <ErrorBoundary>
          <UsernameModal
            isOpen={showUsernameModal}
            currentUsername={username}
            onUsernameChange={handleUsernameChange}
            onClose={() => setShowUsernameModal(false)}
          />
        </ErrorBoundary>

        {/* Connection Status */}
        {!isConnected && (
          <ErrorBoundary>
            <div className="fixed top-4 sm:top-6 left-1/2 transform -translate-x-1/2 z-50">
              <div className="bg-red-500/90 backdrop-blur-md rounded-xl px-3 sm:px-4 py-2 text-white text-xs sm:text-sm font-medium">
                Connecting...
              </div>
            </div>
          </ErrorBoundary>
        )}
      </div>
    </ErrorBoundary>
  );
}