import { useRef, useState, useEffect, useCallback, useMemo } from "react";
import { useLockFn } from "ahooks";
import { Virtuoso, type VirtuosoHandle } from "react-virtuoso";
import {
  getConnections,
  providerHealthCheck,
  updateProxy,
  deleteConnection,
  getGroupProxyDelays,
} from "@/services/api";
import { useProfiles } from "@/hooks/use-profiles";
import { useVerge } from "@/hooks/use-verge";
import { BaseEmpty } from "../base";
import { useRenderList } from "./use-render-list";
import { ProxyRender } from "./proxy-render";
import delayManager from "@/services/delay";
import { useTranslation } from "react-i18next";
import { ScrollTopButton } from "../layout/scroll-top-button";
import { Box, styled } from "@mui/material";
import { memo } from "react";
import { createPortal } from "react-dom";

// 将选择器组件抽离出来，避免主组件重渲染时重复创建样式
const AlphabetSelector = styled(Box)(({ theme }) => ({
  position: "fixed",
  right: 4,
  top: "50%",
  transform: "translateY(-50%)",
  display: "flex",
  flexDirection: "column",
  background: "transparent",
  zIndex: 1000,
  gap: "2px",
  // padding: "4px 2px",
  willChange: "transform",
  "&:hover": {
    background: theme.palette.background.paper,
    boxShadow: theme.shadows[2],
    borderRadius: "8px",
  },
  "& .scroll-container": {
    overflow: "hidden",
    maxHeight: "inherit",
  },
  "& .letter-container": {
    display: "flex",
    flexDirection: "column",
    gap: "2px",
    transition: "transform 0.2s ease",
  },
  "& .letter": {
    padding: "1px 4px",
    fontSize: "12px",
    cursor: "pointer",
    fontFamily:
      "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
    color: theme.palette.text.secondary,
    position: "relative",
    width: "1.5em",
    height: "1.5em",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    transition: "all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)",
    transform: "scale(1) translateZ(0)",
    backfaceVisibility: "hidden",
    borderRadius: "6px",
    "&:hover": {
      color: theme.palette.primary.main,
      transform: "scale(1.4) translateZ(0)",
      backgroundColor: theme.palette.action.hover,
    },
  },
}));

// 创建一个单独的 Tooltip 组件
const Tooltip = styled("div")(({ theme }) => ({
  position: "fixed",
  background: theme.palette.background.paper,
  padding: "4px 8px",
  borderRadius: "6px",
  boxShadow: theme.shadows[3],
  whiteSpace: "nowrap",
  fontSize: "16px",
  color: theme.palette.text.primary,
  pointerEvents: "none",
  "&::after": {
    content: '""',
    position: "absolute",
    right: "-4px",
    top: "50%",
    transform: "translateY(-50%)",
    width: 0,
    height: 0,
    borderTop: "4px solid transparent",
    borderBottom: "4px solid transparent",
    borderLeft: `4px solid ${theme.palette.background.paper}`,
  },
}));

// 抽离字母选择器子组件
const LetterItem = memo(
  ({
    name,
    onClick,
    getFirstChar,
  }: {
    name: string;
    onClick: (name: string) => void;
    getFirstChar: (str: string) => string;
  }) => {
    const [showTooltip, setShowTooltip] = useState(false);
    const letterRef = useRef<HTMLDivElement>(null);
    const [tooltipPosition, setTooltipPosition] = useState({
      top: 0,
      right: 0,
    });
    const hoverTimeoutRef = useRef<ReturnType<typeof setTimeout>>();

    const updateTooltipPosition = useCallback(() => {
      if (!letterRef.current) return;
      const rect = letterRef.current.getBoundingClientRect();
      setTooltipPosition({
        top: rect.top + rect.height / 2,
        right: window.innerWidth - rect.left + 8,
      });
    }, []);

    useEffect(() => {
      if (showTooltip) {
        updateTooltipPosition();
      }
    }, [showTooltip, updateTooltipPosition]);

    const handleMouseEnter = useCallback(() => {
      setShowTooltip(true);
      // 添加 200ms 的延迟，避免鼠标快速划过时触发滚动
      hoverTimeoutRef.current = setTimeout(() => {
        onClick(name);
      }, 100);
    }, [name, onClick]);

    const handleMouseLeave = useCallback(() => {
      setShowTooltip(false);
      if (hoverTimeoutRef.current) {
        clearTimeout(hoverTimeoutRef.current);
      }
    }, []);

    useEffect(() => {
      return () => {
        if (hoverTimeoutRef.current) {
          clearTimeout(hoverTimeoutRef.current);
        }
      };
    }, []);

    return (
      <>
        <div
          ref={letterRef}
          className="letter"
          onClick={() => onClick(name)}
          onMouseEnter={handleMouseEnter}
          onMouseLeave={handleMouseLeave}
        >
          <span>{getFirstChar(name)}</span>
        </div>
        {showTooltip &&
          createPortal(
            <Tooltip
              style={{
                top: tooltipPosition.top,
                right: tooltipPosition.right,
                transform: "translateY(-50%)",
              }}
            >
              {name}
            </Tooltip>,
            document.body,
          )}
      </>
    );
  },
);

