import { useState, useEffect, useCallback } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { queryClient } from "@/lib/queryClient";
import { OptimizedCanvas } from "@/components/optimized-canvas";
import { ColorPalette } from "@/components/color-palette";

import { Button } from "@/components/ui/button";
import { useWebSocket } from "@/hooks/use-websocket";
import { useToast } from "@/hooks/use-toast";

import { DEFAULT_SELECTED_COLOR, generateUserId, getUsername } from "@/lib/config";
import { Pixel, CanvasConfig, InsertPixel, WSMessage } from "@shared/schema";
import { apiRequest } from "@/lib/queryClient";

export default function CanvasPage() {
  const [selectedColor, setSelectedColor] = useState(DEFAULT_SELECTED_COLOR);
  const [showGrid, setShowGrid] = useState(false);
  const [cooldownSeconds, setCooldownSeconds] = useState(0);
  const [userId] = useState(() => generateUserId());
  const [username] = useState(() => getUsername());
  const { toast } = useToast();

  // Fetch initial data
  const { data: pixels = [], isLoading: pixelsLoading } = useQuery<Pixel[]>({
    queryKey: ['/api/pixels'],
  });

  const { data: config, isLoading: configLoading } = useQuery<CanvasConfig>({
    queryKey: ['/api/config'],
  });

  const { data: recentPlacements = [] } = useQuery<Pixel[]>({
    queryKey: ['/api/recent'],
    refetchInterval: 10000, // Refresh every 10 seconds instead of 5
  });

  // WebSocket handling
  const handleWebSocketMessage = useCallback((message: WSMessage) => {
    switch (message.type) {
      case "pixel_placed":
        // Invalidate pixels cache to refetch
        queryClient.invalidateQueries({ queryKey: ['/api/pixels'] });
        queryClient.invalidateQueries({ queryKey: ['/api/recent'] });
        
        //toast({
        //  title: "Pixel placed",
        //  description: `${message.data.username} placed a pixel at (${message.data.x}, ${message.data.y})`,
        //  });
        //break;
      

        
      case "cooldown_update":
        if (message.data.userId === userId) {
          setCooldownSeconds(message.data.remainingSeconds);
        }
        break;
    }
  }, [userId, toast]);

  const { isConnected, userCount } = useWebSocket(handleWebSocketMessage);

  // Pixel placement mutation
  const placePixelMutation = useMutation({
    mutationFn: async (pixel: InsertPixel) => {
      const response = await apiRequest("POST", "/api/pixels", pixel);
      return response.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['/api/pixels'] });
      queryClient.invalidateQueries({ queryKey: ['/api/recent'] });
      // Start cooldown countdown
      if (config && !config.enableAutomaticEvents) {
        setCooldownSeconds(config.defaultCooldown);
      }
    },
    onError: (error: any) => {
      if (error.message.includes("429")) {
        toast({
          title: "Cooldown active",
          description: "Please wait before placing another pixel.",
          variant: "destructive",
        });
      } else {
        toast({
          title: "Error",
          description: "Failed to place pixel. Please try again.",
          variant: "destructive",
        });
      }
    },
  });





  // Cooldown countdown
  useEffect(() => {
    if (cooldownSeconds > 0) {
      const timer = setTimeout(() => {
        setCooldownSeconds(prev => Math.max(0, prev - 1));
      }, 1000);
      return () => clearTimeout(timer);
    }
  }, [cooldownSeconds]);

  // Fetch initial cooldown state
  useEffect(() => {
    const fetchCooldown = async () => {
      try {
        const response = await fetch(`/api/cooldown/${userId}`);
        const data = await response.json();
        setCooldownSeconds(data.remainingSeconds);
      } catch (error) {
        console.error("Failed to fetch cooldown:", error);
      }
    };
    
    if (userId) {
      fetchCooldown();
    }
  }, [userId]);

  const handlePixelClick = (x: number, y: number) => {
    if (cooldownSeconds > 0) return;
    
    placePixelMutation.mutate({
      x,
      y,
      color: selectedColor,
      userId,
      username,
    });
  };



  if (pixelsLoading || configLoading || !config) {
    return (
      <div className="min-h-screen bg-canvas-bg text-white flex items-center justify-center">
        <div className="text-lg">Loading canvas...</div>
      </div>
    );
  }

  return (
    <div className="h-screen flex flex-col bg-canvas-bg text-white">
      {/* Header */}
      <header className="bg-panel-bg border-b border-gray-700 px-4 py-3 flex items-center justify-between">
        <div className="flex items-center space-x-4">
          <h1 className="text-xl font-bold text-white">r/place Clone</h1>
          <div className="flex items-center space-x-2 text-sm text-muted">
            <div className={`w-2 h-2 rounded-full ${isConnected ? 'bg-success' : 'bg-red-500'}`} />
            <span data-testid="user-count">{userCount}</span>
            <span>users online</span>
          </div>
        </div>
        
        <div className="flex items-center space-x-3">




          {/* User Info */}
          <div className="flex items-center space-x-2 px-3 py-2 bg-panel-hover rounded-lg">
            <div className="w-2 h-2 bg-success rounded-full" />
            <span className="text-sm" data-testid="username">{username}</span>
          </div>
        </div>
      </header>

      {/* Main Canvas Area */}
      <div className="flex-1 flex overflow-hidden">
        <OptimizedCanvas
          pixels={pixels}
          selectedColor={selectedColor}
          canvasWidth={config.canvasWidth}
          canvasHeight={config.canvasHeight}
          onPixelClick={handlePixelClick}
          cooldownActive={cooldownSeconds > 0}
        />
        
        <ColorPalette
          selectedColor={selectedColor}
          onColorSelect={setSelectedColor}
          cooldownSeconds={cooldownSeconds}
          recentPlacements={recentPlacements}
        />
      </div>
    </div>
  );
}
