/**
 * [개발 규칙]
 * - src/pages 하위의 모든 파일은 반드시 .tsx 확장자를 사용해야 합니다.
 * - 컴포넌트 파일명은 반드시 대문자로 시작하는 PascalCase 형식이어야 합니다.
 *   예) About/Ceo.tsx, main/Partners.tsx 등
 * - 단, index.tsx 파일은 예외적으로 허용됩니다 (폴더 진입점 용도).
 *
 * 해당 규칙을 어기면 lazyImport 함수에서 컴포넌트를 찾지 못하게 됩니다.
 */

/// <reference types="vite/client" />
import React, { lazy, Suspense } from 'react';

// Vite glob으로 모든 페이지 import
const pages = import.meta.glob('@/pages/**/*.tsx');

/**
 * URL 경로의 마지막 세그먼트만 PascalCase(대문자 시작)로 변환
 * 예: "about/ceo" → "about/Ceo"
 */
const toPascalCaseFilePath = (path: string): string => {
  const parts = path.split('/');
  const last = parts.pop();
  if (!last) return path;
  const fileName = last.charAt(0).toUpperCase() + last.slice(1);
  return [...parts, fileName].join('/');
};

/**
 * [lazyImport 함수] 지정한 경로의 컴포넌트를 동적으로 import합니다.
 *
 * 처리 로직:
 * - menuItems에서 온 경로는 전부 소문자입니다. (예: 'about/ceo')
 * - 마지막 파일명만 PascalCase로 바꿔서 실제 파일 위치와 일치시킵니다.
 * - Vite의 import.meta.glob()으로 가져온 pages 객체에서 해당 컴포넌트를 찾습니다.
 * - 못 찾으면 기본 fallback 컴포넌트를 반환합니다.
 */
export const lazyImport = (path: string) => {
  // 'about/ceo' → 'about/Ceo' 형태로 경로 변환
  const transformedPath = toPascalCaseFilePath(path);

  // glob으로 등록된 경로에서 해당 컴포넌트 importer 찾기
  const importer = pages[`/src/pages/${transformedPath}.tsx`];

  // importer가 존재하면 lazy 로딩 적용, 없으면 fallback 페이지
  return importer
    ? lazy(importer as () => Promise<{ default: React.ComponentType }>)
    : lazy(() => Promise.resolve({
      default: () => <div>페이지를 찾을 수 없습니다.</div>
    }));
};

/**
 * Suspense 래핑 유틸
 * - 컴포넌트를 받아 로딩 fallback을 함께 적용
 */
export const withSuspense = (
  Component: React.LazyExoticComponent<React.ComponentType>
) => (
  <Suspense fallback={<div>로딩 중...</div>}>
    <Component />
  </Suspense>
);
