import { useState, useRef, useEffect } from "react";
import { useSearchParams } from "react-router-dom";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator";
import { Upload, Download, Paintbrush, Square, Circle, Minus, Type, Trash2, Play, Save, Folder } from "lucide-react";
import { skill, entities, auth } from "@/lib/nvwa";

type Tool = "pen" | "rectangle" | "circle" | "line" | "text" | "eraser";

interface DrawingElement {
  type: Tool;
  x: number;
  y: number;
  width?: number;
  height?: number;
  x2?: number;
  y2?: number;
  text?: string;
  color?: string;
  strokeWidth?: number;
}

interface Project {
  id: number;
  name: string;
  description?: string;
  user_id: string;
  created_at: string;
  updated_at?: string;
}

interface Wireframe {
  id: number;
  project_id: number;
  name: string;
  description?: string;
  canvas_data?: DrawingElement[];
  created_at: string;
  updated_at?: string;
}

export default function CanvasPage() {
  const [searchParams] = useSearchParams();
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [tool, setTool] = useState<Tool>("pen");
  const [isDrawing, setIsDrawing] = useState(false);
  const [startPos, setStartPos] = useState({ x: 0, y: 0 });
  const [description, setDescription] = useState("");
  const [generatedImageUrl, setGeneratedImageUrl] = useState<string | null>(null);
  const [isGenerating, setIsGenerating] = useState(false);
  const [elements, setElements] = useState<DrawingElement[]>([]);
  const [currentProject, setCurrentProject] = useState<Project | null>(null);
  const [currentWireframe, setCurrentWireframe] = useState<Wireframe | null>(null);
  const [projects, setProjects] = useState<Project[]>([]);
  const [wireframeName, setWireframeName] = useState("Untitled Wireframe");
  const [isSaving, setIsSaving] = useState(false);

  // Canvas drawing functions
  const startDrawing = (e: React.MouseEvent<HTMLCanvasElement>) => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const rect = canvas.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    setStartPos({ x, y });
    setIsDrawing(true);

    if (tool === "pen") {
      // For pen, we add points continuously
      const newElement: DrawingElement = {
        type: "pen",
        x,
        y,
        color: "#000000",
        strokeWidth: 2
      };
      setElements(prev => [...prev, newElement]);
    }
  };

  const draw = (e: React.MouseEvent<HTMLCanvasElement>) => {
    if (!isDrawing || !canvasRef.current) return;

    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    const rect = canvas.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    if (tool === "pen") {
      // Draw freehand line
      ctx.strokeStyle = "#000000";
      ctx.lineWidth = 2;
      ctx.lineCap = "round";
      ctx.beginPath();
      ctx.moveTo(startPos.x, startPos.y);
      ctx.lineTo(x, y);
      ctx.stroke();

      // Update last element with current position
      setElements(prev => {
        const newElements = [...prev];
        const lastElement = newElements[newElements.length - 1];
        if (lastElement && lastElement.type === "pen") {
          lastElement.x2 = x;
          lastElement.y2 = y;
        }
        return newElements;
      });
      setStartPos({ x, y });
    } else {
      // Preview shape while drawing
      redrawCanvas();
      ctx.strokeStyle = "#000000";
      ctx.lineWidth = 2;

      switch (tool) {
        case "rectangle":
          ctx.strokeRect(startPos.x, startPos.y, x - startPos.x, y - startPos.y);
          break;
        case "circle":
          const radius = Math.sqrt(Math.pow(x - startPos.x, 2) + Math.pow(y - startPos.y, 2));
          ctx.beginPath();
          ctx.arc(startPos.x, startPos.y, radius, 0, 2 * Math.PI);
          ctx.stroke();
          break;
        case "line":
          ctx.beginPath();
          ctx.moveTo(startPos.x, startPos.y);
          ctx.lineTo(x, y);
          ctx.stroke();
          break;
      }
    }
  };

  const stopDrawing = (e: React.MouseEvent<HTMLCanvasElement>) => {
    if (!isDrawing || !canvasRef.current) return;

    const canvas = canvasRef.current;
    const rect = canvas.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    if (tool !== "pen") {
      const newElement: DrawingElement = {
        type: tool,
        x: startPos.x,
        y: startPos.y,
        x2: x,
        y2: y,
        color: "#000000",
        strokeWidth: 2
      };
      setElements(prev => [...prev, newElement]);
    }

    setIsDrawing(false);
    redrawCanvas();
  };

  const redrawCanvas = () => {
    const canvas = canvasRef.current;
    const ctx = canvas?.getContext("2d");
    if (!canvas || !ctx) return;

    // Clear canvas
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // Redraw all elements
    elements.forEach(element => {
      ctx.strokeStyle = element.color || "#000000";
      ctx.lineWidth = element.strokeWidth || 2;

      switch (element.type) {
        case "rectangle":
          if (element.x2 && element.y2) {
            ctx.strokeRect(element.x, element.y, element.x2 - element.x, element.y2 - element.y);
          }
          break;
        case "circle":
          if (element.x2 && element.y2) {
            const radius = Math.sqrt(Math.pow(element.x2 - element.x, 2) + Math.pow(element.y2 - element.y, 2));
            ctx.beginPath();
            ctx.arc(element.x, element.y, radius, 0, 2 * Math.PI);
            ctx.stroke();
          }
          break;
        case "line":
          if (element.x2 && element.y2) {
            ctx.beginPath();
            ctx.moveTo(element.x, element.y);
            ctx.lineTo(element.x2, element.y2);
            ctx.stroke();
          }
          break;
      }
    });
  };

  useEffect(() => {
    redrawCanvas();
  }, [elements]);

  useEffect(() => {
    loadProjectsAndWireframe();
  }, []);

  const loadProjectsAndWireframe = async () => {
    try {
      const user = await auth.currentUser();
      if (!user) return;

      const projectIdFromUrl = searchParams.get("projectId");

      // Load projects
      const { data: userProjects } = await entities
        .from("nvwa_project")
        .select("*")
        .eq("user_id", user.id);

      if (userProjects && userProjects.length > 0) {
        setProjects(userProjects);
        // Use specified project or first one
        let project: Project;
        if (projectIdFromUrl) {
          const found = userProjects.find((p: Project) => p.id === parseInt(projectIdFromUrl));
          if (found) {
            project = found;
          } else {
            project = userProjects[0];
          }
        } else {
          project = userProjects[0];
        }
        setCurrentProject(project);

        // Load latest wireframe for this project
        const { data: wireframes } = await entities
          .from("nvwa_wireframe")
          .select("*")
          .eq("project_id", project.id)
          .order("updated_at", { ascending: false })
          .limit(1);

        if (wireframes && wireframes.length > 0) {
          const wireframe = wireframes[0];
          setCurrentWireframe(wireframe);
          setWireframeName(wireframe.name);
          setDescription(wireframe.description || "");

          // Load canvas data
          if (wireframe.canvas_data) {
            setElements(wireframe.canvas_data);
          }
        }
      } else {
        // Create default project if no projects exist
        const { data: newProject } = await entities
          .from("nvwa_project")
          .insert({
            name: "Default Project",
            description: "Default wireframe project",
            user_id: user.id
          })
          .select()
          .single();

        if (newProject) {
          setCurrentProject(newProject);
          setProjects([newProject]);
        }
      }
    } catch (error) {
      console.error("Failed to load projects:", error);
    }
  };

  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = (event) => {
      const img = new Image();
      img.onload = () => {
        const canvas = canvasRef.current;
        const ctx = canvas?.getContext("2d");
        if (canvas && ctx) {
          // Resize canvas to fit image
          canvas.width = img.width;
          canvas.height = img.height;
          ctx.drawImage(img, 0, 0);
        }
      };
      img.src = event.target?.result as string;
    };
    reader.readAsDataURL(file);
  };

  const generateImage = async () => {
    if (!canvasRef.current || !description.trim()) return;

    // Ensure wireframe is saved before generation
    if (!currentWireframe) {
      await saveWireframe();
      if (!currentWireframe) return; // Still no wireframe, maybe save failed
    }

    setIsGenerating(true);
    try {
      // Convert canvas to base64
      const canvas = canvasRef.current;
      const dataUrl = canvas.toDataURL("image/png");

      // Use DoodlePainting skill
      const result = await skill.execute("DoodlePainting", {
        sketch: dataUrl,
        prompt: description,
        style: "modern",
        structureStrength: 0.8
      });

      if (result && result.imageUrls && result.imageUrls.length > 0) {
        const generatedUrl = result.imageUrls[0];
        setGeneratedImageUrl(generatedUrl);

        // Save generation to database
        await entities
          .from("nvwa_generation")
          .insert({
            wireframe_id: currentWireframe.id,
            prompt: description,
            status: "completed",
            generated_image_url: generatedUrl
          });
      }
    } catch (error) {
      console.error("Generation failed:", error);
      alert("生成失败，请重试");

      // Save failed generation
      if (currentWireframe) {
        await entities
          .from("nvwa_generation")
          .insert({
            wireframe_id: currentWireframe.id,
            prompt: description,
            status: "failed",
            error_message: error instanceof Error ? error.message : "Unknown error"
          });
      }
    } finally {
      setIsGenerating(false);
    }
  };

  const downloadImage = () => {
    if (!generatedImageUrl) return;

    const link = document.createElement("a");
    link.href = generatedImageUrl;
    link.download = "wireframe-render.png";
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  const saveWireframe = async () => {
    if (!currentProject) return;

    setIsSaving(true);
    try {
      const canvasData = elements;

      if (currentWireframe) {
        // Update existing wireframe
        await entities
          .from("nvwa_wireframe")
          .update({
            name: wireframeName,
            canvas_data: canvasData,
            description: description
          })
          .eq("id", currentWireframe.id);
      } else {
        // Create new wireframe
        const { data: newWireframe } = await entities
          .from("nvwa_wireframe")
          .insert({
            project_id: currentProject.id,
            name: wireframeName,
            canvas_data: canvasData,
            description: description
          })
          .select()
          .single();

        if (newWireframe) {
          setCurrentWireframe(newWireframe);
        }
      }
    } catch (error) {
      console.error("Failed to save wireframe:", error);
      alert("保存失败，请重试");
    } finally {
      setIsSaving(false);
    }
  };

  const clearCanvas = () => {
    setElements([]);
    const canvas = canvasRef.current;
    const ctx = canvas?.getContext("2d");
    if (canvas && ctx) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    }
  };

  return (
    <div className="flex h-screen bg-background">
      {/* Toolbar */}
      <div className="w-16 bg-muted p-2 flex flex-col gap-2">
        <Button
          variant={tool === "pen" ? "default" : "ghost"}
          size="sm"
          onClick={() => setTool("pen")}
          title="Pen"
        >
          <Paintbrush className="w-4 h-4" />
        </Button>
        <Button
          variant={tool === "rectangle" ? "default" : "ghost"}
          size="sm"
          onClick={() => setTool("rectangle")}
          title="Rectangle"
        >
          <Square className="w-4 h-4" />
        </Button>
        <Button
          variant={tool === "circle" ? "default" : "ghost"}
          size="sm"
          onClick={() => setTool("circle")}
          title="Circle"
        >
          <Circle className="w-4 h-4" />
        </Button>
        <Button
          variant={tool === "line" ? "default" : "ghost"}
          size="sm"
          onClick={() => setTool("line")}
          title="Line"
        >
          <Minus className="w-4 h-4" />
        </Button>
        <Separator />
        <Button
          variant="ghost"
          size="sm"
          onClick={clearCanvas}
          title="Clear"
        >
          <Trash2 className="w-4 h-4" />
        </Button>
        <Label htmlFor="file-upload" className="cursor-pointer">
          <Button variant="ghost" size="sm" asChild>
            <span title="Upload">
              <Upload className="w-4 h-4" />
            </span>
          </Button>
        </Label>
        <Input
          id="file-upload"
          type="file"
          accept="image/*"
          onChange={handleFileUpload}
          className="hidden"
        />
      </div>

      {/* Canvas */}
      <div className="flex-1 p-4">
        <canvas
          ref={canvasRef}
          width={800}
          height={600}
          className="border border-border bg-white cursor-crosshair"
          onMouseDown={startDrawing}
          onMouseMove={draw}
          onMouseUp={stopDrawing}
          onMouseLeave={stopDrawing}
        />
      </div>

      {/* Sidebar */}
      <div className="w-80 bg-muted p-4 flex flex-col gap-4">
        <Card>
          <CardHeader>
            <CardTitle>Project & Wireframe</CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            <div>
              <Label htmlFor="project-name">Project</Label>
              <Input
                id="project-name"
                value={currentProject?.name || ""}
                disabled
                placeholder="No project selected"
              />
            </div>
            <div>
              <Label htmlFor="wireframe-name">Wireframe Name</Label>
              <Input
                id="wireframe-name"
                value={wireframeName}
                onChange={(e) => setWireframeName(e.target.value)}
                placeholder="Wireframe name"
              />
            </div>
            <Button onClick={saveWireframe} disabled={isSaving} size="sm">
              <Save className="w-4 h-4 mr-2" />
              {isSaving ? "Saving..." : "Save"}
            </Button>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Description</CardTitle>
          </CardHeader>
          <CardContent>
            <Textarea
              placeholder="Describe your wireframe design..."
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              rows={4}
            />
          </CardContent>
        </Card>

        <Button
          onClick={generateImage}
          disabled={isGenerating || !description.trim()}
          className="w-full"
        >
          <Play className="w-4 h-4 mr-2" />
          {isGenerating ? "Generating..." : "Generate Image"}
        </Button>

        {generatedImageUrl && (
          <Card>
            <CardHeader>
              <CardTitle>Generated Image</CardTitle>
            </CardHeader>
            <CardContent className="flex flex-col gap-2">
              <img
                src={generatedImageUrl}
                alt="Generated"
                className="w-full rounded border"
              />
              <Button onClick={downloadImage} variant="outline" size="sm">
                <Download className="w-4 h-4 mr-2" />
                Download
              </Button>
            </CardContent>
          </Card>
        )}
      </div>
    </div>
  );
}