import { findMatchingRoute } from '~common/routes';

import { invoke } from './invoke';

const interceptRoute = async (
  path: string,
  source: 'link-click' | 'push-state' | 'replace-state',
  url: string,
) => {
  console.log(`[preload] Intercepted ${source} and prevented default behavior:`, path);

  // 使用electron-client-ipc的dispatch方法
  try {
    await invoke('interceptRoute', { path, source, url });
  } catch (e) {
    console.error(`[preload] Route interception (${source}) call failed`, e);
  }
};
/**
 * 路由拦截器 - 负责捕获和拦截客户端路由导航
 */
export const setupRouteInterceptors = function () {
  console.log('[preload] Setting up route interceptors');

  // 存储被阻止的路径，避免pushState重复触发
  const preventedPaths = new Set<string>();

  // 拦截所有a标签的点击事件 - 针对Next.js的Link组件
  document.addEventListener(
    'click',
    async (e) => {
      const link = (e.target as HTMLElement).closest('a');
      if (link && link.href) {
        try {
          const url = new URL(link.href);

          // 检查是否为外部链接
          if (url.origin !== window.location.origin) {
            console.log(`[preload] Intercepted external link click:`, url.href);
            // 阻止默认的链接跳转行为
            e.preventDefault();
            e.stopPropagation();
            // 调用主进程处理外部链接
            await invoke('openExternalLink', url.href);
            return false; // 明确阻止后续处理
          }

          // 如果不是外部链接，则继续处理内部路由拦截逻辑
          // 使用共享配置检查是否需要拦截
          const matchedRoute = findMatchingRoute(url.pathname);

          // 如果是需要拦截的路径
          if (matchedRoute) {
            const currentPath = window.location.pathname;
            const isAlreadyInTargetPage = currentPath.startsWith(matchedRoute.pathPrefix);

            // 如果已经在目标页面下，则不拦截，让默认导航继续
            if (isAlreadyInTargetPage) return;

            // 立即阻止默认行为，避免Next.js接管路由
            e.preventDefault();
            e.stopPropagation();

            await interceptRoute(url.pathname, 'link-click', link.href);

            return false;
          }
        } catch (err) {
          // 处理可能的 URL 解析错误或其他问题
          // 例如 mailto:, tel: 等协议会导致 new URL() 抛出错误
          if (err instanceof TypeError && err.message.includes('Invalid URL')) {
            console.log(
              '[preload] Non-HTTP link clicked, allowing default browser behavior:',
              link.href,
            );
            // 对于非 HTTP/HTTPS 链接，允许浏览器默认处理
            // 不需要 e.preventDefault() 或 invoke
          } else {
            console.error('[preload] Link interception error:', err);
          }
        }
      }
    },
    true,
  );

  // 拦截 history API (用于捕获Next.js的useRouter().push/replace等)
  const originalPushState = history.pushState;
  const originalReplaceState = history.replaceState;

  // 重写pushState
  history.pushState = function () {
    const url = arguments[2];
    if (typeof url === 'string') {
      try {
        // 只处理相对路径或当前域的URL
        const parsedUrl = new URL(url, window.location.origin);

        // 使用共享配置检查是否需要拦截
        const matchedRoute = findMatchingRoute(parsedUrl.pathname);

        // 检查是否需要拦截这个导航
        if (matchedRoute) {
          // 检查当前页面是否已经在目标路径下，如果是则不拦截
          const currentPath = window.location.pathname;
          const isAlreadyInTargetPage = currentPath.startsWith(matchedRoute.pathPrefix);

          // 如果已经在目标页面下，则不拦截，让默认导航继续
          if (isAlreadyInTargetPage) {
            console.log(
              `[preload] Skip pushState interception for ${parsedUrl.pathname} because already in target page ${matchedRoute.pathPrefix}`,
            );
            return Reflect.apply(originalPushState, this, arguments);
          }

          // 将此路径添加到已阻止集合中
          preventedPaths.add(parsedUrl.pathname);

          interceptRoute(parsedUrl.pathname, 'push-state', parsedUrl.href);

          // 不执行原始的pushState操作，阻止导航发生
          // 但返回undefined以避免错误
          return;
        }
      } catch (err) {
        console.error('[preload] pushState interception error:', err);
      }
    }
    return Reflect.apply(originalPushState, this, arguments);
  };

  // 重写replaceState
  history.replaceState = function () {
    const url = arguments[2];
    if (typeof url === 'string') {
      try {
        const parsedUrl = new URL(url, window.location.origin);

        // 使用共享配置检查是否需要拦截
        const matchedRoute = findMatchingRoute(parsedUrl.pathname);

        // 检查是否需要拦截这个导航
        if (matchedRoute) {
          // 检查当前页面是否已经在目标路径下，如果是则不拦截
          const currentPath = window.location.pathname;
          const isAlreadyInTargetPage = currentPath.startsWith(matchedRoute.pathPrefix);

          // 如果已经在目标页面下，则不拦截，让默认导航继续
          if (isAlreadyInTargetPage) {
            console.log(
              `[preload] Skip replaceState interception for ${parsedUrl.pathname} because already in target page ${matchedRoute.pathPrefix}`,
            );
            return Reflect.apply(originalReplaceState, this, arguments);
          }

          // 添加到已阻止集合
          preventedPaths.add(parsedUrl.pathname);

          interceptRoute(parsedUrl.pathname, 'replace-state', parsedUrl.href);

          // 阻止导航
          return;
        }
      } catch (err) {
        console.error('[preload] replaceState interception error:', err);
      }
    }
    return Reflect.apply(originalReplaceState, this, arguments);
  };

  // 监听并拦截路由错误 - 有时Next.js会在路由错误时尝试恢复导航
  window.addEventListener(
    'error',
    function (e) {
      if (e.message && e.message.includes('navigation') && preventedPaths.size > 0) {
        console.log('[preload] Captured possible routing error, preventing default behavior');
        e.preventDefault();
      }
    },
    true,
  );

  console.log('[preload] Route interceptors setup completed');
};
