// Sound library + i18n strings — TypeScript
// Uses real MP3 files (existing assets). Custom sounds (uploaded/recorded)
// are loaded separately from IndexedDB by app.tsx.

type Group = 'noise' | 'rain' | 'nature' | 'shush' | 'ambient' | 'music' | 'custom';
type Lang = 'ko' | 'en';

interface SoundDef {
  id: string;
  group: Group;
  emoji: string;
  ko: string;
  en: string;
  file: string;          // MP3 path (or blob URL for custom)
  meta_ko: string;
  meta_en: string;
  isCustom?: boolean;
  loopMode?: 'continuous' | 'interval';
  intervalSec?: number;
  blob?: Blob;           // present for custom sounds (registered with engine)
}

interface PresetDef {
  id: string;
  ko: string;
  en: string;
  icon: string;
  mix: Record<string, number>;   // values 0..1
  custom?: boolean;
}

interface TimerOption { mins: number | null; ko: string; en: string }

interface Strings {
  appTitle: string;
  appSubtitle: string;
  tagline: string;
  badges: string[];
  stopAll: string; playAll: string; master: string; timer: string;
  timerHint: string; timerLeft: string; timerOff: string;
  presets: string; presetsHint: string; saveMix: string; myPresets: string;
  sounds: string; soundsHint: string;
  activeSounds: (n: number) => string;
  nowPlaying: string; nothingPlaying: string; pickToStart: string;
  record: string; upload: string; volume: string;
  cancel: string; save: string; delete: string;
  setTimer: string; end: string; nightMode: string;
  new: string; namePreset: string;
  customSection: string; addFile: string; recordVoice: string;
  customNoneHint: string;
  recHint: string; recStart: string; recStop: string; recRetry: string;
  loopMode: string; continuous: string; interval: string; intervalSec: string;
  customName: string;
  updateAvailable: string; applyUpdate: string;
  fadeOut: string;
  emptyTimer: string;
  oncePlayingTimerActive: string;
}

