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";

// 将选择器组件抽离出来，避免主组件重渲染时重复创建样式
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: "8px 4px",
  willChange: "transform", // 优化动画性能
  "& .letter": {
    padding: "2px 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.15s cubic-bezier(0.34, 1.56, 0.64, 1)", // 稍微加快动画速度
    transform: "scale(1) translateZ(0)", // 开启GPU加速
    backfaceVisibility: "hidden", // 防止闪烁
    borderRadius: "6px",
    "&:hover": {
      color: theme.palette.primary.main,
      transform: "scale(1.2) translateZ(0)",
      backgroundColor: theme.palette.action.hover,
      "& .tooltip": {
        opacity: 1,
        transform: "translateX(0) translateZ(0)",
        visibility: "visible",
      },
    },
    "&:hover ~ .letter": {
      transform: "translateY(2px) translateZ(0)",
    },
  },
  "& .tooltip": {
    position: "absolute",
    right: "calc(100% + 8px)",
    background: theme.palette.background.paper,
    padding: "4px 8px",
    borderRadius: "6px",
    boxShadow: theme.shadows[3],
    whiteSpace: "nowrap",
    opacity: 0,
    visibility: "hidden",
    transform: "translateX(4px) translateZ(0)",
    transition: "all 0.15s cubic-bezier(0.34, 1.56, 0.64, 1)",
    fontSize: "12px",
    color: theme.palette.text.primary,
    pointerEvents: "none",
    backfaceVisibility: "hidden",
    "&::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;
  }) => (
    <div className="letter" onClick={() => onClick(name)}>
      <span>{getFirstChar(name)}</span>
      <div className="tooltip">{name}</div>
    </div>
  ),
);

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);

  // 使用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",
      });
    }
  };

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

  return (
    <div style={{ position: "relative", height: "100%" }}>
      <Virtuoso
        ref={virtuosoRef}
        style={{ height: "calc(100% - 16px)" }}
        totalCount={renderList.length}
        increaseViewportBy={{ top: 256, bottom: 256 }}
        overscan={150}
        defaultItemHeight={56}
        scrollerRef={(ref) => {
          scrollerRef.current = ref as Element;
        }}
        components={{
          Footer: () => <div style={{ height: "16px" }} />,
        }}
        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>
        {groupFirstLetters.map((name) => (
          <LetterItem
            key={name}
            name={name}
            onClick={handleLetterClick}
            getFirstChar={getFirstChar}
          />
        ))}
      </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);
  };
}
