/**
 * pCNT 인지검사 5종 자극/구성 데이터
 * 출처: cnt_1.0.10 react-native/src/components/CNT{TestTapping,Expression,TestCard,TestNBack,Rotation}
 * PRD Phase2 §3.1 기준으로 정리 (EP는 50단계로 축소)
 */

// ---------------------------------------------------------------------------
// 검사 카테고리 메타
// ---------------------------------------------------------------------------
export interface CNTTestMeta {
  code: string; // MC | EP | CST | NB | MR
  route: string; // URL 경로 slug (mc | ep | cst | nb | mr)
  title: string;
  description: string;
  duration: number; // 소요시간(분)
  dataKey: 'MC' | 'EP' | 'CST' | 'NBACK' | 'MR';
}

export const CNT_TEST_LIST: CNTTestMeta[] = [
  {
    code: 'MC',
    route: 'mc',
    title: '소근육',
    description: '소근육 테스트는 피검사자 양손의 소근육 능력을 측정하는 테스트 입니다.',
    duration: 1,
    dataKey: 'MC',
  },
  {
    code: 'EP',
    route: 'ep',
    title: '얼굴표정',
    description: '표정 맞추기 테스트는 피검사자가 사람의 다양한 감정을 정확하게 인지하고, 신속하게 구분할 수 있는지 파악하는 테스트 입니다.',
    duration: 3,
    dataKey: 'EP',
  },
  {
    code: 'CST',
    route: 'cst',
    title: '카드정렬',
    description: '카드정렬 테스트는 피검사자가 제시되는 카드 배열[목표]을 정확하게 인지하고, 집중하여 동일하게 구성할 수 있는지를 파악하는 테스트 입니다.',
    duration: 3,
    dataKey: 'CST',
  },
  {
    code: 'NB',
    route: 'nb',
    title: 'N-Back',
    description: 'N-BACK 테스트는 피검사자가 이전의 기억을 떠올려 작업할 수 있는지를 파악하는 테스트 입니다.',
    duration: 4,
    dataKey: 'NBACK',
  },
  {
    code: 'MR',
    route: 'mr',
    title: '회전도형',
    description: '회전 도형 테스트는 피검사자가 제시되는 도형을 정확하게 인식하고, 집중하여 회상 할 수 있는지를 알아보는 테스트 입니다.',
    duration: 4,
    dataKey: 'MR',
  },
];

// ---------------------------------------------------------------------------
// 인지검사 안내(인트로) 콘텐츠 — 요청사항-001-1
// ---------------------------------------------------------------------------
export interface IntroContent {
  code: string;
  title: string; // 예: "소근육 테스트"
  subtitle: string; // 예: "6단계 · 1분"
  description: string; // 검사 설명
  previewImage?: string; // public/images/ 기준 경로 (선택)
}

export const INTRO_DATA: Record<string, IntroContent> = {
  MC: {
    code: 'MC',
    title: '소근육 테스트',
    subtitle: '6단계 · 1분',
    description:
      '소근육 테스트는 피검사자 양손의 소근육 능력을 측정하는 테스트 입니다.',
    previewImage: '/images/ui/MC_Test_img.png',
  },
  EP: {
    code: 'EP',
    title: '표정 맞추기 테스트',
    subtitle: '50단계 · 3분',
    description: '표정 맞추기 테스트는 피검사자가 사람의 다양한 감정을 정확하게 인지하고, 신속하게 구분할 수 있는지 파악하는 테스트 입니다.',
    previewImage: '/images/ui/EP_Test_img.png',
  },
  CST: {
    code: 'CST',
    title: '카드정렬 테스트',
    subtitle: '30단계 · 3분',
    description: '카드정렬 테스트는 피검사자가 제시되는 카드 배열[목표]을 정확하게 인지하고, 집중하여 동일하게 구성할 수 있는지를 파악하는 테스트 입니다.',
    previewImage: '/images/ui/CST_Test_img.png',
  },
  NB: {
    code: 'NB',
    title: 'N-Back 테스트',
    subtitle: '78단계 · 4분',
    description: 'N-BACK 테스트는 피검사자가 이전의 기억을 떠올려 작업할 수 있는지를 파악하는 테스트 입니다.',
    previewImage: '/images/ui/N-BACK_Test_img.png',
  },
  MR: {
    code: 'MR',
    title: '회전 도형 테스트',
    subtitle: '50단계 · 4분',
    description: '회전 도형 테스트는 피검사자가 제시되는 도형을 정확하게 인식하고, 집중하여 회상 할 수 있는지를 알아보는 테스트 입니다.',
    previewImage: '/images/ui/MR_Test_img.png',
  },
};

