/* eslint-disable */
/* prettier-ignore */
// Generated by elegant-router
// Read more: https://github.com/soybeanjs/elegant-router

import type { RouteRecordRaw, RouteComponent } from 'vue-router';
import type { ElegantConstRoute } from '@elegant-router/vue';
import type { RouteMap, RouteKey, RoutePath } from '@elegant-router/types';

/**
 * transform elegant const routes to vue routes
 * @param routes elegant const routes
 * @param layouts layout components
 * @param views view components
 */
export function transformElegantRoutesToVueRoutes(
  routes: ElegantConstRoute[],
  layouts: Record<string, RouteComponent | (() => Promise<RouteComponent>)>,
  views: Record<string, RouteComponent | (() => Promise<RouteComponent>)>
) {
  return routes.flatMap(route => transformElegantRouteToVueRoute(route, layouts, views));
}

/**
 * transform elegant route to vue route
 * @param route elegant const route
 * @param layouts layout components
 * @param views view components
 */
function transformElegantRouteToVueRoute(
  route: ElegantConstRoute,
  layouts: Record<string, RouteComponent | (() => Promise<RouteComponent>)>,
  views: Record<string, RouteComponent | (() => Promise<RouteComponent>)>
) {
  const LAYOUT_PREFIX = 'layout.';
  const VIEW_PREFIX = 'view.';
  const ROUTE_DEGREE_SPLITTER = '_';
  const FIRST_LEVEL_ROUTE_COMPONENT_SPLIT = '$';

  function isLayout(component: string) {
    return component.startsWith(LAYOUT_PREFIX);
  }

  function getLayoutName(component: string) {
    const layout = component.replace(LAYOUT_PREFIX, '');

    if(!layouts[layout]) {
      throw new Error(`Layout component "${layout}" not found`);
    }

    return layout;
  }

  function isView(component: string) {
    return component.startsWith(VIEW_PREFIX);
  }

  function getViewName(component: string) {
    const view = component.replace(VIEW_PREFIX, '');

    if(!views[view]) {
      throw new Error(`View component "${view}" not found`);
    }

    return view;
  }

  function isFirstLevelRoute(item: ElegantConstRoute) {
    return !item.name.includes(ROUTE_DEGREE_SPLITTER);
  }

  function isSingleLevelRoute(item: ElegantConstRoute) {
    return isFirstLevelRoute(item) && !item.children?.length;
  }

  function getSingleLevelRouteComponent(component: string) {
    const [layout, view] = component.split(FIRST_LEVEL_ROUTE_COMPONENT_SPLIT);

    return {
      layout: getLayoutName(layout),
      view: getViewName(view)
    };
  }

  const vueRoutes: RouteRecordRaw[] = [];

  // add props: true to route
  if (route.path.includes(':') && !route.props) {
    route.props = true;
  }

  const { name, path, component, children, ...rest } = route;

  const vueRoute = { name, path, ...rest } as RouteRecordRaw;

  try {
    if (component) {
      if (isSingleLevelRoute(route)) {
        const { layout, view } = getSingleLevelRouteComponent(component);

        const singleLevelRoute: RouteRecordRaw = {
          path,
          component: layouts[layout],
          meta: {
            title: route.meta?.title || ''
          },
          children: [
            {
              name,
              path: '',
              component: views[view],
              ...rest
            } as RouteRecordRaw
          ]
        };

        return [singleLevelRoute];
      }

      if (isLayout(component)) {
        const layoutName = getLayoutName(component);

        vueRoute.component = layouts[layoutName];
      }

      if (isView(component)) {
        const viewName = getViewName(component);

        vueRoute.component = views[viewName];
      }

    }
  } catch (error: any) {
    console.error(`Error transforming route "${route.name}": ${error.toString()}`);
    return [];
  }

  // add redirect to child
  if (children?.length && !vueRoute.redirect) {
    vueRoute.redirect = {
      name: children[0].name
    };
  }

  if (children?.length) {
    const childRoutes = children.flatMap(child => transformElegantRouteToVueRoute(child, layouts, views));

    if(isFirstLevelRoute(route)) {
      vueRoute.children = childRoutes;
    } else {
      vueRoutes.push(...childRoutes);
    }
  }

  vueRoutes.unshift(vueRoute);

  return vueRoutes;
}

/**
 * map of route name and route path
 */
