import type { ExamCategory, QuestionRecord, QuestionSet, Subject } from './cbtTypes';
import { CBT_BONUS_QUESTION_SEEDS } from './cbtBonusQuestionSeeds';
import { CBT_SUBJECT_EXPANSION_QUESTION_SEEDS } from './cbtSubjectExpansionSeeds';

type QuestionSeed = Omit<QuestionRecord, 'choices' | 'sourceLabel' | 'examId' | 'type' | 'isActive'> & {
  examId?: string;
  choices: [string, string, string, string];
  sourceLabel?: string;
};

const ENGINEER_SOURCE_CORE = '비공식 재구성 문제집';
const ENGINEER_SOURCE_PRACTICE = '비공식 실전형 문제집';
const WEB_SOURCE = '공개 허용 샘플 형식';
const WEB_SOURCE_ADVANCED = '공개 허용 심화 샘플 형식';

export const CBT_EXAMS: ExamCategory[] = [
  { id: 'engineer-info', label: '정보처리기사' },
  { id: 'web-general', label: '웹 일반' },
];

export const CBT_SUBJECTS: Subject[] = [
  { id: 'algo', examId: 'engineer-info', label: '소프트웨어 설계' },
  { id: 'dev', examId: 'engineer-info', label: '소프트웨어 개발' },
  { id: 'db', examId: 'engineer-info', label: '데이터베이스 구축' },
  { id: 'programming', examId: 'engineer-info', label: '프로그래밍 언어 활용' },
  { id: 'system', examId: 'engineer-info', label: '정보시스템 구축관리' },
  { id: 'html-css', examId: 'web-general', label: 'HTML/CSS' },
];

export const CBT_QUESTION_SETS: QuestionSet[] = [
  { id: 'algo-core', examId: 'engineer-info', subjectId: 'algo', label: '설계 핵심 문제집', sourceLabel: ENGINEER_SOURCE_CORE },
  { id: 'algo-pattern', examId: 'engineer-info', subjectId: 'algo', label: '설계 분석/패턴 문제집', sourceLabel: ENGINEER_SOURCE_PRACTICE },
  { id: 'algo-quality', examId: 'engineer-info', subjectId: 'algo', label: '아키텍처/품질 문제집', sourceLabel: ENGINEER_SOURCE_PRACTICE },
  { id: 'dev-core', examId: 'engineer-info', subjectId: 'dev', label: '개발 프로세스 문제집', sourceLabel: ENGINEER_SOURCE_CORE },
  { id: 'dev-test', examId: 'engineer-info', subjectId: 'dev', label: '테스트/품질 문제집', sourceLabel: ENGINEER_SOURCE_PRACTICE },
  { id: 'dev-release', examId: 'engineer-info', subjectId: 'dev', label: '형상/배포 문제집', sourceLabel: ENGINEER_SOURCE_PRACTICE },
  { id: 'db-core', examId: 'engineer-info', subjectId: 'db', label: 'DB 모델링 문제집', sourceLabel: ENGINEER_SOURCE_CORE },
  { id: 'db-sql', examId: 'engineer-info', subjectId: 'db', label: 'SQL 활용 문제집', sourceLabel: ENGINEER_SOURCE_PRACTICE },
  { id: 'db-ops', examId: 'engineer-info', subjectId: 'db', label: '트랜잭션/운영 문제집', sourceLabel: ENGINEER_SOURCE_PRACTICE },
  {
    id: 'programming-core',
    examId: 'engineer-info',
    subjectId: 'programming',
    label: '언어 기초 문제집',
    sourceLabel: ENGINEER_SOURCE_CORE,
  },
  {
    id: 'programming-oo',
    examId: 'engineer-info',
    subjectId: 'programming',
    label: '객체지향 문제집',
    sourceLabel: ENGINEER_SOURCE_PRACTICE,
  },
  {
    id: 'programming-script',
    examId: 'engineer-info',
    subjectId: 'programming',
    label: '스크립트/자료구조 문제집',
    sourceLabel: ENGINEER_SOURCE_PRACTICE,
  },
  { id: 'system-core', examId: 'engineer-info', subjectId: 'system', label: '구축관리 핵심 문제집', sourceLabel: ENGINEER_SOURCE_CORE },
  { id: 'system-security', examId: 'engineer-info', subjectId: 'system', label: '보안/위험 문제집', sourceLabel: ENGINEER_SOURCE_PRACTICE },
  { id: 'system-infra', examId: 'engineer-info', subjectId: 'system', label: '인프라/운영 문제집', sourceLabel: ENGINEER_SOURCE_PRACTICE },
  { id: 'web-core', examId: 'web-general', subjectId: 'html-css', label: '입문 문제집', sourceLabel: WEB_SOURCE },
  { id: 'web-layout', examId: 'web-general', subjectId: 'html-css', label: '레이아웃 문제집', sourceLabel: WEB_SOURCE_ADVANCED },
  { id: 'web-accessibility', examId: 'web-general', subjectId: 'html-css', label: '접근성 문제집', sourceLabel: WEB_SOURCE_ADVANCED },
  { id: 'web-responsive', examId: 'web-general', subjectId: 'html-css', label: '반응형 문제집', sourceLabel: WEB_SOURCE_ADVANCED },
  { id: 'web-performance', examId: 'web-general', subjectId: 'html-css', label: '성능 문제집', sourceLabel: WEB_SOURCE_ADVANCED },
  { id: 'web-browser', examId: 'web-general', subjectId: 'html-css', label: '브라우저/모바일 문제집', sourceLabel: WEB_SOURCE_ADVANCED },
];

const QUESTION_SET_SOURCE_MAP = new Map(CBT_QUESTION_SETS.map((item) => [item.id, item.sourceLabel]));
const INACTIVE_QUESTION_IDS = new Set([
  'dev-core-2',
  'dev-core-2-v1',
  'dev-core-2-v2',
  'dev-core-2-v3',
  'programming-core-2',
  'programming-core-2-v1',
  'programming-core-2-v2',
  'programming-core-2-v3',
  'web-core-1',
  'web-core-3',
]);

function buildQuestion(seed: QuestionSeed): QuestionRecord {
  return {
    id: seed.id,
    examId: seed.examId ?? 'engineer-info',
    subjectId: seed.subjectId,
    setId: seed.setId,
    type: 'multiple-choice',
    body: seed.body,
    answerValue: seed.answerValue,
    explanation: seed.explanation,
    difficulty: seed.difficulty,
    sourceLabel: seed.sourceLabel ?? QUESTION_SET_SOURCE_MAP.get(seed.setId) ?? ENGINEER_SOURCE_PRACTICE,
    tags: seed.tags,
    correctRate: seed.correctRate,
    isActive: !INACTIVE_QUESTION_IDS.has(seed.id),
    choices: seed.choices.map((label, index) => ({
      value: String(index + 1),
      label,
    })),
  };
}

function rotateChoiceOrder(shift: number) {
  return [0, 1, 2, 3].map((index) => (index + shift) % 4);
}

function reorderChoices(choices: [string, string, string, string], order: number[]) {
  return order.map((index) => choices[index]) as [string, string, string, string];
}

