import useSWR from "swr";
import { useEffect, useMemo, useRef, useState, useCallback } from "react";
import { getProxies } from "@/services/api";
import { useVerge } from "@/hooks/use-verge";
import { filterSort } from "./use-filter-sort";
import { useWindowWidth } from "./use-window-width";
import {
  useHeadStateNew,
  DEFAULT_STATE,
  type HeadState,
} from "./use-head-state";

export interface IRenderItem {
  // 组 ｜ head ｜ item ｜ empty | item col
  type: 0 | 1 | 2 | 3 | 4;
  key: string;
  group: IProxyGroupItem;
  proxy?: IProxyItem;
  col?: number;
  proxyCol?: IProxyItem[];
  headState?: HeadState;
}

interface ProxiesData {
  groups: IProxyGroupItem[];
  global?: IProxyGroupItem;
  proxies: any[];
}

// 缓存计算结果
const groupCache = new WeakMap<ProxiesData, Map<string, IProxyGroupItem>>();
// 用于追踪缓存的key
const cacheKeys = new Set<ProxiesData>();

export const useRenderList = (mode: string) => {
  // 添加用户交互标记
  const isUserInteracting = useRef(false);
  const interactionTimer = useRef<number | null>(null);
  // 添加上一次有效的数据缓存
  const [lastValidData, setLastValidData] = useState<ProxiesData | null>(null);
  // 添加刷新锁
  const refreshLock = useRef(false);
  const lastRenderList = useRef<IRenderItem[]>([]);

  // 组件卸载时清理
  useEffect(() => {
    return () => {
      if (interactionTimer.current) {
        clearTimeout(interactionTimer.current);
      }
      refreshLock.current = false;
      isUserInteracting.current = false;
      // 清理 WeakMap 缓存
      cacheKeys.forEach((key) => {
        groupCache.delete(key);
      });
      cacheKeys.clear();
    };
  }, []);

  // 优化数据获取函数
  const fetchProxies = useCallback(async () => {
    try {
      if (isUserInteracting.current || refreshLock.current) {
        return lastValidData;
      }
      const data = await getProxies();

      // 预处理和缓存组数据
      if (data && !groupCache.has(data)) {
        const groupMap = new Map();
        data.groups.forEach((group) => {
          groupMap.set(group.name, group);
        });
        groupCache.set(data, groupMap);
        cacheKeys.add(data);
      }

      setLastValidData(data);
      return data;
    } catch (error) {
      if (lastValidData) return lastValidData;
      throw error;
    }
  }, [lastValidData]);

  const { data: proxiesData, mutate: mutateProxies } = useSWR(
    "getProxies",
    fetchProxies,
    {
      refreshInterval: isUserInteracting.current ? 0 : 2000,
      dedupingInterval: 1000,
      revalidateOnFocus: false,
      keepPreviousData: true,
      onSuccess: (data) => {
        if (!data || isUserInteracting.current) return;

        if (proxiesData) {
          try {
            const groupMap = groupCache.get(proxiesData);
            if (!groupMap) return;

            const needUpdate = data.groups.some((group: IProxyGroupItem) => {
              const oldGroup = groupMap.get(group.name);
              return !oldGroup || oldGroup.now !== group.now;
            });

            if (!needUpdate) return;
          } catch (e) {
            console.error("Data comparison error:", e);
            return;
          }
        }
      },
    },
  );

  // 优化mutateProxies包装函数
  const wrappedMutateProxies = useCallback(async () => {
    refreshLock.current = true;
    isUserInteracting.current = true;

    if (interactionTimer.current) {
      clearTimeout(interactionTimer.current);
    }

    try {
      if (!lastValidData && proxiesData) {
        setLastValidData(proxiesData);
      }
      return await mutateProxies();
    } finally {
      interactionTimer.current = window.setTimeout(() => {
        isUserInteracting.current = false;
        refreshLock.current = false;
        interactionTimer.current = null;
      }, 2000);
    }
  }, [proxiesData, lastValidData, mutateProxies]);

  // 确保初始数据加载后更新lastValidData
  useEffect(() => {
    if (proxiesData && !lastValidData) {
      setLastValidData(proxiesData);
    }
  }, [proxiesData]);

  const { verge } = useVerge();
  const { width } = useWindowWidth();

  const col = useMemo(() => {
    const baseCol = Math.floor(verge?.proxy_layout_column || 6);
    if (baseCol >= 6 || baseCol <= 0) {
      if (width > 1450) return 4;
      if (width > 1024) return 3;
      if (width > 900) return 2;
      if (width >= 600) return 2;
      return 1;
    }
    return baseCol;
  }, [verge?.proxy_layout_column, width]);

  const [headStates, setHeadState] = useHeadStateNew();

  // 优化初始数据加载
  useEffect(() => {
    if (!proxiesData) return;
    const { groups, proxies } = proxiesData;

    if (
      (mode === "rule" && !groups.length) ||
      (mode === "global" && proxies.length < 2)
    ) {
      const timer = setTimeout(() => mutateProxies(), 500);
      return () => clearTimeout(timer);
    }
  }, [proxiesData, mode, mutateProxies]);

  // 优化渲染列表计算
  const renderList = useMemo(() => {
    const currentData = proxiesData || lastValidData;
    if (!currentData) return lastRenderList.current;

    const useRule = mode === "rule" || mode === "script";
    const renderGroups =
      (useRule && currentData.groups.length
        ? currentData.groups
        : [currentData.global!]) || [];

    const newList = renderGroups.flatMap((group: IProxyGroupItem) => {
      const headState = headStates[group.name] || DEFAULT_STATE;
      const ret: IRenderItem[] = [
        { type: 0, key: group.name, group, headState },
      ];

      if (headState?.open || !useRule) {
        const proxies = filterSort(
          group.all,
          group.name,
          headState.filterText,
          headState.sortType,
        );

        ret.push({ type: 1, key: `head-${group.name}`, group, headState });

        if (!proxies.length) {
          ret.push({ type: 3, key: `empty-${group.name}`, group, headState });
          return ret;
        }

        if (col > 1) {
          return ret.concat(
            groupList(proxies, col).map((proxyCol) => ({
              type: 4,
              key: `col-${group.name}-${proxyCol[0].name}`,
              group,
              headState,
              col,
              proxyCol,
            })),
          );
        }

        return ret.concat(
          proxies.map((proxy) => ({
            type: 2,
            key: `${group.name}-${proxy!.name}`,
            group,
            proxy,
            headState,
          })),
        );
      }
      return ret;
    });

    const filteredList = !useRule
      ? newList.slice(1)
      : newList.filter((item) => !item.group.hidden);

    lastRenderList.current = filteredList;
    return filteredList;
  }, [headStates, proxiesData, lastValidData, mode, col]);

  return {
    renderList,
    onProxies: wrappedMutateProxies,
    onHeadState: setHeadState,
  };
};

function groupList<T = any>(list: T[], size: number): T[][] {
  return list.reduce((p, n) => {
    if (!p.length) return [[n]];

    const i = p.length - 1;
    if (p[i].length < size) {
      p[i].push(n);
      return p;
    }

    p.push([n]);
    return p;
  }, [] as T[][]);
}