// ---------------------------------------------------------------------------
// MC — 소근육 탭핑 (6단계, true=왼손탭/오른손스와이프)
// ---------------------------------------------------------------------------
export const MC_STEP_DATA: boolean[] = [true, false, true, false, true, false];
export const MC_STEP_DURATION = 10000; // 10초/단계
export const MC_TOUCH_POLL_MS = 25; // 터치 폴링 간격
export const MC_TOUCH_STATIONARY_MS = 100; // lastMovedTime 정지 판정
export const MC_SWIPE_GAP_DIVISOR = 6; // minSwipeGap = areaCenter / 6

// ---------------------------------------------------------------------------
// EP — 얼굴표정 (PRD §3.1.2: 50단계 = Block1 25 + Block2 25)
// ---------------------------------------------------------------------------
export type EPPersonAge = '10' | '30' | '50' | '70';
export type EPEmotion = 'happy' | 'sad' | 'neutral' | 'angry';
export type EPDifficulty = 'easy' | 'normal' | 'hard';

export interface EPPerson {
  name: string;
  age: EPPersonAge;
}

/** 인물 20명 (아동/청년/중년/노년 × 5명) */
export const EP_PEOPLE: EPPerson[] = [
  // 아동
  { name: 'chooli', age: '10' },
  { name: 'daisy', age: '10' },
  { name: 'james', age: '10' },
  { name: 'john', age: '10' },
  { name: 'kayla', age: '10' },
  // 청년
  { name: 'armand', age: '30' },
  { name: 'endelion', age: '30' },
  { name: 'makayla', age: '30' },
  { name: 'miami', age: '30' },
  { name: 'vernon', age: '30' },
  // 중년
  { name: 'fiona', age: '50' },
  { name: 'innes', age: '50' },
  { name: 'kein', age: '50' },
  { name: 'pamela', age: '50' },
  { name: 'robert', age: '50' },
  // 노년
  { name: 'charlie', age: '70' },
  { name: 'linda', age: '70' },
  { name: 'mac', age: '70' },
  { name: 'romeo', age: '70' },
  { name: 'samanda', age: '70' },
];

/** 감정 → 이미지 파일 접두어 */
export const EP_EMOTION_PREFIX: Record<EPEmotion, string> = {
  happy: 'smile',
  sad: 'depressed',
  neutral: 'normal',
  angry: 'angry',
};

/** 난이도 → 이미지 접미어(1|2|3) */
export const EP_DIFFICULTY_SUFFIX: Record<EPDifficulty, 1 | 2 | 3> = {
  easy: 1,
  normal: 2,
  hard: 3,
};

/** EP 얼굴 이미지 경로 생성 */
export function epImage(person: EPPerson, emotion: EPEmotion, difficulty: EPDifficulty): string {
  return `images/ep/age_${person.age}/${person.name}/${person.name}_${EP_EMOTION_PREFIX[emotion]}_${EP_DIFFICULTY_SUFFIX[difficulty]}.png`;
}

/** 각 단계 슬롯: [감정, 난이도]. 항목이 null이면 랜덤 값으로 채워 항상 실제 얼굴 이미지가 된다 (빈칸 없음). */
export type EPStepSpec = Array<[EPEmotion | null, EPDifficulty | null]>;

/**
 * Block 1 (사진 2장, 25단계):
 *  행복+중립(2) 행복+행복(1) 슬픔+중립(2) 슬픔+슬픔(1) 분노+중립(2) 분노+분노(1) 무작위(16) — 셔플
 * null 항목은 생성 시 무작위 2감정으로 채운다.
 */
export const EP_BLOCK1_SPEC: Array<EPStepSpec | null> = [
  ...Array(2).fill([['happy', 'easy'], ['neutral', 'easy']] as EPStepSpec),
  ...[Array(2).fill(['happy', 'easy'])] as unknown as EPStepSpec,
  ...Array(2).fill([['sad', 'easy'], ['neutral', 'easy']] as EPStepSpec),
  ...[Array(2).fill(['sad', 'easy'])] as unknown as EPStepSpec,
  ...Array(2).fill([['angry', 'easy'], ['neutral', 'easy']] as EPStepSpec),
  ...[Array(2).fill(['angry', 'easy'])] as unknown as EPStepSpec,
  // 전부 무작위 16
  ...Array(16).fill(null),
];

/**
 * Block 2 (사진 4장, 25단계):
 *  감정3장+중립1개(2) 전부 같음(3) 3장+1개 랜덤(5×4감정=20) — 셔플
 *  [null, null] 슬롯은 랜덤 감정으로 채워지며(빈칸 아님), 정답은 런타임에 판정된다.
 */
