// 이 파일이 하는 일: 수준별 과정(초급/중급/고급/특급)의 강좌 카탈로그.
// courseCatalog.jsx(수습용 84강좌)와 같은 구조 — 과정마다 카테고리 1개에 12강좌.
// 학습 포인트: 헤더의 과정 셀렉트(trackContext)가 key(lv1~lv4)를 고르면
// LearnHubPage가 여기서 그 과정의 강좌 목록을 꺼내 그린다. 라우트는 App.jsx가
// LEVEL_COURSES를 map으로 돌려 자동 생성한다 — 수습용과 완전히 같은 패턴이다.
import { lazy } from 'react';

// 아이콘: Lucide(이모지 대신 SVG). 개별 import라 쓰는 것만 번들에 실린다(트리셰이킹).
import {
  Activity,
  Atom,
  Bandage,
  Blocks,
  Boxes,
  ChefHat,
  CircleCheck,
  Compass,
  Database,
  DatabaseBackup,
  Fingerprint,
  FlaskConical,
  Gauge,
  GitBranch,
  GitPullRequest,
  Globe,
  Hammer,
  Hexagon,
  Hourglass,
  Inbox,
  KeyRound,
  Layers,
  Lightbulb,
  Link,
  ListTree,
  Lock,
  MessageSquare,
  Milestone,
  Network,
  Newspaper,
  Package,
  Puzzle,
  Repeat,
  Rocket,
  Ruler,
  Search,
  Shield,
  Signpost,
  Siren,
  Sparkles,
  SquareFunction,
  Telescope,
  TrendingUp,
  TriangleAlert,
  Turtle,
  Zap,
} from 'lucide-react';