const SOUNDS: SoundDef[] = [
  // 백색소음 (noise)
  { id: 'white_noise',  group: 'noise',  emoji: '⚪',  ko: '화이트 노이즈',  en: 'White Noise',
    file: 'audio/white_noise.mp3', meta_ko: '10분 · 24-bit 스튜디오',     meta_en: '10min · Studio' },
  { id: 'pink_noise',   group: 'noise',  emoji: '🌸',  ko: '핑크 노이즈',    en: 'Pink Noise',
    file: 'audio/pink_noise.mp3',  meta_ko: '10분 · 부드러운 노이즈',    meta_en: '10min · Soft noise' },
  { id: 'brown_noise',  group: 'noise',  emoji: '🟫',  ko: '브라운 노이즈',  en: 'Brown Noise',
    file: 'audio/brown_noise.mp3', meta_ko: '10분 · ⭐⭐⭐⭐⭐ 인기',     meta_en: '10min · Most popular' },

  // 빗소리 (rain)
  { id: 'soft_rain',    group: 'rain',   emoji: '☔',  ko: '잔잔한 보슬비',  en: 'Soft Drizzle',
    file: 'audio/soft_rain.mp3',   meta_ko: '9분 · 가장 부드러움',       meta_en: '9min · Gentlest' },
  { id: 'light_rain',   group: 'rain',   emoji: '🌦️', ko: '약한 비',        en: 'Light Rain',
    file: 'audio/light_rain.mp3',  meta_ko: '15분 · 잔잔히 내리는 비',   meta_en: '15min · Calm rain' },
  { id: 'rain_window',  group: 'rain',   emoji: '🪟',  ko: '창문 빗방울',    en: 'Rain on Window',
    file: 'audio/rain_window.mp3', meta_ko: '창문에 떨어지는 빗소리',    meta_en: 'Drops on glass' },
  { id: 'rain',         group: 'rain',   emoji: '🌧️', ko: '폭우',           en: 'Heavy Rain',
    file: 'audio/rain.mp3',        meta_ko: '15분 · 강한 빗줄기',        meta_en: '15min · Strong rain' },
  { id: 'thunderstorm', group: 'rain',   emoji: '⛈️', ko: '번개 뇌우',      en: 'Thunderstorm',
    file: 'audio/thunderstorm.mp3',meta_ko: '16분 · 비 + 천둥',          meta_en: '16min · Rain + thunder' },

  // 자연 (nature)
  { id: 'ocean',        group: 'nature', emoji: '🌊',  ko: '파도 소리',      en: 'Ocean Waves',
    file: 'audio/ocean.mp3',       meta_ko: '15분 · La Jolla 해변',      meta_en: '15min · La Jolla' },
  { id: 'fireplace',    group: 'nature', emoji: '🔥',  ko: '모닥불',         en: 'Fireplace',
    file: 'audio/fireplace.mp3',   meta_ko: '15분 · 진짜 벽난로',        meta_en: '15min · Real fireplace' },
  { id: 'birds_seoul',  group: 'nature', emoji: '🐦',  ko: '한강 새소리',    en: 'Birds (Seoul)',
    file: 'audio/birds_seoul.mp3', meta_ko: '4분 · 반포한강공원',        meta_en: '4min · Han River Park' },
  { id: 'forest',       group: 'nature', emoji: '🌲',  ko: '숲 소리',        en: 'Forest',
    file: 'audio/forest.mp3',      meta_ko: '체코 숲 실제 녹음',         meta_en: 'Czech forest' },

  // 쉬쉬 (shush)
  { id: 'shushing_real',group: 'shush',  emoji: '🤫',  ko: '쉬이이이~',      en: 'Shushing',
    file: 'audio/shushing_real.mp3', meta_ko: '56초 · 실제 녹음',        meta_en: '56s · Real recording' },

  // 분위기 (ambient)
  { id: 'wind_chimes',  group: 'ambient',emoji: '🎐',  ko: '풍경/귀뚜라미',  en: 'Wind Chimes',
    file: 'audio/wind_chimes.mp3', meta_ko: '3분 · 풍경+귀뚜라미+종',    meta_en: '3min · Chimes + crickets' },
  { id: 'heartbeat',    group: 'ambient',emoji: '💓',  ko: '심장박동 (태아)', en: 'Heartbeat (Fetal)',
    file: 'audio/heartbeat.mp3',   meta_ko: '34초 · 자궁 도플러',        meta_en: '34s · Womb doppler' },
  { id: 'heartbeat_slow', group: 'ambient',emoji: '💗', ko: '심장박동 (느림)', en: 'Heartbeat (Slow)',
    file: 'audio/heartbeat_slow.mp3', meta_ko: '46초 · 약 50bpm',        meta_en: '46s · ~50bpm' },
  { id: 'heartbeat_normal', group: 'ambient',emoji: '❤️', ko: '심장박동 (정상)', en: 'Heartbeat (Normal)',
    file: 'audio/heartbeat_normal.mp3', meta_ko: '33초 · 약 70bpm',     meta_en: '33s · ~70bpm' },
  { id: 'heartbeat_fast', group: 'ambient',emoji: '💖', ko: '심장박동 (빠름)', en: 'Heartbeat (Fast)',
    file: 'audio/heartbeat_fast.mp3', meta_ko: '40초 · 약 100bpm',       meta_en: '40s · ~100bpm' },

  // 자장가/오르골 (music)
  { id: 'lullaby',      group: 'music',  emoji: '🍼',  ko: '아기 자장가',    en: 'Baby Lullaby',
    file: 'audio/lullaby.mp3',     meta_ko: '3분 · 부드러운 자장가',     meta_en: '3min · Gentle lullaby' },
  { id: 'musicbox_brahms', group: 'music', emoji: '🎵', ko: '브람스 왈츠',   en: 'Brahms Waltz',
    file: 'audio/musicbox_brahms.mp3', meta_ko: '오르골 · 브람스',       meta_en: 'Music box · Brahms' },
  { id: 'musicbox_bach',group: 'music',  emoji: '🎼',  ko: 'Bach G선상의 아리아', en: "Bach's Air on the G",
    file: 'audio/musicbox_bach.mp3',meta_ko: '오르골 · 바흐',            meta_en: 'Music box · Bach' },
  { id: 'musicbox_chopin',group: 'music',emoji: '🎶',  ko: '쇼팽 야상곡',    en: 'Chopin Nocturne',
    file: 'audio/musicbox_chopin.mp3',meta_ko: '오르골 · 쇼팽',          meta_en: 'Music box · Chopin' },
  { id: 'mozart_twinkle', group: 'music', emoji: '🌟', ko: '모차르트 작은별 변주곡', en: 'Mozart Twinkle Variations',
    file: 'audio/mozart_twinkle.mp3', meta_ko: '2분 · 모차르트 K.265', meta_en: '2min · Mozart K.265' },
  { id: 'mozart_eine_kleine', group: 'music', emoji: '🎻', ko: '아이네 클라이네 나흐트무지크', en: 'Eine kleine Nachtmusik',
    file: 'audio/mozart_eine_kleine.mp3', meta_ko: '4분 · 모차르트 K.525', meta_en: '4min · Mozart K.525' },
  { id: 'mozart_sonata_k545', group: 'music', emoji: '🎹', ko: '모차르트 피아노 소나타', en: 'Mozart Piano Sonata',
    file: 'audio/mozart_sonata_k545.mp3', meta_ko: '2분 · 모차르트 K.545 1악장', meta_en: '2min · Mozart K.545 Mvt.1' },
  { id: 'mozart_clarinet_adagio', group: 'music', emoji: '🎷', ko: '모차르트 클라리넷 아다지오', en: 'Mozart Clarinet Adagio',
    file: 'audio/mozart_clarinet_adagio.mp3', meta_ko: '7분 · 모차르트 K.622 2악장', meta_en: '7min · Mozart K.622 Mvt.2' },
];

