import '@/app';
import { join } from 'path';
<% if (enableRouter) { %>
import routes from '<%- routesPath %>/routes';
<% } %>
<% if (!disableLoadable) { %>
import loadable from '@loadable/component';
<% } %>
import { pathToRegexp } from '@ice/runtime';
import { renderStatic } from './server';

<% if (!enableRouter) { %>
const routes = [];
<% } %>
export default async function ssgRender(options) {
  const { htmlTemplate } = options;
  const buildConfig = { 
    i18n: <%- JSON.stringify(typeof i18n === 'undefined' ? {} : i18n) %>,
    <% if (!disableLoadable) { %>
      loadableStatsPath: join(process.cwd(), '<%- outputDir %>', 'loadable-stats.json'),
    <% } %>
  };
  const htmlTemplateContent = htmlTemplate || 'global.__ICE_SERVER_HTML_TEMPLATE__';
  const pagesData = [];

  let allRoutes = routes;
  if (buildConfig.i18n.locales?.length > 0 && buildConfig.i18n.defaultLocale) {
    allRoutes = addRoutesByLocales(routes, buildConfig.i18n);
  }

  const flatRoutes = await getFlatRoutes(allRoutes);

  for (const flatRoute of flatRoutes) {
    const { path = '', getInitialProps, component, ...rest } = flatRoute;

    const keys = [];
    (pathToRegexp.default || pathToRegexp)(path, keys);
    if (keys.length > 0) {
      // don't render and export static page when the route is dynamic, e.g.: /news/:id, /*
      continue;
    }

    const initialContext = { pathname: path, location: { pathname: path } };
    const { html } = await renderStatic({ 
      htmlTemplateContent, 
      buildConfig,
      initialContext,
      getInitialProps: getInitialProps || component?.getInitialProps,
      component,
     });

    delete flatRoute.component;
    delete rest.routeWrappers;
    pagesData.push({ html, path, ...rest });
  }

  return pagesData;
};

async function getFlatRoutes(routes, parentPath = '') {
  return await routes.reduce(async (asyncPrev, originRoute) => {
    let prev = await asyncPrev;

    // must clone new object to avoid using the same route
    const route = { ...originRoute };

    const { children, path: currentPath = '', redirect } = route;
    if (children) {
      prev = prev.concat(await getFlatRoutes(children, currentPath));
    } else if (!redirect) {
      route.path = join(parentPath, currentPath);
      if (route?.component?.__LOADABLE__) {
        route.component = loadable(route.component.dynamicImport);
      }
      prev.push(route);
      // normal import component
      let getStaticPaths = route.getStaticPaths || route.component.getStaticPaths;
      if (route.component.load) {
        // dynamic import component
        const loadedPageComponent = await route.component.load();
        getStaticPaths = (loadedPageComponent.default || loadedPageComponent).getStaticPaths;
      }
      if (typeof getStaticPaths === 'function') {
        const staticPaths = await getStaticPaths();
        if (Array.isArray(staticPaths)) {
          // add static paths to render
          staticPaths.forEach((staticPath) => {
            prev.push({
              ...route,
              path: staticPath
            })
          })
        }
      }
    }
    return prev;
  }, Promise.resolve([]));
}

function addRoutesByLocales(originRoutes: any[], i18nConfig) {
  const { locales } = i18nConfig;
  if (!locales.length) {
    return originRoutes;
  }

  const modifiedRoutes = [...originRoutes];

  originRoutes.forEach((route) => {
    const { path, redirect } = route;
    if(path && !redirect && typeof path === 'string') {
      locales.forEach((prefixRouteLocale: string) => {
        modifiedRoutes.unshift({ 
          ...route, 
          path: `/${prefixRouteLocale}${path[0] === '/' ? path :`/${path}`}`,
        });
      });
    }
  });

  return modifiedRoutes;
}