/**
 * Book Type Config 单元测试
 * 测试书籍类型配置、字数计算、音频时长计算
 */

import { describe, it, expect } from 'vitest';
import {
  FLOAT_RATIO,
  CHAPTER_WORDS_FLOAT_RATIO,
  getWordUpperLimit,
  getChapterRange,
  calcChapters,
  getChapterWordsRange,
  calcAudioMinutes,
  getBookTypeConfig,
  getAllBookTypes,
  getDetectableTypes,
  getScaleConfig,
  estimateBookWords,
  GLOBAL_ABSOLUTE_WORD_LIMIT,
  getBookWordLimit,
  BOOK_TYPE_CONFIG,
} from '@/modules/book-generator/book-type-config';

describe('FLOAT_RATIO 常量', () => {
  it('浮动比例为 0.2 (20%)', () => {
    expect(FLOAT_RATIO).toBe(0.2);
  });

  it('章节浮动比例为 0.5 (50%)', () => {
    expect(CHAPTER_WORDS_FLOAT_RATIO).toBe(0.5);
  });
});

describe('getWordUpperLimit', () => {
  it('返回基数 × 1.2', () => {
    expect(getWordUpperLimit(100000)).toBe(120000);
    expect(getWordUpperLimit(130000)).toBe(156000);
    expect(getWordUpperLimit(1000)).toBe(1200);
  });

  it('四舍五入到整数', () => {
    expect(getWordUpperLimit(130000)).toBe(156000);
  });
});

describe('getChapterRange', () => {
  it('计算章节浮动范围 ±20%', () => {
    const range = getChapterRange(10);
    expect(range.min).toBe(8);  // 10 × 0.8
    expect(range.max).toBe(12);  // 10 × 1.2
  });

  it('10章返回正确的 min/max', () => {
    const range = getChapterRange(10);
    expect(range.min).toBe(8);
    expect(range.max).toBe(12);
  });

  it('5章返回正确的 min/max', () => {
    const range = getChapterRange(5);
    expect(range.min).toBe(4);
    expect(range.max).toBe(6);
  });

  it('1章返回 0-2 范围', () => {
    const range = getChapterRange(1);
    expect(range.min).toBe(0);
    expect(range.max).toBe(2);
  });
});

describe('calcChapters', () => {
  it('根据每章2千字计算章节数', () => {
    expect(calcChapters(2000)).toBe(1);
    expect(calcChapters(4000)).toBe(2);
    expect(calcChapters(20000)).toBe(10);
    expect(calcChapters(130000)).toBe(65);
  });

  it('最少返回1章', () => {
    expect(calcChapters(100)).toBe(1);
    expect(calcChapters(0)).toBe(1);
  });

  it('130000字返回65章', () => {
    expect(calcChapters(130000)).toBe(65);
  });

  it('340000字返回170章', () => {
    expect(calcChapters(340000)).toBe(170);
  });
});

describe('getChapterWordsRange', () => {
  it('默认每章2000字，返回±50%浮动', () => {
    const range = getChapterWordsRange();
    expect(range.min).toBe(1000);
    expect(range.max).toBe(3000);
  });

  it('自定义每章字数', () => {
    const range = getChapterWordsRange(2000);
    expect(range.min).toBe(1000);
    expect(range.max).toBe(3000);
  });

  it('10000字每章返回正确范围', () => {
    const range = getChapterWordsRange(10000);
    expect(range.min).toBe(5000);
    expect(range.max).toBe(15000);
  });
});

describe('calcAudioMinutes', () => {
  it('根据200字/分钟计算音频时长', () => {
    expect(calcAudioMinutes(200)).toBe(1);
    expect(calcAudioMinutes(1000)).toBe(5);
    expect(calcAudioMinutes(10000)).toBe(50);
  });

  it('向上取整', () => {
    // Math.round(201/200) = Math.round(1.005) = 1 (浮点精度)
    // 只有超过 1.5（即 300 字）才会取整为 2
    expect(calcAudioMinutes(201)).toBe(1);
    expect(calcAudioMinutes(250)).toBe(1);
    expect(calcAudioMinutes(300)).toBe(2); // Math.round(300/200) = Math.round(1.5) = 2
    expect(calcAudioMinutes(199)).toBe(1);
  });

  it('130000字返回650分钟', () => {
    expect(calcAudioMinutes(130000)).toBe(650);
  });
});

