import { Checkbox } from "antd";
import { Tag } from "antd";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";

/**
 * LocalMediaGrid
 * Lightweight replacement for react-grid-gallery inside the chat popover.
 * Props:
 *  - images: Array<{ src, fullsize, filename?, isSelected? }>
 *  - onToggle(index)
 *  - onClick(index) optional for viewing
 *  - thumbSize: automatically set to 125 for chat, 250 for default
 */
export function LocalMediaGrid({
  images,
  onToggle,
  onClick,
  gap = 8,
  minColumns = 3,
  maxColumns = 12,
  context = "default",
  expandHeight = false
}) {
  const thumbSize = context === "chat" ? 100 : 180;
  const containerRef = useRef(null);
  const [cols, setCols] = useState(() => {
    // Pre-calc initial columns to stabilize layout before images render
    const count = images.length;
    if (count === 0) return minColumns; // reserve minimal structure
    if (count === 1 && context === "chat") return 1;
    return Math.min(maxColumns, Math.max(minColumns, count));
  });
  const [justifyMode, setJustifyMode] = useState("start");
  const [distributeExtra, setDistributeExtra] = useState(false);
  const [loadedMap, setLoadedMap] = useState(() => new Map()); // filename -> boolean loaded

  const handleImageLoad = useCallback((key) => {
    setLoadedMap((prev) => {
      if (prev.get(key)) return prev; // already loaded
      const next = new Map(prev);
      next.set(key, true);
      return next;
    });
  }, []);

  // Dynamically compute columns for all contexts to avoid auto-fit stretching gaps in email overlay
  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const compute = () => {
      // For non-chat (email / default) we rely on CSS auto-fill; only chat needs explicit column calc & distribution logic.
      if (context !== "chat") {
        setCols(images.length || 0); // retain count for ARIA semantics; not used for template when non-chat.
        setDistributeExtra(false);
        return;
      }
      const width = el.clientWidth;
      if (!width) return;
      const perCol = thumbSize + gap; // track + gap space
      const fitCols = Math.max(1, Math.floor((width + gap) / perCol));
      // base desired columns: up to how many images we have and how many fit
      let finalCols = Math.min(images.length || 1, fitCols, maxColumns);
      // enforce minimum columns to reserve layout skeleton (except when fewer images)
      if (finalCols < minColumns && images.length >= minColumns) {
        finalCols = Math.min(fitCols, minColumns);
      }
      // chat-specific clamp
      if (context === "chat") {
        finalCols = Math.min(finalCols, 4);
      }
      if (finalCols < 1) finalCols = 1;
      setCols(finalCols);
      setJustifyMode("start");

      // Determine if there is leftover horizontal space that can't fit another column.
      // Only distribute when we're at the maximum allowed columns for the context and images exceed or meet that count.
      const contextMax = context === "chat" ? 4 : maxColumns;
      const baseWidthNeeded = finalCols * thumbSize + (finalCols - 1) * gap;
      const leftover = width - baseWidthNeeded;
      const atMaxColumns = finalCols === contextMax && images.length >= finalCols;
      // leftover must be positive but less than space needed for an additional column (perCol)
      if (atMaxColumns && leftover > 0 && leftover < perCol) {
        setDistributeExtra(true);
      } else {
        setDistributeExtra(false);
      }
    };
    compute();
    const ro = new ResizeObserver(() => compute());
    ro.observe(el);
    return () => ro.disconnect();
  }, [images.length, thumbSize, gap, minColumns, maxColumns, context]);

  const gridTemplateColumns = useMemo(() => {
    if (context === "chat") {
      if (distributeExtra) {
        return `repeat(${cols}, minmax(${thumbSize}px, 1fr))`;
      }
      return `repeat(${cols}, ${thumbSize}px)`;
    }
    // Non-chat contexts: allow browser to auto-fill columns; fixed min (thumbSize) ensures squares; tracks expand to distribute remaining space.
    return `repeat(auto-fill, minmax(${thumbSize}px, 1fr))`;
  }, [cols, thumbSize, distributeExtra, context]);
  const stableWidth = undefined; // no fixed width

  const handleKeyDown = useCallback(
    (e, idx) => {
      if (e.key === "Enter" || e.key === " ") {
        e.preventDefault();
        onToggle(idx);
      }
    },
    [onToggle]
  );

  return (
    <div
      className="local-media-grid"
      style={{
        display: "grid",
        gridTemplateColumns,
        gap,
        ...(expandHeight ? {} : { maxHeight: 420, overflowY: "auto" }),
        overflowX: "hidden",
        padding: 4,
        justifyContent: justifyMode,
        width: stableWidth
      }}
      ref={containerRef}
      role="list"
      aria-label="media thumbnails"
    >
      {images.map((img, idx) => (
        <div
          key={img.filename || idx}
          role="listitem"
          tabIndex={0}
          aria-label={img.filename || `image ${idx + 1}`}
          onClick={() => (onClick ? onClick(idx) : onToggle(idx))}
          onKeyDown={(e) => handleKeyDown(e, idx)}
          style={{
            position: "relative",
            border: img.isSelected ? "2px solid #1890ff" : "1px solid #ccc",
            outline: "none",
            borderRadius: 4,
            cursor: "pointer",
            background: "#fafafa",
            width: thumbSize,
            height: thumbSize,
            overflow: "hidden",
            boxSizing: "border-box"
          }}
        >
          {(() => {
            const key = img.filename || idx;
            const loaded = loadedMap.get(key) === true;
            return (
              <>
                {!loaded && (
                  <div
                    aria-hidden="true"
                    style={{
                      position: "absolute",
                      inset: 0,
                      background: "#f0f0f0",
                      display: "flex",
                      alignItems: "center",
                      justifyContent: "center",
                      fontSize: 10,
                      color: "#bbb"
                    }}
                  >
                    {/* simple skeleton; no shimmer to reduce cost */}…
                  </div>
                )}
                <img
                  src={img.src}
                  alt={img.filename || img.caption || "thumbnail"}
                  loading="lazy"
                  onLoad={() => handleImageLoad(key)}
                  style={{
                    width: thumbSize,
                    height: thumbSize,
                    objectFit: "cover",
                    display: "block",
                    borderRadius: 4,
                    opacity: loaded ? 1 : 0,
                    transition: "opacity .25s ease"
                  }}
                />
                {img.tags && img.tags.length > 0 && (
                  <div
                    style={{
                      position: "absolute",
                      bottom: 0,
                      left: 0,
                      right: 0,
                      padding: "2px 6px",
                      borderRadius: "0 0 4px 4px",
                      overflow: "hidden",
                      textOverflow: "ellipsis",
                      whiteSpace: "nowrap",
                      display: "flex",
                      flexWrap: "wrap",
                      gap: "4px"
                    }}
                  >
                    {img.tags.map((tag, tagIdx) => (
                      <Tag key={tagIdx} variant="outlined" color="gold" style={{ opacity: 0.8 }}>
                        {tag.value || tag.title}
                      </Tag>
                    ))}
                  </div>
                )}
              </>
            );
          })()}
          {img.isSelected && (
            <div
              aria-hidden="true"
              style={{
                position: "absolute",
                inset: 0,
                background: "rgba(24,144,255,0.45)",
                borderRadius: 4
              }}
            />
          )}
          {onClick && (
            <Checkbox
              checked={img.isSelected}
              onChange={(e) => {
                e.stopPropagation();
                onToggle(idx);
              }}
              onClick={(e) => e.stopPropagation()}
              style={{
                position: "absolute",
                top: 5,
                left: 5,
                zIndex: 2,
                opacity: img.isSelected ? 1 : 0.4,
                transition: "opacity 0.3s"
              }}
            />
          )}
        </div>
      ))}
      {/* No placeholders needed; layout uses auto-fit for non-chat or fixed columns for chat */}
    </div>
  );
}

export default LocalMediaGrid;