// Hue mapping for SoundCard (keys must match SoundCard's groupHueMap)
const GROUP_HUE: Record<Group, string> = {
  noise:   'lavender',
  rain:    'sage',
  nature:  'sage',
  shush:   'rose',
  ambient: 'peach',
  music:   'peach',
  custom:  'rose',
};

const GROUP_KEYS: ('all' | Group)[] = ['all', 'noise', 'rain', 'nature', 'shush', 'ambient', 'music', 'custom'];

const GROUP_LABELS: Record<Lang, Record<'all' | Group, string>> = {
  ko: { all: '전체', noise: '백색소음', rain: '빗소리', nature: '자연', shush: '쉬쉬', ambient: '분위기', music: '자장가', custom: '내 음원' },
  en: { all: 'All',  noise: 'Noise',   rain: 'Rain',   nature: 'Nature', shush: 'Shush', ambient: 'Ambient', music: 'Music',  custom: 'Custom' },
};

const PRESETS_DEFAULT: PresetDef[] = [
  { id: 'newborn',     ko: '신생아 잠재우기',    en: 'Newborn Sleep',          icon: '🌙',
    mix: { shushing_real: 0.60, brown_noise: 0.35, lullaby: 0.25 } },
  { id: 'shush-rain',  ko: '쉬이이이 + 빗소리',  en: 'Shush + Rain',           icon: '🤫',
    mix: { shushing_real: 0.65, soft_rain: 0.40 } },
  { id: 'drizzle-llby',ko: '보슬비 자장가',      en: 'Drizzle Lullaby',        icon: '☔',
    mix: { soft_rain: 0.70, lullaby: 0.35 } },
  { id: 'rainy-arvo',  ko: '비 오는 오후',       en: 'Rainy Afternoon',        icon: '🌦️',
    mix: { light_rain: 0.65, fireplace: 0.30 } },
  { id: 'window-rain', ko: '창가의 빗소리',      en: 'Rain on Window',         icon: '🪟',
    mix: { rain_window: 0.80, brown_noise: 0.25 } },
  { id: 'storm-asmr',  ko: '뇌우 ASMR',          en: 'Thunderstorm ASMR',      icon: '⛈️',
    mix: { thunderstorm: 0.75, brown_noise: 0.20 } },
  { id: 'beach-rest',  ko: '바닷가 휴식',        en: 'Beach Rest',             icon: '🏖️',
    mix: { ocean: 0.75, pink_noise: 0.20 } },
  { id: 'campfire',    ko: '캠프파이어',         en: 'Campfire',               icon: '🔥',
    mix: { fireplace: 0.70, wind_chimes: 0.30, brown_noise: 0.25 } },
  { id: 'forest-morn', ko: '숲속 아침',          en: 'Forest Morning',         icon: '🌅',
    mix: { forest: 0.60, birds_seoul: 0.50 } },
  { id: 'deep-sleep',  ko: '깊은 잠',            en: 'Deep Sleep',             icon: '💤',
    mix: { brown_noise: 0.60, soft_rain: 0.30 } },
  { id: 'brahms-rain', ko: '브람스 + 빗소리',    en: 'Brahms + Rain',          icon: '🎵',
    mix: { musicbox_brahms: 0.55, soft_rain: 0.30 } },
  { id: 'bach-rain',   ko: '바흐 + 빗소리',      en: 'Bach + Rain',            icon: '🎼',
    mix: { musicbox_bach: 0.55, light_rain: 0.30 } },
  { id: 'beach-llby',  ko: '해변 자장가',        en: 'Beach Lullaby',          icon: '🌊',
    mix: { ocean: 0.55, lullaby: 0.40 } },
  { id: 'womb',        ko: '태교 · 자궁',        en: 'Prenatal · Womb',        icon: '💓',
    mix: { heartbeat: 0.70, mozart_twinkle: 0.35, brown_noise: 0.25 } },
];