interface Props {
  mode: string;
}

export const ProxyGroups = (props: Props) => {
  const { t } = useTranslation();
  const { mode } = props;

  const { renderList, onProxies, onHeadState } = useRenderList(mode);

  const { verge } = useVerge();
  const { current, patchCurrent } = useProfiles();
  const timeout = verge?.default_latency_timeout || 10000;

  const virtuosoRef = useRef<VirtuosoHandle>(null);
  const scrollPositionRef = useRef<Record<string, number>>({});
  const [showScrollTop, setShowScrollTop] = useState(false);
  const scrollerRef = useRef<Element | null>(null);
  const letterContainerRef = useRef<HTMLDivElement>(null);
  const alphabetSelectorRef = useRef<HTMLDivElement>(null);
  const [maxHeight, setMaxHeight] = useState("auto");

  // 使用useMemo缓存字母索引数据
  const { groupFirstLetters, letterIndexMap } = useMemo(() => {
    const letters = new Set<string>();
    const indexMap: Record<string, number> = {};

    renderList.forEach((item, index) => {
      if (item.type === 0) {
        const fullName = item.group.name;
        letters.add(fullName);
        if (!(fullName in indexMap)) {
          indexMap[fullName] = index;
        }
      }
    });

    return {
      groupFirstLetters: Array.from(letters),
      letterIndexMap: indexMap,
    };
  }, [renderList]);

  // 缓存getFirstChar函数
  const getFirstChar = useCallback((str: string) => {
    const regex = /\p{Extended_Pictographic}|\p{L}|\p{N}|./u;
    const match = str.match(regex);
    return match ? match[0] : str.charAt(0);
  }, []);

  // 从 localStorage 恢复滚动位置
  useEffect(() => {
    if (renderList.length === 0) return;

    try {
      const savedPositions = localStorage.getItem("proxy-scroll-positions");
      if (savedPositions) {
        const positions = JSON.parse(savedPositions);
        scrollPositionRef.current = positions;
        const savedPosition = positions[mode];

        if (savedPosition !== undefined) {
          setTimeout(() => {
            virtuosoRef.current?.scrollTo({
              top: savedPosition,
              behavior: "auto",
            });
          }, 100);
        }
      }
    } catch (e) {
      console.error("Error restoring scroll position:", e);
    }
  }, [mode, renderList]);

  // 使用防抖保存滚动位置
  const saveScrollPosition = useCallback(
    (scrollTop: number) => {
      try {
        scrollPositionRef.current[mode] = scrollTop;
        localStorage.setItem(
          "proxy-scroll-positions",
          JSON.stringify(scrollPositionRef.current),
        );
      } catch (e) {
        console.error("Error saving scroll position:", e);
      }
    },
    [mode],
  );

  // 优化滚动处理函数，使用防抖
  const handleScroll = useCallback(
    debounce((e: any) => {
      const scrollTop = e.target.scrollTop;
      setShowScrollTop(scrollTop > 100);
      saveScrollPosition(scrollTop);
    }, 16),
    [saveScrollPosition],
  );

  // 添加和清理滚动事件监听器
  useEffect(() => {
    const currentScroller = scrollerRef.current;
    if (currentScroller) {
      currentScroller.addEventListener("scroll", handleScroll, {
        passive: true,
      });
      return () => {
        currentScroller.removeEventListener("scroll", handleScroll);
      };
    }
  }, [handleScroll]);

  // 滚动到顶部
  const scrollToTop = useCallback(() => {
    virtuosoRef.current?.scrollTo?.({
      top: 0,
      behavior: "smooth",
    });
    saveScrollPosition(0);
  }, [saveScrollPosition]);

  // 处理字母点击，使用useCallback
  const handleLetterClick = useCallback(
    (name: string) => {
      const index = letterIndexMap[name];
      if (index !== undefined) {
        virtuosoRef.current?.scrollToIndex({
          index,
          align: "start",
          behavior: "smooth",
        });
      }
    },
    [letterIndexMap],
  );

  // 切换分组的节点代理
  const handleChangeProxy = useLockFn(
    async (group: IProxyGroupItem, proxy: IProxyItem) => {
      if (!["Selector", "URLTest", "Fallback"].includes(group.type)) return;

      const { name, now } = group;
      await updateProxy(name, proxy.name);
      onProxies();

      // 断开连接
      if (verge?.auto_close_connection) {
        getConnections().then(({ connections }) => {
          connections.forEach((conn) => {
            if (conn.chains.includes(now!)) {
              deleteConnection(conn.id);
            }
          });
        });
      }

      // 保存到selected中
      if (!current) return;
      if (!current.selected) current.selected = [];

      const index = current.selected.findIndex(
        (item) => item.name === group.name,
      );

      if (index < 0) {
        current.selected.push({ name, now: proxy.name });
      } else {
        current.selected[index] = { name, now: proxy.name };
      }
      await patchCurrent({ selected: current.selected });
    },
  );

  // 测全部延迟
  const handleCheckAll = useLockFn(async (groupName: string) => {
    const proxies = renderList
      .filter(
        (e) => e.group?.name === groupName && (e.type === 2 || e.type === 4),
      )
      .flatMap((e) => e.proxyCol || e.proxy!)
      .filter(Boolean);

    const providers = new Set(proxies.map((p) => p!.provider!).filter(Boolean));

    if (providers.size) {
      Promise.allSettled(
        [...providers].map((p) => providerHealthCheck(p)),
      ).then(() => onProxies());
    }

    const names = proxies.filter((p) => !p!.provider).map((p) => p!.name);

    await Promise.race([
      delayManager.checkListDelay(names, groupName, timeout),
      getGroupProxyDelays(groupName, delayManager.getUrl(groupName), timeout), // 查询group delays 将清除fixed(不关注调用结果)
    ]);

    onProxies();
  });

  // 滚到对应的节点
  const handleLocation = (group: IProxyGroupItem) => {
    if (!group) return;
    const { name, now } = group;

    const index = renderList.findIndex(
      (e) =>
        e.group?.name === name &&
        ((e.type === 2 && e.proxy?.name === now) ||
          (e.type === 4 && e.proxyCol?.some((p) => p.name === now))),
    );

    if (index >= 0) {
      virtuosoRef.current?.scrollToIndex?.({
        index,
        align: "center",
        behavior: "smooth",
      });
    }
  };

  // 添加滚轮事件处理函数
  const handleWheel = useCallback((e: WheelEvent) => {
    e.preventDefault();
    if (!letterContainerRef.current) return;

    const container = letterContainerRef.current;
    const scrollAmount = e.deltaY;
    const currentTransform = new WebKitCSSMatrix(container.style.transform);
    const currentY = currentTransform.m42 || 0;

    const containerHeight = container.getBoundingClientRect().height;
    const parentHeight =
      container.parentElement?.getBoundingClientRect().height || 0;
    const maxScroll = Math.max(0, containerHeight - parentHeight);

    let newY = currentY - scrollAmount;
    newY = Math.min(0, Math.max(-maxScroll, newY));

    container.style.transform = `translateY(${newY}px)`;
  }, []);

  // 添加和移除滚轮事件监听
  useEffect(() => {
    const container = letterContainerRef.current?.parentElement;
    if (container) {
      container.addEventListener("wheel", handleWheel, { passive: false });
      return () => {
        container.removeEventListener("wheel", handleWheel);
      };
    }
  }, [handleWheel]);

  // 添加窗口大小变化监听和最大高度计算
  const updateMaxHeight = useCallback(() => {
    if (!alphabetSelectorRef.current) return;

    const windowHeight = window.innerHeight;
    const bottomMargin = 60; // 底部边距
    const topMargin = bottomMargin * 2; // 顶部边距是底部的2倍
    const availableHeight = windowHeight - (topMargin + bottomMargin);

    // 调整选择器的位置，使其偏下
    const offsetPercentage =
      (((topMargin - bottomMargin) / windowHeight) * 100) / 2;
    alphabetSelectorRef.current.style.top = `calc(48% + ${offsetPercentage}vh)`;

    setMaxHeight(`${availableHeight}px`);
  }, []);

  // 监听窗口大小变化
  useEffect(() => {
    updateMaxHeight();
    window.addEventListener("resize", updateMaxHeight);
    return () => {
      window.removeEventListener("resize", updateMaxHeight);
    };
  }, [updateMaxHeight]);

  if (mode === "direct") {
    return <BaseEmpty text={t("clash_mode_direct")} />;
  }

  return (
    <div style={{ position: "relative", height: "100%" }}>
      <Virtuoso
        ref={virtuosoRef}
        style={{ height: "calc(100% - 14px)" }}
        totalCount={renderList.length}
        increaseViewportBy={{ top: 256, bottom: 256 }}
        overscan={150}
        defaultItemHeight={56}
        scrollerRef={(ref) => {
          scrollerRef.current = ref as Element;
        }}
        components={{
          Footer: () => <div style={{ height: "8px" }} />,
        }}
        itemContent={(index) => (
          <ProxyRender
            key={renderList[index].key}
            item={renderList[index]}
            indent={mode === "rule" || mode === "script"}
            onLocation={handleLocation}
            onCheckAll={handleCheckAll}
            onHeadState={onHeadState}
            onChangeProxy={handleChangeProxy}
          />
        )}
      />
      <ScrollTopButton show={showScrollTop} onClick={scrollToTop} />

      <AlphabetSelector ref={alphabetSelectorRef} style={{ maxHeight }}>
        <div className="scroll-container">
          <div ref={letterContainerRef} className="letter-container">
            {groupFirstLetters.map((name) => (
              <LetterItem
                key={name}
                name={name}
                onClick={handleLetterClick}
                getFirstChar={getFirstChar}
              />
            ))}
          </div>
        </div>
      </AlphabetSelector>
    </div>
  );
};

// 简单的防抖函数
function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number,
): (...args: Parameters<T>) => void {
  let timeout: ReturnType<typeof setTimeout> | null = null;
  return (...args: Parameters<T>) => {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
}