export const EP_BLOCK2_SPEC: EPStepSpec[] = [
  // 감정 3장 + 중립 1개 × 2
  [['happy', 'normal'], ['happy', 'normal'], ['happy', 'normal'], ['neutral', 'normal']],
  [['sad', 'normal'], ['sad', 'normal'], ['sad', 'normal'], ['neutral', 'normal']],
  // 전부 같음 × 3
  [['happy', 'normal'], ['happy', 'normal'], ['happy', 'normal'], ['happy', 'normal']],
  [['sad', 'normal'], ['sad', 'normal'], ['sad', 'normal'], ['sad', 'normal']],
  [['angry', 'normal'], ['angry', 'normal'], ['angry', 'normal'], ['angry', 'normal']],
  // 3장 + 1개 랜덤 × 5회 × 4감정 = 20
  ...Array(5).fill([
    ['happy', 'normal'],
    ['happy', 'normal'],
    ['happy', 'normal'],
    [null, null],
  ] as EPStepSpec),
  ...Array(5).fill([
    ['sad', 'normal'],
    ['sad', 'normal'],
    ['sad', 'normal'],
    [null, null],
  ] as EPStepSpec),
  ...Array(5).fill([
    ['angry', 'normal'],
    ['angry', 'normal'],
    ['angry', 'normal'],
    [null, null],
  ] as EPStepSpec),
  ...Array(5).fill([
    ['neutral', 'normal'],
    ['neutral', 'normal'],
    ['neutral', 'normal'],
    [null, null],
  ] as EPStepSpec),
];

export const EP_STEP_DURATION = 3000; // 3초/단계

// ---------------------------------------------------------------------------
// CST — 카드정렬 (30단계: 3장×10 / 4장×10 / 5장×10)
// ---------------------------------------------------------------------------
export interface CSTCardColor {
  label: string;
  /** id(1~18) → 이미지 파일명 */
  file: (id: number) => string;
}

/**
 * darkgreen/green 카드에 실제 존재하는 파일 번호 (18개).
 * 이전 코드는 `id+26`(27~44)로 생성했으나 실제 파일엔 28~40 등이 없어
 * 이미지 404 → 흰 카드로 표시되는 문제가 있었다. (수정사항-020-2)
 */
const CST_GREEN_FILE_IDS = [27, 41, 42, 43, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65];

export const CST_CARD_COLORS: CSTCardColor[] = [
  { label: 'bluecard', file: (id) => `blue${id}.png` },
  { label: 'browncard', file: (id) => `brown${id}.png` },
  {
    label: 'darkgreencard',
    file: (id) => `darkgreen${CST_GREEN_FILE_IDS[(id - 1) % CST_GREEN_FILE_IDS.length]}.png`,
  },
  {
    label: 'greencard',
    file: (id) => `green${CST_GREEN_FILE_IDS[(id - 1) % CST_GREEN_FILE_IDS.length]}.png`,
  },
  { label: 'redcard', file: (id) => `red${id}.png` },
];

/** 카드 순서 패턴: 2행 × 3열, 각 칸은 카드 id 목록 */
export type CSTPattern = CSTPatternCell[][];
export type CSTPatternCell = Array<{ id: number }>;

/** 난이도별 10개 지시 패턴 (cnt_1.0.10 useCNTTestCard.context.tsx 그대로) */
export const CST_EASY_PATTERNS: CSTPattern[] = [
  [[[{ id: 0 }], [{ id: 1 }], [{ id: 2 }]], [[{ id: 1 }, { id: 0 }], [], [{ id: 2 }]]],
  [[[{ id: 0 }, { id: 1 }], [{ id: 2 }], []], [[], [{ id: 0 }], [{ id: 1 }, { id: 2 }]]],
  [[[{ id: 0 }, { id: 1 }, { id: 2 }], [], []], [[], [{ id: 2 }, { id: 0 }], [{ id: 1 }]]],
  [[[{ id: 0 }, { id: 1 }], [], [{ id: 2 }]], [[{ id: 1 }], [{ id: 0 }], [{ id: 2 }]]],
  [[[], [{ id: 0 }, { id: 1 }], [{ id: 2 }]], [[{ id: 1 }, { id: 2 }], [], [{ id: 0 }]]],
  [[[{ id: 1 }], [{ id: 0 }], [{ id: 2 }]], [[{ id: 1 }], [{ id: 2 }], [{ id: 0 }]]],
  [[[{ id: 0 }], [], [{ id: 2 }, { id: 1 }]], [[{ id: 0 }, { id: 2 }, { id: 1 }], [], []]],
  [[[], [{ id: 1 }], [{ id: 2 }, { id: 0 }]], [[{ id: 2 }], [{ id: 0 }], [{ id: 1 }]]],
  [[[], [{ id: 1 }, { id: 2 }, { id: 0 }], []], [[{ id: 1 }], [], [{ id: 0 }, { id: 2 }]]],
  [[[{ id: 2 }], [{ id: 1 }, { id: 0 }], []], [[{ id: 2 }], [], [{ id: 1 }, { id: 0 }]]],
];