// ── 초급(lv1) → 특급(lv4) 순서, 각 12강좌 ──
const Lv1WhatIsAProgramPage = lazy(() => import('./pages/levels/Lv1WhatIsAProgramPage'));
const Lv1ComputationalThinkingPage = lazy(() => import('./pages/levels/Lv1ComputationalThinkingPage'));
const Lv1FirstHtmlPage = lazy(() => import('./pages/levels/Lv1FirstHtmlPage'));
const Lv1HtmlLinksImagesListsPage = lazy(() => import('./pages/levels/Lv1HtmlLinksImagesListsPage'));
const Lv1HowBrowsersWorkPage = lazy(() => import('./pages/levels/Lv1HowBrowsersWorkPage'));
const Lv1FirstJavascriptPage = lazy(() => import('./pages/levels/Lv1FirstJavascriptPage'));
const Lv1VariablesAndTypesPage = lazy(() => import('./pages/levels/Lv1VariablesAndTypesPage'));
const Lv1ConditionalsPage = lazy(() => import('./pages/levels/Lv1ConditionalsPage'));
const Lv1LoopsPage = lazy(() => import('./pages/levels/Lv1LoopsPage'));
const Lv1FunctionsPage = lazy(() => import('./pages/levels/Lv1FunctionsPage'));
const Lv1ReadingErrorsPage = lazy(() => import('./pages/levels/Lv1ReadingErrorsPage'));
const Lv1FirstMiniProjectPage = lazy(() => import('./pages/levels/Lv1FirstMiniProjectPage'));
const Lv2AsyncJavascriptPage = lazy(() => import('./pages/levels/Lv2AsyncJavascriptPage'));
const Lv2ArrayDataWranglingPage = lazy(() => import('./pages/levels/Lv2ArrayDataWranglingPage'));
const Lv2RestApiDesignPage = lazy(() => import('./pages/levels/Lv2RestApiDesignPage'));
const Lv2ExpressCrudPage = lazy(() => import('./pages/levels/Lv2ExpressCrudPage'));
const Lv2DbTransactionsPage = lazy(() => import('./pages/levels/Lv2DbTransactionsPage'));
const Lv2AuthSessionHashPage = lazy(() => import('./pages/levels/Lv2AuthSessionHashPage'));
const Lv2ReactStateEffectsPage = lazy(() => import('./pages/levels/Lv2ReactStateEffectsPage'));
const Lv2ReactRoutingPage = lazy(() => import('./pages/levels/Lv2ReactRoutingPage'));
const Lv2FormValidationPage = lazy(() => import('./pages/levels/Lv2FormValidationPage'));
const Lv2ErrorHandlingPatternsPage = lazy(() => import('./pages/levels/Lv2ErrorHandlingPatternsPage'));
const Lv2PracticalTestingPage = lazy(() => import('./pages/levels/Lv2PracticalTestingPage'));
const Lv2MiniProjectDeployPage = lazy(() => import('./pages/levels/Lv2MiniProjectDeployPage'));
const Lv3LayeredArchitecturePage = lazy(() => import('./pages/levels/Lv3LayeredArchitecturePage'));
const Lv3DesignPatternsPage = lazy(() => import('./pages/levels/Lv3DesignPatternsPage'));
const Lv3DbIndexingPage = lazy(() => import('./pages/levels/Lv3DbIndexingPage'));
const Lv3TransactionIsolationPage = lazy(() => import('./pages/levels/Lv3TransactionIsolationPage'));
const Lv3QueryOptimizationPage = lazy(() => import('./pages/levels/Lv3QueryOptimizationPage'));
const Lv3CachingStrategyPage = lazy(() => import('./pages/levels/Lv3CachingStrategyPage'));
const Lv3PerformanceProfilingPage = lazy(() => import('./pages/levels/Lv3PerformanceProfilingPage'));
const Lv3WebSecurityPage = lazy(() => import('./pages/levels/Lv3WebSecurityPage'));
const Lv3AuthArchitecturePage = lazy(() => import('./pages/levels/Lv3AuthArchitecturePage'));
const Lv3ObservabilityPage = lazy(() => import('./pages/levels/Lv3ObservabilityPage'));
const Lv3ZeroDowntimeDeployPage = lazy(() => import('./pages/levels/Lv3ZeroDowntimeDeployPage'));
const Lv3CodeReviewRefactoringPage = lazy(() => import('./pages/levels/Lv3CodeReviewRefactoringPage'));
const Lv4DistributedSystemsBasicsPage = lazy(() => import('./pages/levels/Lv4DistributedSystemsBasicsPage'));
const Lv4MessageQueueEventDrivenPage = lazy(() => import('./pages/levels/Lv4MessageQueueEventDrivenPage'));
const Lv4MonolithVsMicroservicesPage = lazy(() => import('./pages/levels/Lv4MonolithVsMicroservicesPage'));
const Lv4DbReplicationShardingPage = lazy(() => import('./pages/levels/Lv4DbReplicationShardingPage'));
const Lv4HighTrafficArchitecturePage = lazy(() => import('./pages/levels/Lv4HighTrafficArchitecturePage'));
const Lv4KubernetesCloudNativePage = lazy(() => import('./pages/levels/Lv4KubernetesCloudNativePage'));
const Lv4ObservabilityMetricsTracingPage = lazy(() => import('./pages/levels/Lv4ObservabilityMetricsTracingPage'));
const Lv4SreIncidentResponsePage = lazy(() => import('./pages/levels/Lv4SreIncidentResponsePage'));
const Lv4SystemDesignUrlShortenerPage = lazy(() => import('./pages/levels/Lv4SystemDesignUrlShortenerPage'));
const Lv4SystemDesignChatPage = lazy(() => import('./pages/levels/Lv4SystemDesignChatPage'));
const Lv4SystemDesignNewsfeedPage = lazy(() => import('./pages/levels/Lv4SystemDesignNewsfeedPage'));
const Lv4TechLeadershipAdrPage = lazy(() => import('./pages/levels/Lv4TechLeadershipAdrPage'));