describe('BOOK_TYPE_CONFIG', () => {
  it('包含13种书籍类型', () => {
    expect(Object.keys(BOOK_TYPE_CONFIG).length).toBe(13);
  });

  it('标准130000字配置正确', () => {
    const config = BOOK_TYPE_CONFIG['130000'];
    expect(config.key).toBe('130000');
    expect(config.totalWords).toBe(130000);
    expect(config.chapters).toBe(65);
    expect(config.audioMinutes).toBe(650);
    expect(config.isShortArticle).toBe(false);
  });

  it('小字数配置标记为 isShortArticle', () => {
    const config = BOOK_TYPE_CONFIG['7000'];
    expect(config.isShortArticle).toBe(true);
    expect(config.readingDifficulty).toBe('极低');
  });

  it('所有配置都有必要字段', () => {
    Object.values(BOOK_TYPE_CONFIG).forEach(config => {
      expect(config).toHaveProperty('key');
      expect(config).toHaveProperty('label');
      expect(config).toHaveProperty('description');
      expect(config).toHaveProperty('chapters');
      expect(config).toHaveProperty('totalWords');
      expect(config).toHaveProperty('chapterWords');
      expect(config).toHaveProperty('audioMinutes');
      expect(config).toHaveProperty('structureFormat');
      expect(config).toHaveProperty('readingDifficulty');
      expect(config).toHaveProperty('isShortArticle');
    });
  });
});

describe('getBookTypeConfig', () => {
  it('根据key获取配置', () => {
    const config = getBookTypeConfig('130000');
    expect(config.key).toBe('130000');
    expect(config.totalWords).toBe(130000);
  });

  it('未知key返回默认配置（130000标准版）', () => {
    const config = getBookTypeConfig('unknown');
    expect(config.key).toBe('130000'); // 默认标准版
    expect(config.label).toBe('标准');
  });

  it('数字字符串返回计算配置（自定义标签）', () => {
    // 数字字符串被当作自定义处理，返回计算的配置
    const config = getBookTypeConfig('50000');
    expect(config.key).toBe('50000');
    expect(config.totalWords).toBe(50000);
    expect(config.label).toBe('自定义'); // 数字字符串统一返回"自定义"
  });

  it('自定义字数返回自定义配置', () => {
    const config = getBookTypeConfig('250000');
    expect(config.key).toBe('250000');
    expect(config.totalWords).toBe(250000);
    expect(config.label).toBe('自定义');
  });

  it('小于10000字标记为 isShortArticle', () => {
    const config = getBookTypeConfig('5000');
    expect(config.isShortArticle).toBe(true);
  });

  it('大于10000字标记为非 isShortArticle', () => {
    const config = getBookTypeConfig('15000');
    expect(config.isShortArticle).toBe(false);
  });
});

describe('getAllBookTypes', () => {
  it('返回所有类型配置', () => {
    const allTypes = getAllBookTypes();
    expect(allTypes.length).toBe(13);
  });

  it('包含标准版', () => {
    const allTypes = getAllBookTypes();
    const standard = allTypes.find(t => t.key === '130000');
    expect(standard).toBeDefined();
    expect(standard?.label).toBe('标准');
  });
});

describe('getDetectableTypes', () => {
  it('返回可检测类型列表', () => {
    const detectable = getDetectableTypes();
    expect(detectable.length).toBe(13);
  });

  it('返回值是配置对象数组', () => {
    const detectable = getDetectableTypes();
    detectable.forEach(config => {
      expect(config).toHaveProperty('key');
      expect(config).toHaveProperty('totalWords');
    });
  });
});

describe('getScaleConfig', () => {
  it('返回规模配置', () => {
    const scale = getScaleConfig('130000');
    expect(scale).toHaveProperty('chapters');
    expect(scale).toHaveProperty('totalWords');
    expect(scale).toHaveProperty('chapterWords');
    expect(scale).toHaveProperty('isShortArticle');
  });

  it('130000字返回正确章节数', () => {
    const scale = getScaleConfig('130000');
    expect(scale.chapters).toBe(65);
    expect(scale.totalWords).toBe(130000);
  });
});

describe('estimateBookWords', () => {
  it('返回字数估算 (min/max/avg)', () => {
    const estimate = estimateBookWords('130000');
    expect(estimate).toHaveProperty('min');
    expect(estimate).toHaveProperty('max');
    expect(estimate).toHaveProperty('avg');
  });

  it('130000字估算结果正确', () => {
    const estimate = estimateBookWords('130000');
    expect(estimate.min).toBe(130000);
    expect(estimate.max).toBe(130000);
    expect(estimate.avg).toBe(130000);
  });

  it('不同规模返回正确估算', () => {
    const small = estimateBookWords('3000');
    expect(small.avg).toBe(3000);

    const large = estimateBookWords('340000');
    expect(large.avg).toBe(340000);
  });
});

describe('GLOBAL_ABSOLUTE_WORD_LIMIT', () => {
  it('全局上限为500000字', () => {
    expect(GLOBAL_ABSOLUTE_WORD_LIMIT).toBe(500000);
  });
});

describe('getBookWordLimit', () => {
  it('返回全局字数上限', () => {
    expect(getBookWordLimit()).toBe(500000);
  });
});

describe('书籍类型边界计算', () => {
  it('1000字下9配置正确', () => {
    const config = getBookTypeConfig('1000');
    expect(config.totalWords).toBe(1000);
    expect(config.chapters).toBe(1);
    expect(config.audioMinutes).toBe(5);
  });

  it('340000字上2配置正确', () => {
    const config = getBookTypeConfig('340000');
    expect(config.totalWords).toBe(340000);
    expect(config.chapters).toBe(170);
    expect(config.audioMinutes).toBe(1700);
  });
});