const routeMap: RouteMap = {
  "root": "/",
  "not-found": "/:pathMatch(.*)*",
  "403": "/403",
  "404": "/404",
  "500": "/500",
  "ai": "/ai",
  "ai_home": "/ai/home",
  "ai_jieguo": "/ai/jieguo",
  "ai_shexiang": "/ai/shexiang",
  "ai_shipin": "/ai/shipin",
  "ai_suanfa": "/ai/suanfa",
  "ai_tixing": "/ai/tixing",
  "ai_tuisong": "/ai/tuisong",
  "casting": "/casting",
  "casting_data": "/casting/data",
  "casting_data_detection": "/casting/data/detection",
  "casting_data_rainfall": "/casting/data/rainfall",
  "casting_home": "/casting/home",
  "casting_monitor": "/casting/monitor",
  "casting_monitor_entering": "/casting/monitor/entering",
  "casting_monitor_manage": "/casting/monitor/manage",
  "casting_police": "/casting/police",
  "casting_police_list": "/casting/police/list",
  "casting_police_setting": "/casting/police/setting",
  "casting_polling": "/casting/polling",
  "casting_polling_manage": "/casting/polling/manage",
  "casting_polling_result": "/casting/polling/result",
  "casting_polling_typemanage": "/casting/polling/typemanage",
  "casting_system": "/casting/system",
  "casting_system_casting": "/casting/system/casting",
  "casting_system_equipment": "/casting/system/equipment",
  "casting_system_modeldata": "/casting/system/modeldata",
  "casting_system_modelmanage": "/casting/system/modelmanage",
  "casting_system_monitor": "/casting/system/monitor",
  "cesiumdeom": "/cesiumdeom",
  "home": "/home",
  "home_police": "/home/police",
  "home_rail": "/home/rail",
  "home_rail_car": "/home/rail/car",
  "home_rail_person": "/home/rail/person",
  "iframe-page": "/iframe-page/:url",
  "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?",
  "monitoring": "/monitoring",
  "monitoring_data": "/monitoring/data",
  "monitoring_data_detection": "/monitoring/data/detection",
  "monitoring_data_rainfall": "/monitoring/data/rainfall",
  "monitoring_home": "/monitoring/home",
  "monitoring_monitor": "/monitoring/monitor",
  "monitoring_monitor_entering": "/monitoring/monitor/entering",
  "monitoring_monitor_manage": "/monitoring/monitor/manage",
  "monitoring_police": "/monitoring/police",
  "monitoring_police_list": "/monitoring/police/list",
  "monitoring_police_setting": "/monitoring/police/setting",
  "monitoring_polling": "/monitoring/polling",
  "monitoring_polling_manage": "/monitoring/polling/manage",
  "monitoring_polling_result": "/monitoring/polling/result",
  "monitoring_polling_typemanage": "/monitoring/polling/typemanage",
  "monitoring_system": "/monitoring/system",
  "monitoring_system_equipment": "/monitoring/system/equipment",
  "monitoring_system_modeldata": "/monitoring/system/modeldata",
  "monitoring_system_modelmanage": "/monitoring/system/modelmanage",
  "monitoring_system_monitor": "/monitoring/system/monitor",
  "orientation": "/orientation",
  "orientation_monitor": "/orientation/monitor",
  "orientation_monitor_facility": "/orientation/monitor/facility",
  "orientation_monitor_history": "/orientation/monitor/history",
  "orientation_video": "/orientation/video",
  "personnel": "/personnel",
  "personnel_facility": "/personnel/facility",
  "personnel_manage": "/personnel/manage",
  "personnel_manage_personnel": "/personnel/manage/personnel",
  "personnel_manage_staff": "/personnel/manage/staff",
  "personnel_manage_visitor": "/personnel/manage/visitor",
  "personnel_realtime": "/personnel/realtime",
  "personnel_sos": "/personnel/sos",
  "personnel_statistics": "/personnel/statistics",
  "personnel_statistics_distribution": "/personnel/statistics/distribution",
  "personnel_statistics_police": "/personnel/statistics/police",
  "personnel_statistics_sheet": "/personnel/statistics/sheet",
  "personnel_statistics_statis": "/personnel/statistics/statis",
  "personnel_track": "/personnel/track",
  "truck": "/truck",
  "truck_area": "/truck/area",
  "truck_area_classes": "/truck/area/classes",
  "truck_area_message": "/truck/area/message",
  "truck_car": "/truck/car",
  "truck_car_cartype": "/truck/car/cartype",
  "truck_car_fault": "/truck/car/fault",
  "truck_car_maintain": "/truck/car/maintain",
  "truck_car_message": "/truck/car/message",
  "truck_car_playback": "/truck/car/playback",
  "truck_car_track": "/truck/car/track",
  "truck_car_type": "/truck/car/type",
  "truck_safety": "/truck/safety",
  "truck_safety_report": "/truck/safety/report",
  "truck_safety_security": "/truck/safety/security",
  "truck_smart": "/truck/smart",
  "truck_vehicle": "/truck/vehicle",
  "truck_video": "/truck/video",
  "truck_video_history": "/truck/video/history",
  "truck_video_monitoring": "/truck/video/monitoring",
  "user": "/user",
  "user_bumen": "/user/bumen",
  "user_caidan": "/user/caidan",
  "user_gangwei": "/user/gangwei",
  "user_juese": "/user/juese",
  "user_log": "/user/log",
  "user_log_loginlog": "/user/log/loginlog",
  "user_log_operatelog": "/user/log/operatelog",
  "user_model": "/user/model",
  "user_model_dixing": "/user/model/dixing",
  "user_model_kuangqu": "/user/model/kuangqu",
  "user_yonghu": "/user/yonghu"
};

/**
 * get route path by route name
 * @param name route name
 */
export function getRoutePath<T extends RouteKey>(name: T) {
  return routeMap[name];
}

/**
 * get route name by route path
 * @param path route path
 */
export function getRouteName(path: RoutePath) {
  const routeEntries = Object.entries(routeMap) as [RouteKey, RoutePath][];

  const routeName: RouteKey | null = routeEntries.find(([, routePath]) => routePath === path)?.[0] || null;

  return routeName;
}
