import { useState } from "react";
import { MousePointer, Square, Pentagon, Circle, Brush, ChevronLeft, ChevronRight } from "lucide-react";
import { Tool } from "./PathoraViewer";
import { type Annotation } from "./AnnotationCanvas";

interface ToolsSidebarProps {
  selectedTool: Tool;
  onToolChange: (tool: Tool) => void;
  annotations: Annotation[];
  selectedAnnotationId: string | null;
  onSelectAnnotation: (annotationId: string | null) => void;
  uploadedSlides: Array<{
    id: string;
    name: string;
    uploadedAt: string;
    levelCount: number;
    levelDimensions: number[][];
  }>;
  tileServerUrl: string;
  onTileServerUrlChange: (value: string) => void;
  onSlideFileChange: (file: File | null) => void;
  slideFileName: string | null;
  onUploadSlide: () => void;
  isTileLoading: boolean;
  tileLoadError: string | null;
  onSelectUploadedSlide: (slideId: string) => void;
  activeLabel: string;
  onLabelChange: (label: string) => void;
  imageMeta: {
    stain: string;
    width: number | null;
    height: number | null;
    levelCount: number | null;
    mpp: number | null;
    slideId: string;
  };
  channelVisibility: {
    original: boolean;
    hematoxylin: boolean;
    eosin: boolean;
  };
  onChannelToggle: (channel: "original" | "hematoxylin" | "eosin", value: boolean) => void;
  isTileLoaded: boolean;
  isCollapsed: boolean;
  onToggleCollapsed: () => void;
}

