import { CloseOutlined } from "@ant-design/icons";
import { Button } from "antd";
import { useCallback, useEffect, useRef, useState } from "react";
import { useAppSelector } from "redux/hooks";
import { darkColors, lightColors } from "ThemeConstants";

interface ProBottomSheetProps {
  isOpen: boolean;
  onClose: () => void;
  title?: string;
  children: React.ReactNode;
  height?: string | number;
  showHandle?: boolean;
  showCloseButton?: boolean;
  backdrop?: boolean;
  snapPoints?: string[] | number[];
  initialSnap?: number;
  className?: string;
  themeName?: "light" | "dark";
  contentStyle?: React.CSSProperties;
}

export function ProBottomSheet({
  isOpen,
  onClose,
  title,
  children,
  height = 500,
  showHandle = true,
  showCloseButton = true,
  backdrop = true,
  snapPoints = [500],
  initialSnap = 0,
  className = "",
  contentStyle = {},
}: ProBottomSheetProps) {
  const [currentSnap, setCurrentSnap] = useState(initialSnap);
  const [isDragging, setIsDragging] = useState(false);
  const startPosRef = useRef(0);
  const sheetRef = useRef<HTMLDivElement>(null);
  const { themeName } = useAppSelector((state) => state.theme);

  // Handle body scroll locking
  useEffect(() => {
    if (isOpen) {
      document.body.style.overflow = "hidden";
    } else {
      document.body.style.overflow = "";
    }

    return () => {
      document.body.style.overflow = "";
    };
  }, [isOpen]);

  // Close mobile keyboard when bottom sheet opens
  useEffect(() => {
    if (isOpen) {
      // Blur any active input element to close the mobile keyboard
      const activeElement = document.activeElement as HTMLElement;
      if (
        activeElement &&
        (activeElement.tagName === "INPUT" ||
          activeElement.tagName === "TEXTAREA" ||
          activeElement.isContentEditable)
      ) {
        activeElement.blur();
      }
    }
  }, [isOpen]);

  // Event handlers
  const startDrag = useCallback((clientY: number) => {
    setIsDragging(true);
    startPosRef.current = clientY;
  }, []);

  const handleDrag = useCallback(
    (clientY: number) => {
      if (!isDragging || !sheetRef.current) return;

      const deltaY = clientY - startPosRef.current;
      sheetRef.current.style.transform = `translateY(${Math.max(0, deltaY)}px)`;
    },
    [isDragging],
  );

  const endDrag = useCallback(
    (clientY: number) => {
      if (!isDragging) return;
      setIsDragging(false);

      const deltaY = clientY - startPosRef.current;
      const threshold = 50; // Reduced threshold for better responsiveness

      if (deltaY > threshold) {
        // Swipe down
        if (currentSnap > 0) {
          setCurrentSnap(currentSnap - 1);
        } else {
          onClose();
        }
      } else if (deltaY < -threshold && currentSnap < snapPoints.length - 1) {
        // Swipe up
        setCurrentSnap(currentSnap + 1);
      }

      // Reset transform
      if (sheetRef.current) {
        sheetRef.current.style.transform = "translateY(0)";
      }
    },
    [isDragging, currentSnap, snapPoints.length, onClose],
  );

  // Track if drag started from handle/header area
  const dragStartElementRef = useRef<HTMLElement | null>(null);

  // Touch event handlers
  const handleTouchStart = useCallback(
    (e: React.TouchEvent) => {
      // Only allow drag if starting from handle or header area
      const target = e.target as HTMLElement;
      const isHandle = target.closest('[style*="cursor: grab"]') !== null;
      const isHeader = target.closest('[style*="borderBottom"]') !== null;

      if (isHandle || isHeader) {
        dragStartElementRef.current = target;
        startDrag(e.touches[0].clientY);
      }
    },
    [startDrag],
  );

  const handleTouchMove = useCallback(
    (e: React.TouchEvent) => {
      // Only handle drag if it started from handle/header
      if (!isDragging || !dragStartElementRef.current) return;

      // Prevent scroll from affecting the bottom sheet
      e.preventDefault();
      handleDrag(e.touches[0].clientY);
    },
    [handleDrag, isDragging],
  );

  const handleTouchEnd = useCallback(
    (e: React.TouchEvent) => {
      if (dragStartElementRef.current) {
        endDrag(e.changedTouches[0].clientY);
        dragStartElementRef.current = null;
      }
    },
    [endDrag],
  );

  // Mouse event handlers
  const handleMouseDown = useCallback(
    (e: React.MouseEvent) => {
      startDrag(e.clientY);
    },
    [startDrag],
  );

  const handleMouseMove = useCallback(
    (e: MouseEvent) => {
      handleDrag(e.clientY);
    },
    [handleDrag],
  );

  const handleMouseUp = useCallback(
    (e: MouseEvent) => {
      endDrag(e.clientY);
    },
    [endDrag],
  );

  // Mouse event listeners
  useEffect(() => {
    if (isDragging) {
      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
    }

    return () => {
      document.removeEventListener("mousemove", handleMouseMove);
      document.removeEventListener("mouseup", handleMouseUp);
    };
  }, [isDragging, handleMouseMove, handleMouseUp]);

  // Enhanced styles with better dark themeName support
  const backdropStyle: React.CSSProperties = {
    position: "fixed",
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor:
      themeName === "dark" ? "rgba(0, 0, 0, 0.7)" : "rgba(0, 0, 0, 0.5)",
    backdropFilter: "blur(4px)",
    zIndex: 1000,
    opacity: isOpen ? 1 : 0,
    visibility: isOpen ? "visible" : "hidden",
    transition: "opacity 0.3s ease, visibility 0.3s ease",
    pointerEvents: isOpen ? "auto" : "none",
  };

  const sheetStyle: React.CSSProperties = {
    position: "fixed",
    left: 0,
    right: 0,
    bottom: 0,
    height: snapPoints[currentSnap] || height,
    backgroundColor:
      themeName === "dark" ? darkColors.bgColor : lightColors.bgColor,
    borderTopLeftRadius: 20,
    borderTopRightRadius: 20,
    boxShadow:
      themeName === "dark"
        ? "0 -8px 32px rgba(0, 0, 0, 0.6)"
        : "0 -4px 20px rgba(0, 0, 0, 0.15)",
    zIndex: 1001,
    transform: isOpen ? "translateY(0)" : "translateY(100%)",
    transition: isDragging
      ? "none"
      : "transform 0.3s cubic-bezier(0.2, 0, 0, 1), height 0.3s ease",
    display: "flex",
    flexDirection: "column",
    maxHeight: height,
    border: `1px solid ${themeName === "dark" ? "#363636" : "#e5e7eb"}`,
    borderBottom: "none",
    backdropFilter: themeName === "dark" ? "blur(12px)" : "none",
    width: "100vw",
  };

  const handleStyle: React.CSSProperties = {
    width: 40,
    height: 4,
    backgroundColor: themeName === "dark" ? "#525252" : "#d1d5db",
    borderRadius: 2,
    margin: "12px auto 8px",
    cursor: "grab",
    transition: "background-color 0.3s ease",
  };

  const headerStyle: React.CSSProperties = {
    padding: "16px 20px",
    borderBottom: `1px solid ${themeName === "dark" ? "#363636" : "#e5e7eb"}`,
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    minHeight: 60,
    backdropFilter: themeName === "dark" ? "blur(8px)" : "none",
  };

  const contentWrapperStyle: React.CSSProperties = {
    flex: 1,
    overflow: "auto",
    padding: "0 20px",
    backgroundColor:
      themeName === "dark" ? darkColors.bgColor : lightColors.bgColor,
    color: themeName === "dark" ? "#ffffff" : "#000000",
    ...contentStyle,
  };

  const closeButtonStyle: React.CSSProperties = {
    color: themeName === "dark" ? "#ffffff" : "#4D5154",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    padding: 8,
    borderRadius: "50%",
    backgroundColor: themeName === "dark" ? "rgba(54, 54, 54, 0.8)" : "#EDEEEE",
    border: `1px solid ${themeName === "dark" ? "#424242" : "transparent"}`,
    transition: "all 0.3s ease",
    cursor: "pointer",
    width: 30,
    height: 30,
  };

  const titleStyle: React.CSSProperties = {
    fontSize: 18,
    fontWeight: 600,
    color: themeName === "dark" ? "#ffffff" : "#1f2937",
    margin: 0,
    textShadow: themeName === "dark" ? "0 1px 2px rgba(0, 0, 0, 0.3)" : "none",
    transition: "color 0.3s ease",
  };

  return (
    <>
      {backdrop && <div style={backdropStyle} onClick={onClose} />}
      <div
        ref={sheetRef}
        style={sheetStyle}
        className={className}
        onTouchStart={handleTouchStart}
        onTouchMove={handleTouchMove}
        onTouchEnd={handleTouchEnd}
      >
        {showHandle && (
          <div
            style={handleStyle}
            onMouseDown={handleMouseDown}
            onMouseEnter={() => {
              if (handleStyle) {
                handleStyle.backgroundColor =
                  themeName === "dark" ? "#6b6b6b" : "#9ca3af";
              }
            }}
            onMouseLeave={() => {
              if (handleStyle) {
                handleStyle.backgroundColor =
                  themeName === "dark" ? "#525252" : "#d1d5db";
              }
            }}
          />
        )}

        {(title || showCloseButton) && (
          <div style={headerStyle}>
            <h3 style={titleStyle}>{title}</h3>
            {showCloseButton && (
              <Button
                type="text"
                icon={<CloseOutlined />}
                onClick={onClose}
                style={closeButtonStyle}
                onMouseEnter={(e) => {
                  e.currentTarget.style.backgroundColor =
                    themeName === "dark" ? "rgba(66, 66, 66, 0.9)" : "#e5e7eb";
                  e.currentTarget.style.transform = "scale(1.05)";
                }}
                onMouseLeave={(e) => {
                  e.currentTarget.style.backgroundColor =
                    themeName === "dark" ? "rgba(54, 54, 54, 0.8)" : "#EDEEEE";
                  e.currentTarget.style.transform = "scale(1)";
                }}
              />
            )}
          </div>
        )}

        <div
          style={contentWrapperStyle}
          onTouchStart={(e) => {
            // Prevent touch events in content from triggering sheet drag
            e.stopPropagation();
          }}
          onTouchMove={(e) => {
            // Allow normal scrolling in content
            e.stopPropagation();
          }}
        >
          {children}
        </div>
      </div>
    </>
  );
}