function remapAnswerValue(answerValue: string, order: number[]) {
  const correctIndex = Number(answerValue) - 1;
  const nextIndex = order.indexOf(correctIndex);
  return String(nextIndex + 1);
}

function createVariantBody(body: string, variantIndex: number) {
  if (variantIndex === 1) {
    return `${body} (변형 문제)`;
  }

  if (variantIndex === 2) {
    return `다음 핵심 개념을 다시 묻습니다. ${body}`;
  }

  return `실전 감각 확인용 추가 문항입니다. ${body}`;
}

function createVariantExplanation(explanation: string, variantIndex: number) {
  if (variantIndex === 1) {
    return `기존 개념을 표현만 바꿔 다시 확인하는 문항입니다. ${explanation}`;
  }

  if (variantIndex === 2) {
    return `실전형으로 다시 물어도 핵심 판단 기준은 같습니다. ${explanation}`;
  }

  return `응용 문항으로 바뀌어도 같은 개념을 판단하면 됩니다. ${explanation}`;
}

const QUESTION_SEEDS: QuestionSeed[] = [
  {
    id: 'algo-core-1',
    subjectId: 'algo',
    setId: 'algo-core',
    body: '요구사항 명세에서 비기능 요구사항을 별도 항목으로 관리하는 가장 큰 이유는 무엇인가요?',
    answerValue: '2',
    explanation: '성능, 보안, 가용성 같은 품질 속성은 기능 요구사항과 다른 기준으로 검증해야 합니다.',
    difficulty: 'easy',
    tags: ['요구사항', '분석'],
    correctRate: 0.74,
    choices: ['화면 색상을 통일하려고', '품질 속성 검증 기준을 분리하려고', 'ERD를 먼저 작성하려고', '테스트 인력을 줄이려고'],
  },
  {
    id: 'algo-core-2',
    subjectId: 'algo',
    setId: 'algo-core',
    body: '유스케이스 기술서에서 기본 흐름과 예외 흐름을 함께 작성하는 주된 목적은 무엇인가요?',
    answerValue: '4',
    explanation: '정상 흐름과 예외 흐름을 함께 적어야 구현과 테스트 범위를 빠짐없이 정의할 수 있습니다.',
    difficulty: 'easy',
    tags: ['유스케이스', '분석'],
    correctRate: 0.72,
    choices: ['UI 시안을 자동 생성하려고', '코드 중복을 제거하려고', '배포 스크립트를 만들려고', '정상/예외 시나리오를 모두 검증하려고'],
  },
  {
    id: 'algo-core-3',
    subjectId: 'algo',
    setId: 'algo-core',
    body: 'UML에서 객체 간 메시지 전달 순서를 시간 흐름으로 표현하는 다이어그램은 무엇인가요?',
    answerValue: '2',
    explanation: '시퀀스 다이어그램은 시간 축을 따라 객체 간 메시지 흐름을 표현합니다.',
    difficulty: 'easy',
    tags: ['UML', '설계'],
    correctRate: 0.68,
    choices: ['클래스 다이어그램', '시퀀스 다이어그램', '컴포넌트 다이어그램', '배치 다이어그램'],
  },
  {
    id: 'algo-core-4',
    subjectId: 'algo',
    setId: 'algo-core',
    body: '자료 사전(Data Dictionary)에 포함될 내용으로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '자료 사전은 데이터 항목명, 의미, 길이, 허용값 같은 정의 정보를 정리합니다.',
    difficulty: 'medium',
    tags: ['자료사전', '분석'],
    correctRate: 0.61,
    choices: ['데이터 항목 정의와 제약 조건', '서버 CPU 사용량 이력', '디자이너 업무 분장표', '배포 승인 기록'],
  },
  {
    id: 'algo-core-5',
    subjectId: 'algo',
    setId: 'algo-core',
    body: '구조적 분석 도구인 DFD의 특징으로 가장 적절한 것은 무엇인가요?',
    answerValue: '3',
    explanation: 'DFD는 처리, 데이터 흐름, 데이터 저장소, 외부 개체를 중심으로 시스템을 표현합니다.',
    difficulty: 'medium',
    tags: ['DFD', '구조적분석'],
    correctRate: 0.58,
    choices: ['클래스 상속 구조를 그린다', '배포 장비 위치를 표현한다', '데이터 흐름과 처리를 시각화한다', '테스트 결과 통계를 적는다'],
  },
  {
    id: 'algo-pattern-1',
    subjectId: 'algo',
    setId: 'algo-pattern',
    body: '하나의 객체가 상태 변화 시 여러 객체에 자동 통지해야 할 때 적절한 디자인 패턴은 무엇인가요?',
    answerValue: '1',
    explanation: 'Observer 패턴은 주체 상태 변화를 구독자들에게 통지하는 구조입니다.',
    difficulty: 'medium',
    tags: ['패턴', '아키텍처'],
    correctRate: 0.57,
    choices: ['Observer', 'Builder', 'Bridge', 'Flyweight'],
  },
  {
    id: 'algo-pattern-2',
    subjectId: 'algo',
    setId: 'algo-pattern',
    body: '서브시스템의 복잡한 호출 절차를 단순한 하나의 인터페이스로 감추는 패턴은 무엇인가요?',
    answerValue: '4',
    explanation: 'Facade 패턴은 복잡한 하위 시스템을 단순한 접근점으로 감쌉니다.',
    difficulty: 'medium',
    tags: ['패턴', '설계'],
    correctRate: 0.55,
    choices: ['Strategy', 'Template Method', 'Prototype', 'Facade'],
  },
  {
    id: 'algo-pattern-3',
    subjectId: 'algo',
    setId: 'algo-pattern',
    body: '전략을 런타임에 교체할 수 있도록 동작 알고리즘을 캡슐화하는 패턴은 무엇인가요?',
    answerValue: '2',
    explanation: 'Strategy 패턴은 알고리즘군을 캡슐화하고 상호 교체 가능하게 합니다.',
    difficulty: 'medium',
    tags: ['패턴', '동작'],
    correctRate: 0.6,
    choices: ['Decorator', 'Strategy', 'Singleton', 'Mediator'],
  },
  {
    id: 'algo-pattern-4',
    subjectId: 'algo',
    setId: 'algo-pattern',
    body: '상위 클래스에서 처리 흐름 골격을 정하고 일부 단계를 하위 클래스가 구현하게 하는 패턴은 무엇인가요?',
    answerValue: '3',
    explanation: 'Template Method 패턴은 알고리즘의 뼈대를 상위 클래스가 정의합니다.',
    difficulty: 'hard',
    tags: ['패턴', '객체지향'],
    correctRate: 0.46,
    choices: ['Chain of Responsibility', 'Command', 'Template Method', 'Adapter'],
  },
  {
    id: 'algo-pattern-5',
    subjectId: 'algo',
    setId: 'algo-pattern',
    body: '모델, 뷰, 컨트롤러로 책임을 분리할 때 기대 효과로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: '관심사를 분리하면 변경 영향이 줄고 테스트와 유지보수가 쉬워집니다.',
    difficulty: 'easy',
    tags: ['MVC', '분리'],
    correctRate: 0.7,
    choices: ['전역 상태를 늘린다', '모든 로직을 뷰에 모은다', 'DB 연결을 없앤다', 'UI와 비즈니스 로직의 결합을 낮춘다'],
  },
  {
    id: 'algo-quality-1',
    subjectId: 'algo',
    setId: 'algo-quality',
    body: '모듈 응집도를 높이고 결합도를 낮추는 설계 원칙의 직접적인 효과는 무엇인가요?',
    answerValue: '2',
    explanation: '변경 시 영향 범위가 줄어 유지보수성이 높아집니다.',
    difficulty: 'easy',
    tags: ['품질', '모듈설계'],
    correctRate: 0.73,
    choices: ['배포 횟수를 줄인다', '변경 영향 범위를 작게 만든다', '코드 길이를 항상 절반으로 줄인다', '테스트를 생략할 수 있다'],
  },
  {
    id: 'algo-quality-2',
    subjectId: 'algo',
    setId: 'algo-quality',
    body: 'N계층 아키텍처를 적용할 때 프레젠테이션 계층과 데이터 계층을 분리하는 이유로 가장 적절한 것은 무엇인가요?',
    answerValue: '3',
    explanation: '계층 분리는 역할별 변경을 독립적으로 다루고 재사용성을 높입니다.',
    difficulty: 'medium',
    tags: ['아키텍처', '계층'],
    correctRate: 0.62,
    choices: ['DB 성능만 자동 향상하려고', '모든 계층을 한 서버에 고정하려고', '책임과 변경 지점을 분리하려고', '로그 수집을 없애려고'],
  },
  {
    id: 'algo-quality-3',
    subjectId: 'algo',
    setId: 'algo-quality',
    body: '트랜잭션이 많은 시스템에서 성능 품질 속성을 평가할 때 주요 관점으로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '응답 시간과 처리량은 성능 품질 속성의 핵심 지표입니다.',
    difficulty: 'medium',
    tags: ['품질속성', '성능'],
    correctRate: 0.59,
    choices: ['응답 시간과 처리량', '소스 폴더 개수', '개발자 수', '화면 배경색'],
  },
  {
    id: 'algo-quality-4',
    subjectId: 'algo',
    setId: 'algo-quality',
    body: '재사용 가능한 컴포넌트 설계 조건으로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: '구현 의존을 줄이고 인터페이스를 명확히 해야 다른 문맥에서도 재사용하기 쉽습니다.',
    difficulty: 'medium',
    tags: ['재사용', '컴포넌트'],
    correctRate: 0.54,
    choices: ['전역 변수에 강하게 의존한다', '화면 로직과 DB 로직을 묶는다', '환경별 상수를 코드에 박아 넣는다', '입출력 계약과 의존 범위를 명확히 한다'],
  },
  {
    id: 'algo-quality-5',
    subjectId: 'algo',
    setId: 'algo-quality',
    body: 'GoF 원칙 중 OCP(Open-Closed Principle)에 가장 가까운 설명은 무엇인가요?',
    answerValue: '2',
    explanation: '확장에는 열려 있고 기존 코드 수정에는 닫혀 있도록 설계하는 것이 OCP입니다.',
    difficulty: 'hard',
    tags: ['SOLID', '객체지향'],
    correctRate: 0.45,
    choices: ['모든 클래스는 하나의 파일에 둔다', '기능 확장은 쉽게, 기존 수정은 최소화한다', '인터페이스 구현을 금지한다', '예외 처리를 사용하지 않는다'],
  },
  {
    id: 'dev-core-1',
    subjectId: 'dev',
    setId: 'dev-core',
    body: '애자일 개발 방식의 핵심 특징으로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '애자일은 짧은 반복 주기와 지속적 피드백을 중심으로 진행합니다.',
    difficulty: 'easy',
    tags: ['애자일', '프로세스'],
    correctRate: 0.79,
    choices: ['반복 개발과 고객 피드백을 중시한다', '요구사항 변경을 원칙적으로 금지한다', '배포는 프로젝트 종료 후 1회만 한다', '문서 작성을 완전히 하지 않는다'],
  },
  {
    id: 'dev-core-2',
    subjectId: 'dev',
    setId: 'dev-core',
    body: '폭포수 모델의 설명으로 가장 적절한 것은 무엇인가요?',
    answerValue: '3',
    explanation: '폭포수 모델은 단계별 산출물을 기준으로 순차 진행하는 전통적 생명주기입니다.',
    difficulty: 'easy',
    tags: ['생명주기', '폭포수'],
    correctRate: 0.7,
    choices: ['매일 배포를 전제로 한다', '요구사항이 없어도 개발부터 한다', '단계별 순차 진행과 승인 절차를 중시한다', '프로토타입을 금지한다'],
  },
  {
    id: 'dev-core-3',
    subjectId: 'dev',
    setId: 'dev-core',
    body: '프로토타이핑 모델의 장점으로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '초기 화면과 동작을 보여 주며 요구사항을 구체화하는 데 유리합니다.',
    difficulty: 'easy',
    tags: ['프로토타입', '요구사항'],
    correctRate: 0.71,
    choices: ['코드 리뷰를 생략할 수 있다', '사용자 피드백으로 요구사항을 조기에 다듬기 쉽다', 'DB 정규화를 자동 수행한다', '테스트 케이스를 만들 필요가 없다'],
  },
  {
    id: 'dev-core-4',
    subjectId: 'dev',
    setId: 'dev-core',
    body: '스프린트 회고(Retrospective)의 목적에 가장 가까운 것은 무엇인가요?',
    answerValue: '4',
    explanation: '팀이 지난 반복 주기를 돌아보고 다음 작업 방식 개선점을 찾는 활동입니다.',
    difficulty: 'medium',
    tags: ['스크럼', '개선'],
    correctRate: 0.63,
    choices: ['릴리즈 노트를 자동 생성한다', '개발 서버를 재시작한다', '인사 평가를 확정한다', '팀의 협업 방식과 프로세스를 개선한다'],
  },
  {
    id: 'dev-core-5',
    subjectId: 'dev',
    setId: 'dev-core',
    body: '소프트웨어 공학에서 CASE 도구의 기대 효과로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '분석, 설계, 문서화, 추적성을 지원해 개발 생산성을 높입니다.',
    difficulty: 'medium',
    tags: ['CASE', '생산성'],
    correctRate: 0.58,
    choices: ['분석·설계 산출물 관리와 추적성을 높인다', '모든 코딩을 수동으로 바꾼다', '테스트를 금지한다', '요구사항 변경 이력을 삭제한다'],
  },
  {
    id: 'dev-test-1',
    subjectId: 'dev',
    setId: 'dev-test',
    body: '화이트박스 테스트 기법에 해당하는 것은 무엇인가요?',
    answerValue: '3',
    explanation: '조건 커버리지는 내부 로직 경로를 기준으로 측정하는 화이트박스 테스트입니다.',
    difficulty: 'medium',
    tags: ['테스트', '화이트박스'],
    correctRate: 0.59,
    choices: ['동등 분할', '경계값 분석', '조건 커버리지', '원인-결과 그래프'],
  },
  {
    id: 'dev-test-2',
    subjectId: 'dev',
    setId: 'dev-test',
    body: '블랙박스 테스트 기법으로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '경계값 분석은 입력 범위 경계를 중심으로 결함을 찾는 블랙박스 기법입니다.',
    difficulty: 'easy',
    tags: ['테스트', '블랙박스'],
    correctRate: 0.74,
    choices: ['기초 경로 검사', '경계값 분석', '문장 커버리지', '조건/결정 커버리지'],
  },
  {
    id: 'dev-test-3',
    subjectId: 'dev',
    setId: 'dev-test',
    body: '회귀 테스트의 주된 목적은 무엇인가요?',
    answerValue: '4',
    explanation: '수정한 코드가 기존 정상 기능에 부작용을 만들지 않았는지 확인합니다.',
    difficulty: 'easy',
    tags: ['회귀테스트', '품질'],
    correctRate: 0.77,
    choices: ['DB 백업을 자동 수행한다', '성능을 무조건 두 배로 만든다', '화면 디자인을 다시 만든다', '변경 이후 기존 기능의 이상 여부를 확인한다'],
  },
  {
    id: 'dev-test-4',
    subjectId: 'dev',
    setId: 'dev-test',
    body: '테스트 드라이버(Driver)가 필요한 경우로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '하위 모듈이 준비됐지만 이를 호출할 상위 모듈이 없을 때 드라이버를 사용합니다.',
    difficulty: 'hard',
    tags: ['통합테스트', '드라이버'],
    correctRate: 0.43,
    choices: ['상위 호출부 없이 하위 모듈을 시험해야 할 때', '운영 로그를 압축할 때', 'SQL 인덱스를 자동 생성할 때', 'UI 색상을 검사할 때'],
  },
  {
    id: 'dev-test-5',
    subjectId: 'dev',
    setId: 'dev-test',
    body: '결함 예방 관점에서 코드 리뷰의 기대 효과로 가장 적절한 것은 무엇인가요?',
    answerValue: '3',
    explanation: '실행 전에 논리 오류와 규칙 위반을 조기에 발견할 수 있습니다.',
    difficulty: 'easy',
    tags: ['코드리뷰', '품질'],
    correctRate: 0.75,
    choices: ['배포 서버를 자동 증설한다', '인프라 비용을 0으로 만든다', '결함을 조기에 발견해 수정 비용을 낮춘다', '사용자 교육을 대체한다'],
  },
  {
    id: 'dev-release-1',
    subjectId: 'dev',
    setId: 'dev-release',
    body: '형상 관리 도구를 사용하는 주된 이유로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '변경 이력과 협업 충돌을 관리하기 위해 형상 관리가 필요합니다.',
    difficulty: 'easy',
    tags: ['형상관리', '협업'],
    correctRate: 0.81,
    choices: ['UI 색상을 자동 추천하려고', '버전 이력과 변경 통제를 관리하려고', '정규화를 대신하려고', '사용자 인증을 없애려고'],
  },
  {
    id: 'dev-release-2',
    subjectId: 'dev',
    setId: 'dev-release',
    body: '지속적 통합(CI)의 설명으로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: '작은 변경을 자주 통합하고 자동 빌드·테스트로 문제를 빠르게 찾는 방식입니다.',
    difficulty: 'medium',
    tags: ['CI', '배포'],
    correctRate: 0.65,
    choices: ['개발 완료 후 1년에 1회만 병합한다', '운영 장애를 숨긴다', '테스트 없이 바로 배포한다', '작은 변경을 자주 통합하며 자동 검증한다'],
  },
  {
    id: 'dev-release-3',
    subjectId: 'dev',
    setId: 'dev-release',
    body: '릴리즈 노트에 우선 포함해야 할 내용으로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '변경 기능, 수정 버그, 주의사항을 정리해야 사용자와 운영팀이 영향을 파악할 수 있습니다.',
    difficulty: 'easy',
    tags: ['릴리즈', '운영'],
    correctRate: 0.72,
    choices: ['변경 내용과 영향 범위', '개발자 개인 일정표', '임시 메모 전체', '브라우저 즐겨찾기 목록'],
  },
  {
    id: 'dev-release-4',
    subjectId: 'dev',
    setId: 'dev-release',
    body: '브랜치 전략에서 핫픽스 브랜치를 두는 목적은 무엇인가요?',
    answerValue: '3',
    explanation: '운영 장애를 빠르게 수정해 본선 흐름과 분리하여 안정적으로 반영하기 위함입니다.',
    difficulty: 'medium',
    tags: ['브랜치', '운영'],
    correctRate: 0.57,
    choices: ['문서 폴더를 나누려고', '테스트 케이스를 삭제하려고', '운영 긴급 수정 사항을 신속히 반영하려고', '모든 개발을 중지하려고'],
  },
  {
    id: 'dev-release-5',
    subjectId: 'dev',
    setId: 'dev-release',
    body: '베이스라인(Baseline)의 의미로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '특정 시점의 승인된 산출물 집합으로 이후 변경 통제 기준이 됩니다.',
    difficulty: 'hard',
    tags: ['형상통제', '베이스라인'],
    correctRate: 0.44,
    choices: ['개발자 개인 브랜치 임시본', '승인되어 변경 기준이 되는 산출물 집합', '삭제 예정 파일 목록', '오류 로그 모음'],
  },
  {
    id: 'db-core-1',
    subjectId: 'db',
    setId: 'db-core',
    body: '개념적 데이터 모델링 단계에서 주로 사용하는 표현 요소는 무엇인가요?',
    answerValue: '4',
    explanation: '엔터티, 속성, 관계는 개념적 모델의 핵심 구성 요소입니다.',
    difficulty: 'easy',
    tags: ['ERD', '모델링'],
    correctRate: 0.76,
    choices: ['인덱스, 뷰, 트리거', '스토리지, 세션, 포트', '프로시저, 패키지, 함수', '엔터티, 속성, 관계'],
  },
  {
    id: 'db-core-2',
    subjectId: 'db',
    setId: 'db-core',
    body: '정규화의 주된 목적은 무엇인가요?',
    answerValue: '2',
    explanation: '데이터 중복과 이상 현상을 줄여 무결성을 높이는 것이 정규화의 핵심입니다.',
    difficulty: 'easy',
    tags: ['정규화', '무결성'],
    correctRate: 0.73,
    choices: ['조회 성능만 최대화한다', '중복과 이상 현상을 줄인다', '외래키를 제거한다', '모든 테이블을 하나로 합친다'],
  },
  {
    id: 'db-core-3',
    subjectId: 'db',
    setId: 'db-core',
    body: '기본키(Primary Key)의 조건으로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '기본키는 각 행을 유일하게 식별해야 하며 NULL을 허용하지 않습니다.',
    difficulty: 'easy',
    tags: ['키', '무결성'],
    correctRate: 0.78,
    choices: ['유일해야 하고 NULL을 허용하지 않는다', '중복을 허용해야 한다', '반드시 외래키여야 한다', '문자형만 사용할 수 있다'],
  },
  {
    id: 'db-core-4',
    subjectId: 'db',
    setId: 'db-core',
    body: '외래키(Foreign Key)를 두는 가장 직접적인 이유는 무엇인가요?',
    answerValue: '3',
    explanation: '테이블 간 참조 관계를 표현하고 참조 무결성을 유지하기 위함입니다.',
    difficulty: 'medium',
    tags: ['외래키', '관계'],
    correctRate: 0.66,
    choices: ['인덱스를 자동 제거하려고', '트랜잭션을 비활성화하려고', '참조 무결성을 유지하려고', '뷰를 생성하려고'],
  },
  {
    id: 'db-core-5',
    subjectId: 'db',
    setId: 'db-core',
    body: '반정규화의 적용 이유로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: '성능 요구가 높을 때 조인 비용을 줄이기 위해 제한적으로 사용합니다.',
    difficulty: 'hard',
    tags: ['반정규화', '성능'],
    correctRate: 0.48,
    choices: ['항상 무결성을 높이기 위해서', '키 제약을 없애기 위해서', '모든 중복을 제거하려고', '조회 성능 요구에 맞춰 조인 비용을 줄이려고'],
  },
  {
    id: 'db-sql-1',
    subjectId: 'db',
    setId: 'db-sql',
    body: '특정 조건을 만족하는 행만 조회할 때 사용하는 SQL 절은 무엇인가요?',
    answerValue: '2',
    explanation: 'WHERE 절은 행 필터링 조건을 지정합니다.',
    difficulty: 'easy',
    tags: ['SQL', '조회'],
    correctRate: 0.84,
    choices: ['ORDER BY', 'WHERE', 'GROUP BY', 'HAVING'],
  },
  {
    id: 'db-sql-2',
    subjectId: 'db',
    setId: 'db-sql',
    body: '집계 결과를 조건으로 필터링할 때 사용하는 절은 무엇인가요?',
    answerValue: '4',
    explanation: 'HAVING 절은 GROUP BY 이후 집계 결과에 조건을 적용합니다.',
    difficulty: 'medium',
    tags: ['SQL', '집계'],
    correctRate: 0.58,
    choices: ['FROM', 'WHERE', 'SELECT', 'HAVING'],
  },
  {
    id: 'db-sql-3',
    subjectId: 'db',
    setId: 'db-sql',
    body: '두 테이블에서 일치하는 값이 있는 행만 가져오려면 일반적으로 어떤 조인을 사용하나요?',
    answerValue: '1',
    explanation: 'INNER JOIN은 양쪽 테이블에 모두 존재하는 행을 반환합니다.',
    difficulty: 'easy',
    tags: ['SQL', '조인'],
    correctRate: 0.75,
    choices: ['INNER JOIN', 'CROSS JOIN', 'SELF JOIN', 'OUTER APPLY'],
  },
  {
    id: 'db-sql-4',
    subjectId: 'db',
    setId: 'db-sql',
    body: '중복 행을 제거하고 조회하려면 어떤 키워드를 사용하는 것이 가장 적절한가요?',
    answerValue: '3',
    explanation: 'DISTINCT는 결과 집합에서 중복 행을 제거합니다.',
    difficulty: 'easy',
    tags: ['SQL', '중복제거'],
    correctRate: 0.77,
    choices: ['UNIQUE', 'MERGE', 'DISTINCT', 'FILTER'],
  },
  {
    id: 'db-sql-5',
    subjectId: 'db',
    setId: 'db-sql',
    body: '인덱스의 주된 목적은 무엇인가요?',
    answerValue: '2',
    explanation: '인덱스는 검색 경로를 최적화해 조회 성능을 높이는 데 사용합니다.',
    difficulty: 'medium',
    tags: ['인덱스', '성능'],
    correctRate: 0.64,
    choices: ['무결성을 대신 보장한다', '조회 성능을 향상한다', '트랜잭션을 직렬화한다', '백업을 자동화한다'],
  },
  {
    id: 'db-ops-1',
    subjectId: 'db',
    setId: 'db-ops',
    body: '트랜잭션의 ACID 속성 중 원자성(Atomicity)에 해당하는 설명은 무엇인가요?',
    answerValue: '1',
    explanation: '전체 성공 또는 전체 실패만 허용하는 성질이 원자성입니다.',
    difficulty: 'medium',
    tags: ['트랜잭션', 'ACID'],
    correctRate: 0.57,
    choices: ['전부 성공하거나 전부 실패해야 한다', '항상 동시에 읽기만 가능하다', '영구 저장 장치가 필요 없다', '결과가 화면에만 남는다'],
  },
  {
    id: 'db-ops-2',
    subjectId: 'db',
    setId: 'db-ops',
    body: 'COMMIT 명령의 역할로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: 'COMMIT은 현재 트랜잭션의 변경 사항을 영구 반영합니다.',
    difficulty: 'easy',
    tags: ['트랜잭션', 'COMMIT'],
    correctRate: 0.79,
    choices: ['최근 SELECT 결과를 지운다', '인덱스를 재생성한다', '읽기 잠금을 강제로 건다', '변경 내용을 확정한다'],
  },
  {
    id: 'db-ops-3',
    subjectId: 'db',
    setId: 'db-ops',
    body: '동시성 제어가 필요한 가장 직접적인 이유는 무엇인가요?',
    answerValue: '3',
    explanation: '여러 트랜잭션이 동시에 접근할 때 갱신 손실 등 불일치를 막기 위해 필요합니다.',
    difficulty: 'medium',
    tags: ['동시성', '운영'],
    correctRate: 0.6,
    choices: ['ERD를 자동 그리려고', 'SQL 문법을 바꾸려고', '동시 접근 시 데이터 불일치를 방지하려고', '뷰를 삭제하려고'],
  },
  {
    id: 'db-ops-4',
    subjectId: 'db',
    setId: 'db-ops',
    body: '백업 전략을 세울 때 RPO가 의미하는 것으로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: 'RPO는 장애 시 허용 가능한 데이터 손실 시점을 뜻합니다.',
    difficulty: 'hard',
    tags: ['백업', '복구'],
    correctRate: 0.42,
    choices: ['서비스 복구에 걸리는 시간', '허용 가능한 데이터 손실 시점', 'CPU 사용률 상한', 'DB 접속 사용자 수'],
  },
  {
    id: 'db-ops-5',
    subjectId: 'db',
    setId: 'db-ops',
    body: '데이터베이스 로그를 활용하는 주된 목적 중 하나는 무엇인가요?',
    answerValue: '4',
    explanation: '장애 복구, 추적, 감사에 필요한 변경 이력을 확보할 수 있습니다.',
    difficulty: 'medium',
    tags: ['로그', '복구'],
    correctRate: 0.56,
    choices: ['화면 테마를 바꾸기 위해', '정규화를 취소하기 위해', '외래키를 자동 제거하기 위해', '복구와 감사 추적에 활용하기 위해'],
  },
  {
    id: 'programming-core-1',
    subjectId: 'programming',
    setId: 'programming-core',
    body: 'C 언어에서 반복 횟수가 명확한 순회에 적합한 구문은 무엇인가요?',
    answerValue: '1',
    explanation: '반복 횟수가 분명할 때는 for 문이 가장 읽기 쉽습니다.',
    difficulty: 'easy',
    tags: ['C', '반복문'],
    correctRate: 0.82,
    choices: ['for', 'switch', 'typedef', 'struct'],
  },
  {
    id: 'programming-core-2',
    subjectId: 'programming',
    setId: 'programming-core',
    body: 'C 언어에서 배열 인덱스의 시작값은 무엇인가요?',
    answerValue: '2',
    explanation: 'C 배열은 0부터 시작합니다.',
    difficulty: 'easy',
    tags: ['C', '배열'],
    correctRate: 0.86,
    choices: ['-1', '0', '1', '2'],
  },
  {
    id: 'programming-core-3',
    subjectId: 'programming',
    setId: 'programming-core',
    body: '변수의 자료형을 지정하는 주된 이유로 가장 적절한 것은 무엇인가요?',
    answerValue: '3',
    explanation: '자료형은 저장 가능한 값의 범위와 연산 방식을 결정합니다.',
    difficulty: 'easy',
    tags: ['자료형', '기초'],
    correctRate: 0.75,
    choices: ['주석을 줄이기 위해', '함수 수를 늘리기 위해', '메모리 표현과 연산 규칙을 정하기 위해', '예외 처리를 대신하기 위해'],
  },
  {
    id: 'programming-core-4',
    subjectId: 'programming',
    setId: 'programming-core',
    body: '함수의 반환값이 없음을 나타낼 때 C 계열 언어에서 주로 사용하는 키워드는 무엇인가요?',
    answerValue: '4',
    explanation: 'void는 반환값이 없음을 의미합니다.',
    difficulty: 'easy',
    tags: ['함수', 'C'],
    correctRate: 0.8,
    choices: ['null', 'empty', 'return', 'void'],
  },
  {
    id: 'programming-core-5',
    subjectId: 'programming',
    setId: 'programming-core',
    body: '포인터를 사용할 때 주의해야 할 점으로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '초기화되지 않은 포인터 역참조는 오류와 비정상 동작을 유발할 수 있습니다.',
    difficulty: 'medium',
    tags: ['포인터', '메모리'],
    correctRate: 0.55,
    choices: ['정수형보다 항상 빠르다', '유효하지 않은 주소를 참조하지 않도록 해야 한다', '배열보다 메모리를 더 적게 쓴다', '해제 후에도 안전하게 재사용된다'],
  },
  {
    id: 'programming-oo-1',
    subjectId: 'programming',
    setId: 'programming-oo',
    body: 'Java에서 상속받은 메서드를 하위 클래스에서 다시 구현하는 개념은 무엇인가요?',
    answerValue: '4',
    explanation: '오버라이딩은 상속받은 메서드를 재정의하는 것입니다.',
    difficulty: 'easy',
    tags: ['Java', '객체지향'],
    correctRate: 0.8,
    choices: ['오버로딩', '캡슐화', '추상화', '오버라이딩'],
  },
  {
    id: 'programming-oo-2',
    subjectId: 'programming',
    setId: 'programming-oo',
    body: '캡슐화의 목적에 가장 가까운 설명은 무엇인가요?',
    answerValue: '1',
    explanation: '내부 구현을 숨기고 필요한 인터페이스만 노출해 객체의 일관성을 지킵니다.',
    difficulty: 'easy',
    tags: ['객체지향', '캡슐화'],
    correctRate: 0.74,
    choices: ['데이터와 메서드를 묶고 접근을 통제한다', '모든 속성을 public으로 공개한다', '클래스를 하나만 허용한다', '상속을 금지한다'],
  },
  {
    id: 'programming-oo-3',
    subjectId: 'programming',
    setId: 'programming-oo',
    body: '다형성의 장점으로 가장 적절한 것은 무엇인가요?',
    answerValue: '3',
    explanation: '공통 인터페이스로 다양한 구현 객체를 동일하게 다룰 수 있습니다.',
    difficulty: 'medium',
    tags: ['객체지향', '다형성'],
    correctRate: 0.63,
    choices: ['자료형을 하나로 제한한다', '상속을 사용하지 않게 한다', '인터페이스 중심 확장에 유리하다', '예외 처리를 제거한다'],
  },
  {
    id: 'programming-oo-4',
    subjectId: 'programming',
    setId: 'programming-oo',
    body: '추상 클래스의 설명으로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '공통 기능과 추상 메서드를 함께 둘 수 있어 기본 골격을 제공하는 데 적합합니다.',
    difficulty: 'medium',
    tags: ['Java', '추상클래스'],
    correctRate: 0.58,
    choices: ['객체를 절대 만들 수 없는 인터페이스와 같다', '공통 구현과 추상 메서드를 함께 정의할 수 있다', '상속을 받을 수 없다', '필드를 선언할 수 없다'],
  },
  {
    id: 'programming-oo-5',
    subjectId: 'programming',
    setId: 'programming-oo',
    body: '오버로딩의 조건으로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: '같은 이름의 메서드라도 매개변수 목록이 달라야 오버로딩이 성립합니다.',
    difficulty: 'hard',
    tags: ['객체지향', '오버로딩'],
    correctRate: 0.47,
    choices: ['반환형만 달라야 한다', '접근제어자만 달라야 한다', '상속 관계여야 한다', '매개변수 개수나 타입이 달라야 한다'],
  },
  {
    id: 'programming-script-1',
    subjectId: 'programming',
    setId: 'programming-script',
    body: 'Python 리스트 내포(List Comprehension)의 장점으로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '반복 결과를 간결하게 생성해 가독성과 작성 효율을 높일 수 있습니다.',
    difficulty: 'medium',
    tags: ['Python', '문법'],
    correctRate: 0.65,
    choices: ['예외 처리를 자동 수행한다', '반복 결과 생성을 간결하게 표현한다', '모든 자료형을 집합으로 바꾼다', '반드시 실행 속도를 두 배로 만든다'],
  },
  {
    id: 'programming-script-2',
    subjectId: 'programming',
    setId: 'programming-script',
    body: '스택(Stack)의 특징으로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '스택은 가장 나중에 들어온 요소가 가장 먼저 나오는 LIFO 구조입니다.',
    difficulty: 'easy',
    tags: ['자료구조', '스택'],
    correctRate: 0.79,
    choices: ['후입선출 구조이다', '항상 정렬된 상태를 유지한다', '양쪽 끝에서만 삽입한다', '인덱스로만 접근 가능하다'],
  },
  {
    id: 'programming-script-3',
    subjectId: 'programming',
    setId: 'programming-script',
    body: '큐(Queue)의 설명으로 가장 적절한 것은 무엇인가요?',
    answerValue: '3',
    explanation: '큐는 먼저 들어온 데이터가 먼저 나가는 FIFO 구조입니다.',
    difficulty: 'easy',
    tags: ['자료구조', '큐'],
    correctRate: 0.81,
    choices: ['재귀 호출만 저장한다', '마지막 입력만 남긴다', '선입선출 구조이다', '해시 충돌을 제거한다'],
  },
  {
    id: 'programming-script-4',
    subjectId: 'programming',
    setId: 'programming-script',
    body: '해시 테이블의 평균적인 탐색 성능이 좋은 이유로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: '키를 해시 함수로 변환해 바로 접근 위치를 찾기 때문에 평균 탐색이 빠릅니다.',
    difficulty: 'medium',
    tags: ['자료구조', '해시'],
    correctRate: 0.56,
    choices: ['항상 정렬된 트리이기 때문에', '메모리를 전혀 쓰지 않기 때문에', '재귀만 사용하기 때문에', '키를 인덱스로 변환해 직접 접근하기 때문에'],
  },
  {
    id: 'programming-script-5',
    subjectId: 'programming',
    setId: 'programming-script',
    body: '재귀 함수 작성 시 필수적으로 고려해야 할 요소는 무엇인가요?',
    answerValue: '2',
    explanation: '재귀 종료 조건이 없으면 무한 호출이 발생할 수 있습니다.',
    difficulty: 'medium',
    tags: ['재귀', '알고리즘'],
    correctRate: 0.61,
    choices: ['반드시 전역 변수를 사용한다', '종료 조건을 명확히 둔다', '반복문을 함께 쓰지 않는다', '메모리 해제를 생략한다'],
  },
  {
    id: 'system-core-1',
    subjectId: 'system',
    setId: 'system-core',
    body: '프로젝트 일정 관리에서 주 경로(Critical Path)의 의미로 가장 적절한 것은 무엇인가요?',
    answerValue: '3',
    explanation: '지연되면 전체 프로젝트 종료일이 늦어지는 작업 경로를 말합니다.',
    difficulty: 'medium',
    tags: ['프로젝트관리', '일정'],
    correctRate: 0.6,
    choices: ['가장 비용이 낮은 작업 목록', '가장 쉬운 테스트 항목', '전체 일정에 직접 영향을 주는 핵심 경로', '가장 먼저 끝난 작업 모음'],
  },
  {
    id: 'system-core-2',
    subjectId: 'system',
    setId: 'system-core',
    body: 'WBS(Work Breakdown Structure)의 주된 목적은 무엇인가요?',
    answerValue: '1',
    explanation: '프로젝트 범위를 작업 단위로 나눠 계획, 책임, 일정 관리를 쉽게 합니다.',
    difficulty: 'easy',
    tags: ['프로젝트관리', 'WBS'],
    correctRate: 0.77,
    choices: ['작업 범위를 세분화해 관리하기 위해', '데이터 정규화를 수행하기 위해', 'UI 시안을 만들기 위해', '방화벽 규칙을 설정하기 위해'],
  },
  {
    id: 'system-core-3',
    subjectId: 'system',
    setId: 'system-core',
    body: '가용성을 높이기 위한 시스템 구성 방식으로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '중요 자원을 이중화하면 장애 시 대체 경로를 제공할 수 있습니다.',
    difficulty: 'easy',
    tags: ['가용성', '운영'],
    correctRate: 0.79,
    choices: ['단일 서버만 유지한다', '중요 구성 요소를 이중화한다', '백업을 중지한다', '권한 관리를 해제한다'],
  },
  {
    id: 'system-core-4',
    subjectId: 'system',
    setId: 'system-core',
    body: 'SLA(Service Level Agreement)에 포함될 항목으로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: '가용성 목표, 응답 시간, 장애 대응 기준 등 서비스 수준 약속이 포함됩니다.',
    difficulty: 'medium',
    tags: ['SLA', '운영'],
    correctRate: 0.55,
    choices: ['개발자의 취미 목록', '테스트용 임시 비밀번호', '디자이너 색상 선호도', '서비스 가용성과 지원 기준'],
  },
  {
    id: 'system-core-5',
    subjectId: 'system',
    setId: 'system-core',
    body: '형상 통제 절차의 설명으로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '변경 요청을 검토하고 승인된 항목만 기준선에 반영하는 활동입니다.',
    difficulty: 'medium',
    tags: ['형상통제', '운영'],
    correctRate: 0.59,
    choices: ['변경 요청과 승인 이력을 관리하며 반영한다', '배포 후 이력을 모두 삭제한다', '사용자 테스트를 생략한다', '장애 기록을 외부에 공개한다'],
  },
  {
    id: 'system-security-1',
    subjectId: 'system',
    setId: 'system-security',
    body: '위험 대응 전략으로 보기 어려운 것은 무엇인가요?',
    answerValue: '3',
    explanation: '회피, 완화, 전가, 수용이 일반적이며 은폐는 적절한 전략이 아닙니다.',
    difficulty: 'medium',
    tags: ['위험관리', '보안'],
    correctRate: 0.58,
    choices: ['회피', '완화', '은폐', '전가'],
  },
  {
    id: 'system-security-2',
    subjectId: 'system',
    setId: 'system-security',
    body: '기밀성(Confidentiality)을 지키기 위한 통제로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '권한 통제와 암호화는 비인가 접근을 막아 기밀성을 높입니다.',
    difficulty: 'easy',
    tags: ['보안', '기밀성'],
    correctRate: 0.76,
    choices: ['로그를 모두 삭제한다', '권한 통제와 암호화를 적용한다', '서버 시간을 수동으로 고정한다', '백업 파일을 공개 폴더에 둔다'],
  },
  {
    id: 'system-security-3',
    subjectId: 'system',
    setId: 'system-security',
    body: '무결성(Integrity) 침해 사례로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: '인가되지 않은 데이터 변경은 무결성 침해에 해당합니다.',
    difficulty: 'medium',
    tags: ['보안', '무결성'],
    correctRate: 0.62,
    choices: ['합법적 백업 수행', '서버 점검 공지 게시', '로그인 페이지 접속 지연', '허가되지 않은 주문 데이터 수정'],
  },
  {
    id: 'system-security-4',
    subjectId: 'system',
    setId: 'system-security',
    body: '접근 통제 원칙 중 최소 권한 원칙의 의미로 가장 적절한 것은 무엇인가요?',
    answerValue: '1',
    explanation: '업무 수행에 필요한 최소 권한만 부여해야 사고 범위를 줄일 수 있습니다.',
    difficulty: 'easy',
    tags: ['보안', '접근통제'],
    correctRate: 0.78,
    choices: ['필요한 최소 수준의 권한만 부여한다', '모든 사용자에게 관리자 권한을 준다', '권한 검토를 하지 않는다', '비밀번호를 공유한다'],
  },
  {
    id: 'system-security-5',
    subjectId: 'system',
    setId: 'system-security',
    body: '재해 복구 계획을 마련하는 가장 직접적인 이유는 무엇인가요?',
    answerValue: '3',
    explanation: '장애나 재난 발생 시 서비스 복구 절차를 사전에 확보하기 위함입니다.',
    difficulty: 'medium',
    tags: ['재해복구', 'BCP'],
    correctRate: 0.57,
    choices: ['개발 일정을 연장하려고', '테스트를 줄이려고', '중단 시 복구 절차와 우선순위를 준비하려고', 'DB 스키마를 숨기려고'],
  },
  {
    id: 'system-infra-1',
    subjectId: 'system',
    setId: 'system-infra',
    body: '로드 밸런서의 역할로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '여러 서버로 요청을 분산해 부하와 장애 영향을 줄이는 역할을 합니다.',
    difficulty: 'easy',
    tags: ['인프라', '로드밸런서'],
    correctRate: 0.8,
    choices: ['소스코드를 자동 작성한다', '요청을 여러 서버에 분산한다', 'DB 정규화를 수행한다', '로그를 삭제한다'],
  },
  {
    id: 'system-infra-2',
    subjectId: 'system',
    setId: 'system-infra',
    body: '캐시 서버를 두는 주요 목적은 무엇인가요?',
    answerValue: '4',
    explanation: '자주 조회되는 데이터를 빠르게 제공해 응답 속도와 원본 부하를 개선합니다.',
    difficulty: 'easy',
    tags: ['인프라', '캐시'],
    correctRate: 0.75,
    choices: ['사용자 권한을 제거한다', '스토리지를 줄이기만 한다', '백업을 중단한다', '반복 조회 데이터를 빠르게 제공한다'],
  },
  {
    id: 'system-infra-3',
    subjectId: 'system',
    setId: 'system-infra',
    body: '모니터링 지표 중 시스템 이상 징후를 조기에 파악하는 데 도움이 되는 것은 무엇인가요?',
    answerValue: '1',
    explanation: 'CPU, 메모리, 응답 시간, 오류율 같은 지표를 지속 관찰해야 이상을 빨리 잡을 수 있습니다.',
    difficulty: 'medium',
    tags: ['모니터링', '운영'],
    correctRate: 0.67,
    choices: ['응답 시간과 오류율 추이', '파일 아이콘 색상', '개발자 좌석 배치도', '스크린샷 해상도'],
  },
  {
    id: 'system-infra-4',
    subjectId: 'system',
    setId: 'system-infra',
    body: '클라우드 환경에서 오토스케일링의 장점으로 가장 적절한 것은 무엇인가요?',
    answerValue: '3',
    explanation: '부하 변화에 따라 자원을 자동으로 증감해 비용과 성능 균형을 맞출 수 있습니다.',
    difficulty: 'medium',
    tags: ['클라우드', '오토스케일링'],
    correctRate: 0.61,
    choices: ['서버 로그를 자동 삭제한다', '모든 장애를 원천 차단한다', '부하에 맞춰 자원을 자동 조절한다', '개발자를 대체한다'],
  },
  {
    id: 'system-infra-5',
    subjectId: 'system',
    setId: 'system-infra',
    body: '배치 작업 운영 시 스케줄러를 사용하는 이유로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '정해진 시간이나 조건에 맞춰 반복 작업을 자동 실행하기 위해 사용합니다.',
    difficulty: 'easy',
    tags: ['운영', '배치'],
    correctRate: 0.73,
    choices: ['소스 코드를 암호화하기 위해', '반복 작업을 정해진 시점에 자동 실행하기 위해', '테이블 관계를 설계하기 위해', 'UI 애니메이션을 추가하기 위해'],
  },
  {
    id: 'web-core-1',
    examId: 'web-general',
    subjectId: 'html-css',
    setId: 'web-core',
    body: '시맨틱 HTML 태그 사용의 장점으로 가장 적절한 것은 무엇인가요?',
    answerValue: '4',
    explanation: '시맨틱 태그는 문서 구조 이해, 접근성, 유지보수성 향상에 도움을 줍니다.',
    difficulty: 'easy',
    tags: ['HTML', '접근성'],
    correctRate: 0.74,
    sourceLabel: WEB_SOURCE,
    choices: ['CSS를 사용할 수 없게 한다', '브라우저 캐시를 비활성화한다', '자바스크립트를 줄여 준다', '문서 의미를 더 명확하게 전달한다'],
  },
  {
    id: 'web-core-2',
    examId: 'web-general',
    subjectId: 'html-css',
    setId: 'web-core',
    body: '모바일 화면에서 하단 고정 액션바가 안전 영역을 침범하지 않게 할 때 유용한 CSS는 무엇인가요?',
    answerValue: '3',
    explanation: '`env(safe-area-inset-bottom)`를 사용하면 노치와 홈 인디케이터 영역을 고려할 수 있습니다.',
    difficulty: 'medium',
    tags: ['CSS', '모바일'],
    correctRate: 0.49,
    sourceLabel: WEB_SOURCE,
    choices: ['position: absolute', 'display: inline', 'env(safe-area-inset-bottom)', 'text-overflow: ellipsis'],
  },
  {
    id: 'web-core-3',
    examId: 'web-general',
    subjectId: 'html-css',
    setId: 'web-core',
    body: '터치 친화적인 보기 버튼 UX로 가장 적절한 것은 무엇인가요?',
    answerValue: '2',
    explanation: '충분한 패딩과 명확한 선택 상태를 제공해야 모바일 터치 오차를 줄일 수 있습니다.',
    difficulty: 'easy',
    tags: ['UX', '모바일'],
    correctRate: 0.83,
    sourceLabel: WEB_SOURCE,
    choices: ['텍스트만 작은 크기로 배치한다', '넓은 터치 영역과 선택 상태를 제공한다', '제출 버튼을 숨긴다', '스크롤 끝에만 정답을 표시한다'],
  },
];