export function ToolsSidebar({
  selectedTool,
  onToolChange,
  annotations,
  selectedAnnotationId,
  onSelectAnnotation,
  uploadedSlides,
  tileServerUrl,
  onTileServerUrlChange,
  onSlideFileChange,
  slideFileName,
  onUploadSlide,
  isTileLoading,
  tileLoadError,
  onSelectUploadedSlide,
  activeLabel,
  onLabelChange,
  imageMeta,
  channelVisibility,
  onChannelToggle,
  isTileLoaded,
  isCollapsed,
  onToggleCollapsed,
}: ToolsSidebarProps) {
  const [activeTab, setActiveTab] = useState<"tools" | "image" | "images" | "annotations">("tools");

  const tools = [
    { id: "select" as Tool, label: "Select", icon: MousePointer },
    { id: "rectangle" as Tool, label: "Rectangle", icon: Square },
    { id: "polygon" as Tool, label: "Polygon", icon: Pentagon },
    { id: "ellipse" as Tool, label: "Ellipse", icon: Circle },
    { id: "brush" as Tool, label: "Brush", icon: Brush },
  ];

  const annotationLabel = (annotation: Annotation, index: number) => {
    if (annotation.label && annotation.label.trim().length > 0) {
      return annotation.label;
    }

    return annotation.type === "rectangle"
      ? "Rectangle"
      : annotation.type === "polygon"
        ? "Polygon"
        : annotation.type === "ellipse"
          ? "Ellipse"
          : "Brush";
  };

  const normalizePoints = (points: Array<{ x: number; y: number }>, size = 24) => {
    if (points.length === 0) return [];
    const xs = points.map((p) => p.x);
    const ys = points.map((p) => p.y);
    const minX = Math.min(...xs);
    const maxX = Math.max(...xs);
    const minY = Math.min(...ys);
    const maxY = Math.max(...ys);
    const width = Math.max(maxX - minX, 1);
    const height = Math.max(maxY - minY, 1);
    const padding = 2;
    const scale = Math.min((size - padding * 2) / width, (size - padding * 2) / height);

    return points.map((p) => ({
      x: (p.x - minX) * scale + padding,
      y: (p.y - minY) * scale + padding,
    }));
  };

  const normalizeBaseUrl = (value: string) => value.replace(/\/$/, "");
  const baseTileUrl = normalizeBaseUrl(tileServerUrl);
  const thumbnailSize = 192;

  const renderAnnotationPreview = (annotation: Annotation) => {
    const size = 24;
    const stroke = annotation.color || "#9CA3AF";
    const normalized = normalizePoints(annotation.points, size);

    if (annotation.type === "rectangle" && normalized.length >= 2) {
      const [p1, p2] = normalized;
      const x = Math.min(p1.x, p2.x);
      const y = Math.min(p1.y, p2.y);
      const width = Math.abs(p2.x - p1.x);
      const height = Math.abs(p2.y - p1.y);
      return (
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
          <rect x={x} y={y} width={width} height={height} fill="none" stroke={stroke} strokeWidth="2" />
        </svg>
      );
    }

    if (annotation.type === "ellipse" && normalized.length >= 2) {
      const [p1, p2] = normalized;
      const cx = (p1.x + p2.x) / 2;
      const cy = (p1.y + p2.y) / 2;
      const rx = Math.abs(p2.x - p1.x) / 2;
      const ry = Math.abs(p2.y - p1.y) / 2;
      return (
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
          <ellipse cx={cx} cy={cy} rx={Math.max(1, rx)} ry={Math.max(1, ry)} fill="none" stroke={stroke} strokeWidth="2" />
        </svg>
      );
    }

    if ((annotation.type === "polygon" || annotation.type === "brush") && normalized.length >= 2) {
      const path = normalized.map((p, idx) => `${idx === 0 ? "M" : "L"}${p.x} ${p.y}`).join(" ");
      const closed = annotation.type === "polygon" ? " Z" : "";
      return (
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
          <path d={`${path}${closed}`} fill="none" stroke={stroke} strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" />
        </svg>
      );
    }

    return (
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <rect x="4" y="4" width="16" height="16" fill="none" stroke={stroke} strokeWidth="2" />
      </svg>
    );
  };

  return (
    <aside
      className={`bg-gray-800 border-r border-gray-700 flex flex-col py-4 transition-all duration-300 ${
        isCollapsed ? "w-20" : "w-72"
      }`}
    >
      <div className={`flex items-center justify-between px-3 ${isCollapsed ? "mb-2" : "mb-3"}`}>
        <div className="text-white text-xs font-semibold">
          {isCollapsed ? "" : "PANEL"}
        </div>
        <button
          onClick={onToggleCollapsed}
          className="p-1 rounded hover:bg-gray-700 text-gray-300"
          title={isCollapsed ? "Expand panel" : "Collapse panel"}
        >
          {isCollapsed ? <ChevronRight className="w-4 h-4" /> : <ChevronLeft className="w-4 h-4" />}
        </button>
      </div>

      <div className={`h-px ${isCollapsed ? "mx-3" : "mx-4"} bg-gray-600 mb-3`} />

      {!isCollapsed && (
        <div className="px-3 mb-3">
          <div className="flex items-center bg-gray-700 rounded-lg p-1 text-[11px]">
            {([
              { id: "tools", label: "Tools" },
              { id: "images", label: "Uploads" },
              { id: "image", label: "Image" },
              { id: "annotations", label: "Annotations" },
            ] as const).map((tab) => (
              <button
                key={tab.id}
                onClick={() => setActiveTab(tab.id)}
                className={`flex-1 px-2 py-1 rounded-md transition-colors ${
                  activeTab === tab.id
                    ? "bg-teal-600 text-white"
                    : "text-gray-200 hover:bg-gray-600"
                }`}
              >
                {tab.label}
              </button>
            ))}
          </div>
        </div>
      )}

      {(isCollapsed || activeTab === "tools") && (
        <div className="px-3">
          {!isCollapsed && (
            <div className="mb-3">
              <label className="block text-[11px] text-gray-300 mb-1">Annotation label</label>
              <select
                value={activeLabel}
                onChange={(e) => onLabelChange(e.target.value)}
                className="w-full text-xs bg-gray-700 text-gray-200 border border-gray-600 rounded px-2 py-1"
              >
                <option value="Tumor">Tumor</option>
                <option value="Benign">Benign</option>
                <option value="Stroma">Stroma</option>
                <option value="Necrosis">Necrosis</option>
                <option value="DCIS">DCIS</option>
                <option value="Invasive">Invasive</option>
              </select>
            </div>
          )}

          <div className={`grid ${isCollapsed ? "grid-cols-1" : "grid-cols-2"} gap-2`}>
            {tools.map((tool) => {
              const Icon = tool.icon;
              const isSelected = selectedTool === tool.id;

              return (
                <button
                  key={tool.id}
                  onClick={() => onToolChange(isSelected ? "none" : tool.id)}
                  className={`
                    h-14 flex flex-col items-center justify-center rounded-lg
                    transition-all duration-200
                    ${
                      isSelected
                        ? "bg-teal-600 text-white shadow-lg"
                        : "bg-gray-700 text-gray-300 hover:bg-gray-600 hover:text-white"
                    }
                  `}
                  title={tool.label}
                >
                  <Icon className="w-5 h-5" />
                  {!isCollapsed && (
                    <span className="text-[10px] mt-1 font-medium">{tool.label}</span>
                  )}
                </button>
              );
            })}
          </div>
        </div>
      )}

      {!isCollapsed && activeTab === "image" && (
        <div className="mt-2 px-3">
          <div className="text-xs font-semibold text-gray-200 mb-2">Slide metadata</div>
          <div className="space-y-2 text-[11px] text-gray-300">
            <div className="flex items-center justify-between">
              <span className="text-gray-400">Stain</span>
              <span>{imageMeta.stain}</span>
            </div>
            <div className="flex items-center justify-between">
              <span className="text-gray-400">Size</span>
              <span>
                {imageMeta.width && imageMeta.height
                  ? `${imageMeta.width} x ${imageMeta.height}`
                  : "n/a"}
              </span>
            </div>
            <div className="flex items-center justify-between">
              <span className="text-gray-400">Levels</span>
              <span>{imageMeta.levelCount ?? "n/a"}</span>
            </div>
            <div className="flex items-center justify-between">
              <span className="text-gray-400">MPP</span>
              <span>{imageMeta.mpp ? `${imageMeta.mpp.toFixed(3)} µm/px` : "n/a"}</span>
            </div>
            <div className="flex items-center justify-between">
              <span className="text-gray-400">Case / Slide</span>
              <span className="text-right max-w-[130px] truncate">{imageMeta.slideId}</span>
            </div>
          </div>

          <div className="mt-4">
            <div className="text-xs font-semibold text-gray-200 mb-2">Channels</div>
            <div className="space-y-2 text-[11px] text-gray-300">
              {([
                { id: "original", label: "Original", color: "bg-gray-400" },
                { id: "hematoxylin", label: "Hematoxylin", color: "bg-indigo-500" },
                { id: "eosin", label: "Eosin", color: "bg-pink-500" },
              ] as const).map((channel) => (
                <label
                  key={channel.id}
                  className={`flex items-center justify-between rounded px-2 py-1 border border-gray-700 ${
                    isTileLoaded ? "hover:bg-gray-700/50" : "opacity-50"
                  }`}
                >
                  <span className="flex items-center gap-2">
                    <span className={`w-3 h-3 rounded-sm ${channel.color}`} />
                    {channel.label}
                  </span>
                  <input
                    type="radio"
                    name="channel"
                    disabled={!isTileLoaded}
                    checked={channelVisibility[channel.id]}
                    onChange={() => {
                      onChannelToggle("original", channel.id === "original");
                      onChannelToggle("hematoxylin", channel.id === "hematoxylin");
                      onChannelToggle("eosin", channel.id === "eosin");
                    }}
                    className="accent-teal-500"
                  />
                </label>
              ))}
            </div>
          </div>
        </div>
      )}

      {!isCollapsed && activeTab === "images" && (
        <div className="mt-2 px-3">
          <div className="text-xs font-semibold text-gray-200 mb-2">Uploaded images</div>
          <div className="space-y-2 mb-3">
            <label className="block text-[11px] text-gray-300">Tile server URL</label>
            <input
              value={tileServerUrl}
              onChange={(e) => onTileServerUrlChange(e.target.value)}
              className="w-full text-xs bg-gray-700 text-gray-200 border border-gray-600 rounded px-2 py-1"
              placeholder="http://localhost:8001"
            />

            <label className="block text-[11px] text-gray-300">WSI file (SVS/TIFF)</label>
            <input
              type="file"
              accept=".svs,.tif,.tiff"
              onChange={(e) => {
                const file = e.target.files?.[0] ?? null;
                onSlideFileChange(file);
              }}
              className="w-full text-xs bg-gray-700 text-gray-200 border border-gray-600 rounded px-2 py-1"
            />
            {slideFileName && (
              <p className="text-[11px] text-gray-400">Selected: {slideFileName}</p>
            )}

            <button
              onClick={onUploadSlide}
              disabled={isTileLoading}
              className="w-full bg-teal-600 text-white text-xs font-semibold py-1.5 rounded hover:bg-teal-700 disabled:opacity-60"
            >
              {isTileLoading ? "Uploading slide..." : "Load Image"}
            </button>

            {tileLoadError && (
              <p className="text-[11px] text-red-400">{tileLoadError}</p>
            )}
          </div>
          <div className="text-[11px] text-gray-400 mb-2">
            {uploadedSlides.length} total
          </div>
          <div className="max-h-[50vh] overflow-y-auto pr-1 space-y-2">
            {uploadedSlides.length === 0 && (
              <div className="text-[11px] text-gray-500 bg-gray-700/40 rounded p-2">
                No uploads yet
              </div>
            )}
            {uploadedSlides.map((slide) => (
              <button
                key={slide.id}
                type="button"
                onClick={() => onSelectUploadedSlide(slide.id)}
                className={`w-full rounded border px-2 py-2 text-[11px] transition-colors h-[88px] ${
                  slide.id === imageMeta.slideId
                    ? "bg-teal-600/20 border-teal-500 text-teal-100"
                    : "bg-gray-700/40 border-gray-700 text-gray-200"
                }`}
              >
                <div className="flex items-center gap-3 h-full">
                  <div className="w-16 h-16 rounded bg-white border border-gray-700 overflow-hidden flex-shrink-0">
                    <img
                      src={`${baseTileUrl}/slides/${slide.id}/thumbnail?size=${thumbnailSize}&channel=original`}
                      alt={`WSI preview ${slide.id}`}
                      className="w-full h-full object-contain"
                      loading="lazy"
                    />
                  </div>
                  <div className="min-w-0 text-left">
                    <div className="text-xs font-semibold truncate text-left">{slide.name}</div>
                    <div className="text-[10px] text-gray-400 truncate text-left">{slide.uploadedAt}</div>
                    <div className="text-[10px] text-gray-400 truncate text-left">{slide.id}</div>
                  </div>
                </div>
              </button>
            ))}
          </div>
        </div>
      )}

      {!isCollapsed && activeTab === "annotations" && (
        <div className="mt-4 px-3">
          <div className="text-xs font-semibold text-gray-200 mb-2">Annotations</div>
          <div className="text-[11px] text-gray-400 mb-2">
            {annotations.length} total
          </div>
          <div className="max-h-[50vh] overflow-y-auto pr-1 space-y-1">
            {annotations.length === 0 && (
              <div className="text-[11px] text-gray-500 bg-gray-700/40 rounded p-2">
                No annotations yet
              </div>
            )}
            {annotations.map((annotation, index) => {
              const isActive = annotation.id === selectedAnnotationId;
              const label = annotationLabel(annotation, index);
              return (
                <button
                  key={annotation.id}
                  onClick={() => onSelectAnnotation(annotation.id)}
                  className={`w-full text-left px-2 py-2 rounded border transition-colors ${
                    isActive
                      ? "bg-teal-600/20 border-teal-500 text-teal-100"
                      : "bg-gray-700/40 border-gray-700 text-gray-200 hover:bg-gray-700"
                  }`}
                  title={annotation.id}
                >
                  <div className="flex items-center gap-2">
                    <div className="w-7 h-7 flex items-center justify-center rounded bg-gray-800/60 border border-gray-700">
                      {renderAnnotationPreview(annotation)}
                    </div>
                    <span className="text-xs font-semibold truncate text-left flex-1">{label}</span>
                    <span className="text-[10px] text-gray-400">
                      {annotation.type === "rectangle"
                        ? "Rect"
                        : annotation.type === "polygon"
                          ? "Poly"
                          : annotation.type === "ellipse"
                            ? "Ell"
                            : "Brush"}
                    </span>
                  </div>
                  <div className="text-[10px] text-gray-400 truncate">
                    {annotation.id}
                  </div>
                </button>
              );
            })}
          </div>
        </div>
      )}

      <div className="flex-1" />
    </aside>
  );
}
