import type { Plugin } from 'vite';

function normalizeBasePath(base: string) {
  const baseSegment = base.trim().replaceAll(/^\/+|\/+$/g, '');
  return baseSegment ? `/${baseSegment}/` : '/';
}

/**
 * 解析开发服务器入口地址的规范化跳转目标。
 *
 * @param requestUrl 当前请求地址
 * @param base Vite 应用基路径
 * @returns 需要跳转时返回目标地址，否则返回 null
 */
export function resolveBasePathRedirect(
  requestUrl: string | undefined,
  base: string,
): null | string {
  if (!requestUrl) {
    return null;
  }
  const normalizedBase = normalizeBasePath(base);
  if (normalizedBase === '/') {
    return null;
  }

  const request = new URL(requestUrl, 'http://easyflow.local');
  const baseWithoutTrailingSlash = normalizedBase.slice(0, -1);
  if (
    request.pathname !== '/' &&
    request.pathname !== baseWithoutTrailingSlash
  ) {
    return null;
  }
  return `${normalizedBase}${request.search}`;
}

/**
 * 创建开发入口规范化脚本，确保 HTML 回退先于前端路由执行跳转。
 *
 * @param base Vite 应用基路径
 * @returns 可注入 HTML 头部的同步脚本
 */
export function buildBasePathRedirectScript(base: string): string {
  const normalizedBase = normalizeBasePath(base);
  const baseWithoutTrailingSlash = normalizedBase.slice(0, -1);
  return `(()=>{const l=window.location;if(${JSON.stringify(normalizedBase)}!=="/"&&(l.pathname==="/"||l.pathname===${JSON.stringify(baseWithoutTrailingSlash)})){l.replace(${JSON.stringify(normalizedBase)}+l.search+l.hash)}})();`;
}

/**
 * 创建开发服务器入口规范化插件。
 *
 * Vite 会对浏览器导航请求提前执行 HTML 回退，因此同时使用服务端跳转
 * 与同步头部脚本，保证 `/`、`/flow` 均在路由初始化前进入 `/flow/`。
 *
 * @returns Vite 开发服务器插件
 */
export function createBasePathRedirectPlugin(): Plugin {
  let resolvedBase = '/';
  return {
    apply: 'serve',
    configResolved(config) {
      resolvedBase = config.base;
    },
    configureServer(server) {
      server.middlewares.use((request, response, next) => {
        const redirectTarget = resolveBasePathRedirect(
          request.url,
          server.config.base,
        );
        if (!redirectTarget) {
          next();
          return;
        }
        response.statusCode = 302;
        response.setHeader('Location', redirectTarget);
        response.end();
      });
    },
    enforce: 'pre',
    name: 'easyflow-base-path-redirect',
    transformIndexHtml: {
      handler() {
        return [
          {
            children: buildBasePathRedirectScript(resolvedBase),
            injectTo: 'head-prepend',
            tag: 'script',
          },
        ];
      },
      order: 'pre',
    },
  };
}