export const CST_NORMAL_PATTERNS: CSTPattern[] = [
  [[[{ id: 0 }, { id: 3 }], [{ id: 1 }], [{ id: 2 }]], [[{ id: 0 }, { id: 1 }], [{ id: 3 }, { id: 2 }], []]],
  [[[{ id: 1 }], [{ id: 2 }, { id: 0 }], [{ id: 3 }]], [[{ id: 1 }], [{ id: 3 }], [{ id: 0 }, { id: 2 }]]],
  [[[{ id: 2 }, { id: 3 }, { id: 0 }], [{ id: 1 }], []], [[], [{ id: 0 }, { id: 2 }], [{ id: 1 }, { id: 3 }]]],
  [[[{ id: 1 }, { id: 3 }], [], [{ id: 0 }, { id: 2 }]], [[{ id: 0 }, { id: 3 }], [], [{ id: 1 }, { id: 2 }]]],
  [[[{ id: 0 }, { id: 2 }], [], [{ id: 3 }, { id: 1 }]], [[], [{ id: 1 }, { id: 2 }, { id: 3 }], [{ id: 0 }]]],
  [[[], [{ id: 2 }, { id: 0 }], [{ id: 3 }, { id: 1 }]], [[{ id: 3 }, { id: 1 }, { id: 0 }], [{ id: 2 }], []]],
  [[[{ id: 3 }], [{ id: 0 }], [{ id: 1 }, { id: 2 }]], [[{ id: 3 }, { id: 1 }, { id: 2 }], [], [{ id: 0 }]]],
  [[[], [{ id: 0 }], [{ id: 1 }, { id: 3 }, { id: 2 }]], [[{ id: 0 }, { id: 3 }], [{ id: 2 }, { id: 1 }], []]],
  [[[{ id: 1 }, { id: 2 }], [{ id: 3 }, { id: 0 }], []], [[{ id: 3 }], [], [{ id: 0 }, { id: 2 }, { id: 1 }]]],
  [[[{ id: 0 }, { id: 1 }], [{ id: 2 }, { id: 3 }], []], [[], [{ id: 2 }, { id: 0 }, { id: 3 }], [{ id: 1 }]]],
];

export const CST_HARD_PATTERNS: CSTPattern[] = [
  [[[{ id: 0 }, { id: 3 }], [{ id: 1 }, { id: 4 }], [{ id: 2 }]], [[{ id: 3 }, { id: 4 }], [], [{ id: 2 }, { id: 0 }, { id: 1 }]]],
  [[[{ id: 0 }, { id: 3 }, { id: 4 }], [{ id: 1 }, { id: 2 }], []], [[{ id: 0 }], [{ id: 3 }, { id: 1 }], [{ id: 4 }, { id: 2 }]]],
  [[[{ id: 0 }], [{ id: 4 }, { id: 2 }], [{ id: 3 }, { id: 1 }]], [[{ id: 1 }, { id: 3 }, { id: 2 }], [{ id: 4 }], [{ id: 0 }]]],
  [[[{ id: 0 }, { id: 1 }], [{ id: 4 }], [{ id: 2 }, { id: 3 }]], [[{ id: 4 }, { id: 1 }], [{ id: 2 }, { id: 3 }], [{ id: 0 }]]],
  [[[{ id: 0 }], [{ id: 4 }, { id: 1 }, { id: 2 }], [{ id: 3 }]], [[{ id: 3 }, { id: 1 }], [{ id: 4 }], [{ id: 0 }, { id: 2 }]]],
  [[[{ id: 2 }], [{ id: 0 }], [{ id: 1 }, { id: 3 }, { id: 4 }]], [[{ id: 3 }, { id: 1 }], [{ id: 0 }, { id: 2 }], [{ id: 4 }]]],
  [[[{ id: 4 }, { id: 3 }, { id: 1 }], [{ id: 2 }, { id: 0 }], []], [[], [{ id: 1 }, { id: 3 }], [{ id: 2 }, { id: 0 }, { id: 4 }]]],
  [[[{ id: 3 }, { id: 1 }], [{ id: 2 }], [{ id: 4 }, { id: 0 }]], [[], [{ id: 0 }, { id: 3 }], [{ id: 4 }, { id: 2 }, { id: 1 }]]],
  [[[], [{ id: 2 }, { id: 3 }, { id: 0 }], [{ id: 1 }, { id: 4 }]], [[{ id: 3 }, { id: 2 }], [{ id: 0 }, { id: 4 }], [{ id: 1 }]]],
  [[[{ id: 0 }, { id: 3 }], [{ id: 1 }, { id: 4 }], [{ id: 2 }]], [[{ id: 2 }, { id: 4 }, { id: 3 }], [], [{ id: 1 }, { id: 0 }]]],
];

