/* eslint-disable react-refresh/only-export-components */

import { type ComponentType, lazy, type LazyExoticComponent } from 'react';

import type { PresetEditorTab } from '../components/PresetEditor';

type AppRouteComponent = LazyExoticComponent<
  ComponentType<Record<string, unknown>>
>;

export type AppRouteMatch =
  | {
      kind: 'game';
    }
  | {
      kind: 'preset-editor';
      initialTab: PresetEditorTab;
    }
  | {
      kind: 'qwen-sprite-tool';
    };

export type ResolvedAppRoute = {
  kind: AppRouteMatch['kind'];
  loadingEyebrow: string;
  loadingText: string;
  Component: AppRouteComponent;
  componentProps?: Record<string, unknown>;
};

const GameApp = lazy(() => import('../App')) as AppRouteComponent;
const PresetEditorApp = lazy(async () => {
  const module = await import('../components/PresetEditor');

  return {
    default: module.PresetEditor,
  };
}) as AppRouteComponent;
const QwenSpriteToolApp = lazy(
  () => import('../tools/QwenSpriteSheetTool'),
) as AppRouteComponent;

const PRESET_EDITOR_ROUTES: Array<{
  prefixes: string[];
  initialTab: PresetEditorTab;
}> = [
  {
    prefixes: ['/character-asset-studio', '/asset-studio'],
    initialTab: 'assets',
  },
  {
    prefixes: ['/function-editor', '/behavior-editor'],
    initialTab: 'functions',
  },
  {
    prefixes: ['/item-editor'],
    initialTab: 'items',
  },
  {
    prefixes: ['/npc-editor'],
    initialTab: 'npcs',
  },
  {
    prefixes: ['/preset-editor'],
    initialTab: 'characters',
  },
];

const QWEN_SPRITE_TOOL_PREFIXES = [
  '/qwen-sprite-tool',
  '/sprite-tool',
  '/pixelmotion-qwen',
];

function normalizeRoutePath(pathname: string) {
  const trimmedPathname = pathname.trim().toLowerCase();

  if (!trimmedPathname || trimmedPathname === '/') {
    return '/';
  }

  return trimmedPathname.replace(/\/+$/u, '');
}

function matchesRoutePrefix(pathname: string, prefix: string) {
  const normalizedPrefix = normalizeRoutePath(prefix);

  return (
    pathname === normalizedPrefix || pathname.startsWith(`${normalizedPrefix}/`)
  );
}

export function matchAppRoute(pathname: string): AppRouteMatch {
  const normalizedPathname = normalizeRoutePath(pathname);
  const isQwenSpriteToolRoute = QWEN_SPRITE_TOOL_PREFIXES.some((prefix) =>
    matchesRoutePrefix(normalizedPathname, prefix),
  );

  if (isQwenSpriteToolRoute) {
    return {
      kind: 'qwen-sprite-tool',
    };
  }

  const presetRoute = PRESET_EDITOR_ROUTES.find((route) =>
    route.prefixes.some((prefix) =>
      matchesRoutePrefix(normalizedPathname, prefix),
    ),
  );

  if (presetRoute) {
    return {
      kind: 'preset-editor',
      initialTab: presetRoute.initialTab,
    };
  }

  return {
    kind: 'game',
  };
}

export function resolveAppRoute(pathname: string): ResolvedAppRoute {
  const matchedRoute = matchAppRoute(pathname);

  if (matchedRoute.kind === 'qwen-sprite-tool') {
    return {
      kind: matchedRoute.kind,
      loadingEyebrow: '正在载入精灵表工坊',
      loadingText: '正在载入 Qwen 精灵表工具...',
      Component: QwenSpriteToolApp,
    };
  }

  if (matchedRoute.kind === 'preset-editor') {
    return {
      kind: matchedRoute.kind,
      loadingEyebrow: '正在载入编辑器',
      loadingText: '正在载入编辑器...',
      Component: PresetEditorApp,
      componentProps: {
        initialTab: matchedRoute.initialTab,
      },
    };
  }

  return {
    kind: 'game',
    loadingEyebrow: '正在载入游戏',
    loadingText: '正在载入冒险...',
    Component: GameApp,
  };
}