const ENGINEER_VARIANT_QUESTION_SEEDS: QuestionSeed[] = QUESTION_SEEDS.flatMap((seed) => {
  if ((seed.examId ?? 'engineer-info') !== 'engineer-info') {
    return [];
  }

  return [1, 2, 3].map((variantIndex) => {
    const order = rotateChoiceOrder(variantIndex);
    const nextCorrectRate =
      variantIndex === 1
        ? Math.max(0.35, Number((seed.correctRate - 0.05).toFixed(2)))
        : Math.min(0.92, Number((seed.correctRate + 0.03).toFixed(2)));

    return {
      ...seed,
      id: `${seed.id}-v${variantIndex}`,
      body: createVariantBody(seed.body, variantIndex),
      answerValue: remapAnswerValue(seed.answerValue, order),
      explanation: createVariantExplanation(seed.explanation, variantIndex),
      correctRate: nextCorrectRate,
      choices: reorderChoices(seed.choices, order),
      sourceLabel: `${seed.sourceLabel ?? QUESTION_SET_SOURCE_MAP.get(seed.setId) ?? ENGINEER_SOURCE_PRACTICE} · 확장형`,
    } satisfies QuestionSeed;
  });
});

export const CBT_QUESTIONS: QuestionRecord[] = [
  ...QUESTION_SEEDS,
  ...ENGINEER_VARIANT_QUESTION_SEEDS,
  ...CBT_BONUS_QUESTION_SEEDS,
  ...CBT_SUBJECT_EXPANSION_QUESTION_SEEDS,
].map(buildQuestion);

export const QUICK_QUESTION_COUNTS = [10, 20, 40, 60, 80];