/** key → 그 과정의 카테고리 배열 (courseCatalog의 COURSE_CATEGORIES와 같은 모양) */
export const LEVEL_TRACKS = {
  lv1: [{
    category: '초급 과정 — 코딩 첫걸음',
    desc: '코딩이 처음인 사람을 위한 12강좌 — 변수 하나에서 첫 프로그램까지.',
    items: [
      { slug: 'lv1-what-is-a-program', Icon: Lightbulb, title: '프로그램이란 무엇일까?', desc: '코드를 한 줄도 쓰기 전에, 컴퓨터에게 \'일을 시킨다\'는 게 무슨 뜻인지부터 몸으로 이해해요.', level: '입문', Component: Lv1WhatIsAProgramPage },
      { slug: 'lv1-computational-thinking', Icon: Puzzle, title: '컴퓨터처럼 생각하기: 컴퓨팅 사고', desc: '코드 없이도 기를 수 있는 문제 해결 근육 — 쪼개고, 패턴을 찾고, 순서를 세우는 법을 배워요.', level: '입문', Component: Lv1ComputationalThinkingPage },
      { slug: 'lv1-first-html', Icon: Globe, title: '나의 첫 웹페이지: HTML 첫걸음', desc: '메모장 수준의 도구만으로 브라우저에 뜨는 \'진짜 내 페이지\'를 오늘 바로 만들어요.', level: '입문', Component: Lv1FirstHtmlPage },
      { slug: 'lv1-html-links-images-lists', Icon: Blocks, title: '태그로 페이지에 살 붙이기', desc: '링크·이미지·목록·표를 넣어서 밋밋한 문서를 \'진짜 웹페이지\'처럼 만들어요.', level: '입문', Component: Lv1HtmlLinksImagesListsPage },
      { slug: 'lv1-how-browsers-work', Icon: Search, title: '브라우저는 내 코드를 어떻게 읽을까', desc: '주소창에 엔터를 치면 무슨 일이 벌어질까? 개발자 도구를 열고 웹의 뒷면을 구경해요.', level: '입문', Component: Lv1HowBrowsersWorkPage },
      { slug: 'lv1-first-javascript', Icon: Sparkles, title: '나의 첫 JavaScript', desc: '멈춰 있던 페이지가 말을 걸고 반응하기 시작해요 — 첫 코드 한 줄의 짜릿함.', level: '입문', Component: Lv1FirstJavascriptPage },
      { slug: 'lv1-variables-and-types', Icon: Package, title: '변수와 자료형: 이름 붙인 상자', desc: '값을 상자에 담아 두고 꺼내 쓰는 법 — 모든 프로그램의 가장 작은 부품을 배워요.', level: '실전', Component: Lv1VariablesAndTypesPage },
      { slug: 'lv1-conditionals', Icon: GitBranch, title: '조건문: 컴퓨터가 판단하게 하기', desc: '"만약 ~라면" 한마디로 프로그램이 갈림길에서 스스로 길을 고르게 만들어요.', level: '실전', Component: Lv1ConditionalsPage },
      { slug: 'lv1-loops', Icon: Repeat, title: '반복문: 지루한 일은 컴퓨터에게', desc: '100번 반복도 한 줄로 — 컴퓨터가 가장 잘하는 일을 시키는 법을 배워요.', level: '실전', Component: Lv1LoopsPage },
      { slug: 'lv1-functions', Icon: SquareFunction, title: '함수: 나만의 명령어 만들기', desc: '자주 쓰는 코드에 이름을 붙여 언제든 다시 부르는 법 — 진짜 개발자처럼 코드를 조립해요.', level: '실전', Component: Lv1FunctionsPage },
      { slug: 'lv1-reading-errors', Icon: Bandage, title: '에러와 친해지기: 빨간 글씨 해독법', desc: '에러는 벌점이 아니라 힌트예요. 메시지를 읽고, 원인을 좁히고, 스스로 고치는 힘을 길러요.', level: '심화', Component: Lv1ReadingErrorsPage },
      { slug: 'lv1-first-mini-project', Icon: Rocket, title: '첫 프로젝트: 숫자 맞히기 게임 만들기', desc: '지금까지 배운 전부를 총동원해 처음부터 끝까지 \'내가 만든 웹 게임\'을 완성해요.', level: '프로젝트', Component: Lv1FirstMiniProjectPage },
    ],
  }],
  lv2: [{
    category: '중급 과정 — 실전 웹 개발',
    desc: '돌아가는 웹 서비스를 직접 만드는 12강좌.',
    items: [
      { slug: 'lv2-async-javascript', Icon: Hourglass, title: '비동기 JavaScript: fetch와 Promise 정복', desc: '콜백 지옥에서 async/await까지 — 서버와 대화하는 코드를 제대로 쓰는 법', level: '실전', Component: Lv2AsyncJavascriptPage },
      { slug: 'lv2-array-data-wrangling', Icon: ChefHat, title: '배열 메서드로 데이터 요리하기', desc: 'map·filter·reduce로 API 응답을 화면에 딱 맞는 데이터로 썰고 볶는 실전 기술', level: '실전', Component: Lv2ArrayDataWranglingPage },
      { slug: 'lv2-rest-api-design', Icon: Ruler, title: 'REST API 설계: 주소와 동사의 문법', desc: '코드를 짜기 전에 API 명세부터 — 프론트와 백이 싸우지 않는 계약서 쓰는 법', level: '실전', Component: Lv2RestApiDesignPage },
      { slug: 'lv2-express-crud', Icon: Hammer, title: 'Express로 CRUD API 만들기', desc: '설계한 명세를 진짜 돌아가는 서버로 — 라우터·미들웨어·계층 분리까지 한 번에', level: '실전', Component: Lv2ExpressCrudPage },
      { slug: 'lv2-db-transactions', Icon: Database, title: 'DB 연동과 트랜잭션: 데이터가 사는 집', desc: '서버를 껐다 켜도 살아남는 데이터 — SQL 연동부터 all-or-nothing 트랜잭션까지', level: '심화', Component: Lv2DbTransactionsPage },
      { slug: 'lv2-auth-session-hash', Icon: KeyRound, title: '로그인 구현: 세션과 비밀번호 해시', desc: '비밀번호를 지키고 사용자를 기억하는 법 — 회원가입부터 보호 라우트까지 직접 구현', level: '심화', Component: Lv2AuthSessionHashPage },
      { slug: 'lv2-react-state-effects', Icon: Atom, title: 'React 상태와 이펙트 실전', desc: '상태를 \'설계\'하는 단계로 — 불변 업데이트, useEffect 데이터 페칭, 커스텀 훅까지', level: '실전', Component: Lv2ReactStateEffectsPage },
      { slug: 'lv2-react-routing', Icon: Compass, title: 'React Router로 멀티 페이지 SPA', desc: '주소창이 곧 상태다 — URL 파라미터, 중첩 레이아웃, 보호 라우트로 진짜 앱 골격 만들기', level: '실전', Component: Lv2ReactRoutingPage },
      { slug: 'lv2-form-validation', Icon: CircleCheck, title: '폼 검증: 사용자를 돕고 서버를 지키기', desc: '검증은 두 번 한다 — 프론트에서 친절하게, 서버에서 단호하게. 이중 검증 완전 정복', level: '실전', Component: Lv2FormValidationPage },
      { slug: 'lv2-error-handling-patterns', Icon: TriangleAlert, title: '에러 처리 패턴: 무너지지 않는 서비스', desc: '에러는 없앨 수 없다, 다스릴 뿐 — 백엔드 에러 미들웨어부터 프론트 폴백 UI까지', level: '심화', Component: Lv2ErrorHandlingPatternsPage },
      { slug: 'lv2-practical-testing', Icon: FlaskConical, title: '테스트 작성 실전: 자신 있게 고치는 힘', desc: '고칠 때마다 손이 떨리지 않으려면 — 단위·API·컴포넌트 테스트를 실제 코드에 붙이기', level: '심화', Component: Lv2PracticalTestingPage },
      { slug: 'lv2-mini-project-deploy', Icon: Rocket, title: '미니 프로젝트: 설계부터 배포까지', desc: '11주간 만든 조각을 하나로 — 기획·조립·배포·회고까지, 포트폴리오가 되는 첫 서비스', level: '프로젝트', Component: Lv2MiniProjectDeployPage },
    ],
  }],
  lv3: [{
    category: '고급 과정 — 아키텍처·성능·보안',
    desc: '"잘 만드는 법"을 파고드는 12강좌.',
    items: [
      { slug: 'lv3-layered-architecture', Icon: Layers, title: '레이어드 아키텍처와 관심사 분리', desc: '돌아가는 코드에서 오래 사는 코드로 — 계층으로 변경을 가두는 법.', level: '심화', Component: Lv3LayeredArchitecturePage },
      { slug: 'lv3-design-patterns', Icon: Puzzle, title: '디자인 패턴 실전', desc: '외우는 패턴 말고 쓰는 패턴 — \'이 문제엔 이 해법\'을 우리 코드로.', level: '실전', Component: Lv3DesignPatternsPage },
      { slug: 'lv3-db-indexing', Icon: ListTree, title: 'DB 인덱스와 실행계획 읽기', desc: '쿼리가 왜 느린지 감으로 찍지 말고 EXPLAIN으로 증명하는 법.', level: '심화', Component: Lv3DbIndexingPage },
      { slug: 'lv3-transaction-isolation', Icon: Lock, title: '트랜잭션과 격리 수준', desc: '동시에 밀려드는 요청 속에서 돈과 데이터를 지키는 규칙.', level: '심화', Component: Lv3TransactionIsolationPage },
      { slug: 'lv3-query-optimization', Icon: Turtle, title: 'N+1과 쿼리 최적화', desc: '목록 하나 여는데 쿼리 수백 개 — ORM이 숨긴 재앙을 걷어내기.', level: '실전', Component: Lv3QueryOptimizationPage },
      { slug: 'lv3-caching-strategy', Icon: Zap, title: '캐싱 전략 — 로컬과 Redis', desc: '빠르게 만드는 마법이 아니라, 무효화와 일관성을 감당하는 설계.', level: '심화', Component: Lv3CachingStrategyPage },
      { slug: 'lv3-performance-profiling', Icon: TrendingUp, title: '성능 측정과 프로파일링', desc: '추측하지 말고 측정하라 — 병목은 늘 예상 밖에 숨어 있다.', level: '실전', Component: Lv3PerformanceProfilingPage },
      { slug: 'lv3-web-security', Icon: Shield, title: '웹 보안 심화 — OWASP Top 10', desc: '공격자의 눈으로 내 서비스를 보고, 계층으로 방어하는 법.', level: '심화', Component: Lv3WebSecurityPage },
      { slug: 'lv3-auth-architecture', Icon: Fingerprint, title: '인증 아키텍처 — 세션 vs JWT vs OAuth', desc: '쿠키냐 토큰이냐, 무상태의 자유와 대가를 저울질하는 설계.', level: '심화', Component: Lv3AuthArchitecturePage },
      { slug: 'lv3-observability', Icon: Telescope, title: '로깅·모니터링·알림 설계', desc: '무엇이 느린가와 왜 느린가를 나눠 답하는 관측 가능성.', level: '실전', Component: Lv3ObservabilityPage },
      { slug: 'lv3-zero-downtime-deploy', Icon: Milestone, title: '무중단 배포와 롤백', desc: '배포가 무섭지 않아야 자주 배포한다 — 되돌릴 수 있게 나가는 법.', level: '실전', Component: Lv3ZeroDowntimeDeployPage },
      { slug: 'lv3-code-review-refactoring', Icon: GitPullRequest, title: '코드 리뷰와 리팩터링 전략', desc: '이 과정의 종착점 — 설계·성능·보안·운영을 리뷰 한 판에 녹여내기.', level: '프로젝트', Component: Lv3CodeReviewRefactoringPage },
    ],
  }],
  lv4: [{
    category: '특급 과정 — 대규모 시스템',
    desc: '대용량·분산 환경을 설계하는 전문가 12강좌.',
    items: [
      { slug: 'lv4-distributed-systems-basics', Icon: Network, title: '분산 시스템 첫걸음 — 왜 서버 한 대로는 안 될까', desc: '서버가 여러 대가 되는 순간 생기는 근본 문제들 — CAP, 일관성 모델, 부분 실패를 몸으로 이해합니다.', level: '심화', Component: Lv4DistributedSystemsBasicsPage },
      { slug: 'lv4-message-queue-event-driven', Icon: Inbox, title: '메시지 큐와 이벤트 드리븐 — 시스템을 느슨하게 잇는 법', desc: '동기 호출의 한계를 넘어 Kafka 같은 메시지 브로커로 시스템을 분리하고, 이벤트 중심으로 사고하는 법을 배웁니다.', level: '심화', Component: Lv4MessageQueueEventDrivenPage },
      { slug: 'lv4-monolith-vs-microservices', Icon: Boxes, title: '모놀리스 vs 마이크로서비스 — 쪼개는 것의 진짜 비용', desc: '유행이 아니라 트레이드오프로 아키텍처를 고릅니다. 서비스 경계 긋기, 분산 트랜잭션, 그리고 \'쪼개지 않을 용기\'까지.', level: '심화', Component: Lv4MonolithVsMicroservicesPage },
      { slug: 'lv4-db-replication-sharding', Icon: DatabaseBackup, title: 'DB 레플리케이션과 샤딩 — 데이터베이스를 늘리는 두 가지 축', desc: '읽기를 늘리는 복제, 쓰기를 늘리는 샤딩. 복제 지연과 핫 샤드 같은 부작용까지 다루는 데이터 확장 설계.', level: '심화', Component: Lv4DbReplicationShardingPage },
      { slug: 'lv4-high-traffic-architecture', Icon: Gauge, title: '대용량 트래픽 설계 — 밀려오는 요청 앞에서 무너지지 않기', desc: '로드밸런싱, CDN, 캐시 계층, 레이트리밋, 백프레셔까지 — 트래픽이 10배가 되어도 버티는 구조를 설계합니다.', level: '심화', Component: Lv4HighTrafficArchitecturePage },
      { slug: 'lv4-kubernetes-cloud-native', Icon: Hexagon, title: '쿠버네티스와 클라우드 네이티브 — 선언하면 알아서 굴러가는 인프라', desc: 'docker compose 다음 단계. 파드·서비스·디플로이먼트부터 오토스케일링까지, 선언형 운영의 사고방식을 익힙니다.', level: '심화', Component: Lv4KubernetesCloudNativePage },
      { slug: 'lv4-observability-metrics-tracing', Icon: Activity, title: '관측성 — 보이지 않으면 고칠 수 없다', desc: '메트릭·로그·트레이스 세 기둥으로 분산 시스템 내부를 들여다봅니다. \'요청이 어디서 느려졌나\'에 답하는 기술.', level: '심화', Component: Lv4ObservabilityMetricsTracingPage },
      { slug: 'lv4-sre-incident-response', Icon: Siren, title: 'SRE와 장애 대응 — 무너져도 빨리 일어나는 팀', desc: 'SLO와 에러 버짓으로 신뢰성을 숫자로 관리하고, 장애를 침착하게 지휘하고, 비난 없는 포스트모템으로 배우는 법.', level: '심화', Component: Lv4SreIncidentResponsePage },
      { slug: 'lv4-system-design-url-shortener', Icon: Link, title: '시스템 설계 훈련 1 — URL 단축기를 처음부터 끝까지', desc: '가장 고전적인 설계 문제로 \'요구사항 → 용량 산정 → API → 데이터 → 확장\'의 설계 루틴을 몸에 새깁니다.', level: '프로젝트', Component: Lv4SystemDesignUrlShortenerPage },
      { slug: 'lv4-system-design-chat', Icon: MessageSquare, title: '시스템 설계 훈련 2 — 실시간 채팅 시스템', desc: '연결이 오래 유지되는 실시간 시스템의 설계. WebSocket, 메시지 순서, 읽음 표시, 오프라인 동기화까지 파고듭니다.', level: '프로젝트', Component: Lv4SystemDesignChatPage },
      { slug: 'lv4-system-design-newsfeed', Icon: Newspaper, title: '시스템 설계 훈련 3 — 뉴스피드와 타임라인', desc: '푸시 vs 풀, 팬아웃, 랭킹, 셀럽 문제 — 읽기 폭발형 시스템의 끝판왕 설계로 3부작을 완성합니다.', level: '프로젝트', Component: Lv4SystemDesignNewsfeedPage },
      { slug: 'lv4-tech-leadership-adr', Icon: Signpost, title: '기술 리더십과 ADR — 결정을 설계하고 기록하는 사람', desc: '특급 과정의 마무리. 아키텍처 결정 기록(ADR), 설계 리뷰 문화, 트레이드오프 커뮤니케이션으로 팀을 움직이는 개발자가 됩니다.', level: '심화', Component: Lv4TechLeadershipAdrPage },
    ],
  }],
};

/** 모든 수준별 강좌를 평평하게 — 라우트 생성과 퀴즈 제목 조회에 쓴다. */
export const LEVEL_COURSES = Object.values(LEVEL_TRACKS)
  .flat()
  .flatMap((c) => c.items.filter((i) => i.slug));
