import { useCallback, useMemo } from "react";
import { useLockFn } from "ahooks";
import {
  updateProxy,
  updateProxyAndSync,
  forceRefreshProxies,
  syncTrayProxySelection,
  getConnections,
  deleteConnection,
} from "@/services/cmds";
import { useProfiles } from "@/hooks/use-profiles";
import { useVerge } from "@/hooks/use-verge";

// 缓存连接清理
const cleanupConnections = async (previousProxy: string) => {
  try {
    const { connections } = await getConnections();
    const cleanupPromises = connections
      .filter((conn) => conn.chains.includes(previousProxy))
      .map((conn) => deleteConnection(conn.id));

    if (cleanupPromises.length > 0) {
      await Promise.allSettled(cleanupPromises);
      console.log(`[ProxySelection] 清理了 ${cleanupPromises.length} 个连接`);
    }
  } catch (error) {
    console.warn("[ProxySelection] 连接清理失败:", error);
  }
};

export interface ProxySelectionOptions {
  onSuccess?: () => void;
  onError?: (error: any) => void;
  enableConnectionCleanup?: boolean;
}

// 代理选择 Hook
export const useProxySelection = (options: ProxySelectionOptions = {}) => {
  const { current, patchCurrent } = useProfiles();
  const { verge } = useVerge();

  const { onSuccess, onError, enableConnectionCleanup = true } = options;

  // 缓存
  const config = useMemo(
    () => ({
      autoCloseConnection: verge?.auto_close_connection ?? false,
      enableConnectionCleanup,
    }),
    [verge?.auto_close_connection, enableConnectionCleanup],
  );

  // 切换节点
  const changeProxy = useLockFn(
    async (
      groupName: string,
      proxyName: string,
      previousProxy?: string,
      skipConfigSave: boolean = false,
    ) => {
      console.log(`[ProxySelection] 代理切换: ${groupName} -> ${proxyName}`);

      try {
        if (current && !skipConfigSave) {
          if (!current.selected) current.selected = [];

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

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

        await updateProxyAndSync(groupName, proxyName);
        console.log(
          `[ProxySelection] 代理和状态同步完成: ${groupName} -> ${proxyName}`,
        );

        onSuccess?.();

        if (
          config.enableConnectionCleanup &&
          config.autoCloseConnection &&
          previousProxy
        ) {
          setTimeout(() => cleanupConnections(previousProxy), 0);
        }
      } catch (error) {
        console.error(
          `[ProxySelection] 代理切换失败: ${groupName} -> ${proxyName}`,
          error,
        );

        try {
          await updateProxy(groupName, proxyName);
          await forceRefreshProxies();
          await syncTrayProxySelection();
          onSuccess?.();
          console.log(
            `[ProxySelection] 代理切换回退成功: ${groupName} -> ${proxyName}`,
          );
        } catch (fallbackError) {
          console.error(
            `[ProxySelection] 代理切换回退也失败: ${groupName} -> ${proxyName}`,
            fallbackError,
          );
          onError?.(fallbackError);
        }
      }
    },
  );

  const handleSelectChange = useCallback(
    (
      groupName: string,
      previousProxy?: string,
      skipConfigSave: boolean = false,
    ) =>
      (event: { target: { value: string } }) => {
        const newProxy = event.target.value;
        changeProxy(groupName, newProxy, previousProxy, skipConfigSave);
      },
    [changeProxy],
  );

  const handleProxyGroupChange = useCallback(
    (group: { name: string; now?: string }, proxy: { name: string }) => {
      changeProxy(group.name, proxy.name, group.now);
    },
    [changeProxy],
  );

  return {
    changeProxy,
    handleSelectChange,
    handleProxyGroupChange,
  };
};