/** 카드 수별 난이도 코드/시간 */
export const CST_DIFFICULTY: Record<
  3 | 4 | 5,
  { code: 'C3' | 'C4' | 'C5'; duration: number }
> = {
  3: { code: 'C3', duration: 5000 },
  4: { code: 'C4', duration: 10000 },
  5: { code: 'C5', duration: 15000 },
};

/** 30단계 생성 (3/4/5장 × 각10) */
export const CST_STEP_SIZES: Array<3 | 4 | 5> = [
  ...Array(10).fill(3),
  ...Array(10).fill(4),
  ...Array(10).fill(5),
];

// ---------------------------------------------------------------------------
// NB — N-Back (이전 cnt_1.0.10 상태머신 재현: 준비 n개 + 답변 m개, 총 70개 기록)
//   ONE_BACK_COUNT = 1+15, TWO_BACK_COUNT = 2+30, THREE_BACK_COUNT = 3+25
//   → 각 레벨 첫 n개 값은 "준비(prime)"로 표시만(답변 불가), 이후가 "question"
// ---------------------------------------------------------------------------
export type NBStepKind = 'transition' | 'prime' | 'question';

export interface NBStep {
  kind: NBStepKind;
  nback: 1 | 2 | 3;
  value: number; // prime/question — 표시할 숫자 (transition은 0)
  isMatch?: boolean; // question — 현재 값이 n단계 전 값과 같은지
  to?: 2 | 3; // transition — 다음 레벨
}

export const NB_STEP_DURATION = 3000; // 3초/단계
export const NB_ANIMATION_MS = 500; // 단계 전환 회전·페이드 애니메이션

/** 세션당 랜덤 단계 목록 생성 (cnt_1.0.10과 동일한 준비/답변 구조) */
export function buildNBackSteps(): NBStep[] {
  const rand = (count: number) =>
    Array.from({ length: count }, () => Math.floor(Math.random() * 10));
  const steps: NBStep[] = [];

  // 1-Back: 준비1 + 답변15 (isMatch = 직전 값과 비교)
  const b1 = rand(16);
  steps.push({ kind: 'prime', nback: 1, value: b1[0] });
  for (let i = 1; i < 16; i++) {
    steps.push({ kind: 'question', nback: 1, value: b1[i], isMatch: b1[i] === b1[i - 1] });
  }

  // 2-Back: 레벨 전환 + 준비2 + 답변30
  steps.push({ kind: 'transition', nback: 2, value: 0, to: 2 });
  const b2 = rand(32);
  steps.push({ kind: 'prime', nback: 2, value: b2[0] });
  steps.push({ kind: 'prime', nback: 2, value: b2[1] });
  for (let i = 2; i < 32; i++) {
    steps.push({ kind: 'question', nback: 2, value: b2[i], isMatch: b2[i] === b2[i - 2] });
  }

  // 3-Back: 레벨 전환 + 준비3 + 답변25
  steps.push({ kind: 'transition', nback: 3, value: 0, to: 3 });
  const b3 = rand(28);
  steps.push({ kind: 'prime', nback: 3, value: b3[0] });
  steps.push({ kind: 'prime', nback: 3, value: b3[1] });
  steps.push({ kind: 'prime', nback: 3, value: b3[2] });
  for (let i = 3; i < 28; i++) {
    steps.push({ kind: 'question', nback: 3, value: b3[i], isMatch: b3[i] === b3[i - 3] });
  }

  return steps;
}

// ---------------------------------------------------------------------------
// MR — 회전도형 (50단계: 같은 도형 25 + 다른 도형 25)
// ---------------------------------------------------------------------------
export const MR_STEP_DURATION = 5000; // 5초
export const MR_SAME_COUNT = 25;
export const MR_DIFF_COUNT = 25;
export const MR_SHAPE_COUNT = 10;
export const MR_ROTATION_COUNT = 27;

export function mrImage(shape: number, rotation: number): string {
  return `images/shape/shape-${shape}-${rotation}.png`;
}