const TIMER_OPTIONS: TimerOption[] = [
  { mins: null, ko: '계속',  en: 'Off' },
  { mins: 15,   ko: '15분',  en: '15m' },
  { mins: 30,   ko: '30분',  en: '30m' },
  { mins: 60,   ko: '1시간', en: '1h' },
  { mins: 120,  ko: '2시간', en: '2h' },
  { mins: 240,  ko: '4시간', en: '4h' },
];

const STR: Record<Lang, Strings> = {
  ko: {
    appTitle: '아기 백색소음 믹서',
    appSubtitle: '여러 소리를 동시에 · 오프라인 작동',
    tagline: '여러 소리를 동시에 · 인터넷 없이도 재생 · 무한 반복',
    badges: ['오프라인', '무한 반복', '광고 없음'],
    stopAll: '전체 정지', playAll: '재생', master: '마스터', timer: '타이머',
    timerHint: '드래그해서 시간 설정', timerLeft: '남은 시간', timerOff: '계속 재생',
    presets: '프리셋', presetsHint: '자주 쓰는 조합을 빠르게',
    saveMix: '현재 믹스 저장', myPresets: '내 프리셋',
    sounds: '소리', soundsHint: '카드를 탭해서 켜기 · 길게 눌러 볼륨 조절',
    activeSounds: (n: number) => `${n}개 재생 중`,
    nowPlaying: '지금 재생 중',
    nothingPlaying: '아직 아무 소리도 켜지지 않았어요',
    pickToStart: '아래에서 소리를 선택해주세요',
    record: '내 녹음', upload: '파일 추가', volume: '볼륨',
    cancel: '취소', save: '저장', delete: '삭제',
    setTimer: '타이머 설정', end: '종료', nightMode: '밤 모드',
    new: '새로 만들기', namePreset: '프리셋 이름',
    customSection: '내 음원', addFile: '📁 파일 추가', recordVoice: '🎤 녹음하기',
    customNoneHint: '아직 추가된 음원이 없어요',
    recHint: '녹음 시작을 누르면 마이크 권한을 요청합니다.',
    recStart: '⏺ 녹음 시작', recStop: '⏹ 정지', recRetry: '↻ 다시',
    loopMode: '재생 방식', continuous: '연속 재생', interval: 'N초마다 반복', intervalSec: '간격(초)',
    customName: '이름',
    updateAvailable: '새 버전이 준비됐어요. 탭하면 적용됩니다.', applyUpdate: '업데이트',
    fadeOut: '⏱ 타이머 종료 · 페이드아웃 중',
    emptyTimer: '소리를 먼저 켜주세요',
    oncePlayingTimerActive: '재생 중일 때 자동 종료',
  },
  en: {
    appTitle: 'Baby Sleep Mixer',
    appSubtitle: 'Layer sounds · works offline',
    tagline: 'Layer sounds · works offline · loops forever',
    badges: ['Offline', 'Loops forever', 'No ads'],
    stopAll: 'Stop all', playAll: 'Play', master: 'Master', timer: 'Timer',
    timerHint: 'Drag to set duration', timerLeft: 'Time left', timerOff: 'No timer',
    presets: 'Presets', presetsHint: 'Your favorite combinations',
    saveMix: 'Save current mix', myPresets: 'My presets',
    sounds: 'Sounds', soundsHint: 'Tap a card to start · long-press for volume',
    activeSounds: (n: number) => `${n} playing`,
    nowPlaying: 'Now playing',
    nothingPlaying: 'Nothing is playing yet',
    pickToStart: 'Pick a sound below to get started',
    record: 'My recording', upload: 'Add file', volume: 'Volume',
    cancel: 'Cancel', save: 'Save', delete: 'Delete',
    setTimer: 'Set timer', end: 'End', nightMode: 'Night mode',
    new: 'New', namePreset: 'Preset name',
    customSection: 'My sounds', addFile: '📁 Add file', recordVoice: '🎤 Record',
    customNoneHint: 'No custom sounds yet',
    recHint: 'Tap Start to grant microphone permission.',
    recStart: '⏺ Start', recStop: '⏹ Stop', recRetry: '↻ Retry',
    loopMode: 'Loop mode', continuous: 'Continuous', interval: 'Every N seconds', intervalSec: 'Interval (s)',
    customName: 'Name',
    updateAvailable: 'A new version is ready. Tap to apply.', applyUpdate: 'Update',
    fadeOut: '⏱ Timer end · fading out',
    emptyTimer: 'Start a sound first',
    oncePlayingTimerActive: 'Auto stop while playing',
  },
};

(Object.assign as any)(window, { SOUNDS, GROUP_HUE, GROUP_KEYS, GROUP_LABELS, PRESETS_DEFAULT, TIMER_OPTIONS, STR });
