#!/usr/bin/env python3
"""
Скрипт для получения статистики по главам EPUB книги.

Использование:
    python statistics.py <путь_к_epub_файлу>
    python statistics.py book.epub
"""
import sys
import json
import argparse
import re
from pathlib import Path
from typing import Dict, Any, List
from ebooklib import epub

# Импортируем функции из app.py
from app import parse_epub_content, calculate_chapter_tokens


def sanitize_filename(title: str, max_length: int = 100) -> str:
    """Очищает название книги для использования в имени файла.
    
    Удаляет недопустимые символы и ограничивает длину имени файла.
    
    Args:
        title: Название книги для очистки.
        max_length: Максимальная длина имени файла.
        
    Returns:
        Безопасное имя файла.
    """
    if not title:
        return 'book_statistics'
    
    # Удаляем недопустимые символы для имени файла
    # Оставляем буквы, цифры, пробелы, дефисы, подчеркивания
    sanitized = re.sub(r'[<>:"/\\|?*]', '', title)
    
    # Заменяем множественные пробелы на один
    sanitized = re.sub(r'\s+', ' ', sanitized)
    
    # Убираем пробелы в начале и конце
    sanitized = sanitized.strip()
    
    # Ограничиваем длину
    if len(sanitized) > max_length:
        sanitized = sanitized[:max_length].rstrip()
    
    # Если после очистки ничего не осталось, используем дефолтное имя
    if not sanitized:
        sanitized = 'book_statistics'
    
    return sanitized


def format_statistics(title: str, author: str, chapters: List[Dict[str, Any]]) -> Dict[str, Any]:
    """Форматирует статистику по книге и главам.
    
    Args:
        title: Название книги.
        author: Автор книги.
        chapters: Список глав с данными.
        
    Returns:
        Словарь со статистикой в формате JSON.
    """
    # Статистика по главам
    chapters_stats: List[Dict[str, Any]] = []
    total_chars = 0
    total_tokens = 0
    
    for chapter in chapters:
        chapter_text = chapter.get('text', '')
        chapter_title = chapter.get('chapterTitle', 'Глава без названия')
        chapter_number = chapter.get('chapterNumber', 0)
        footnotes_count = chapter.get('footnotesCount', 0)
        token_count = chapter.get('tokenCount', 0)
        
        # Подсчитываем символы (включая пробелы)
        char_count = len(chapter_text)
        
        # Если tokenCount не был подсчитан, подсчитываем сейчас
        if token_count == 0 and chapter_text:
            chapter_data = {
                'text': chapter_text,
                'chapterTitle': chapter_title,
                'chapterId': chapter.get('chapterId', ''),
                'chapterNumber': chapter_number,
                'filePath': chapter.get('filePath', ''),
                'footnotes': chapter.get('footnotes', [])
            }
            token_count = calculate_chapter_tokens(chapter_data)
        
        total_chars += char_count
        total_tokens += token_count
        
        chapters_stats.append({
            'chapterNumber': chapter_number,
            'chapterTitle': chapter_title,
            'characters': char_count,
            'tokens': token_count,
            'footnotesCount': footnotes_count,
            'filePath': chapter.get('filePath', '')
        })
    
    # Общая статистика
    result: Dict[str, Any] = {
        'book': {
            'title': title,
            'author': author,
            'totalChapters': len(chapters),
            'totalCharacters': total_chars,
            'totalTokens': total_tokens
        },
        'chapters': chapters_stats
    }
    
    return result


def main():
    """Основная функция скрипта."""
    parser = argparse.ArgumentParser(
        description='Получение статистики по главам EPUB книги',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Примеры использования:
  python statistics.py book.epub
  python statistics.py /path/to/book.epub --output stats.json
  python statistics.py book.epub --stdout
        """
    )
    parser.add_argument(
        'epub_file',
        type=str,
        help='Путь к EPUB файлу'
    )
    parser.add_argument(
        '-o', '--output',
        type=str,
        default=None,
        help='Путь к выходному JSON файлу (если не указан, создается файл с названием книги)'
    )
    parser.add_argument(
        '--stdout',
        action='store_true',
        help='Вывести результат в stdout вместо сохранения в файл'
    )
    parser.add_argument(
        '--compact',
        action='store_true',
        help='Сохранить JSON в компактном формате (без отступов)'
    )
    
    args = parser.parse_args()
    
    # Проверяем существование файла
    epub_path = Path(args.epub_file)
    if not epub_path.exists():
        print(f"Ошибка: Файл '{epub_path}' не найден.", file=sys.stderr)
        sys.exit(1)
    
    if not epub_path.is_file():
        print(f"Ошибка: '{epub_path}' не является файлом.", file=sys.stderr)
        sys.exit(1)
    
    try:
        # Читаем и парсим EPUB
        book = epub.read_epub(str(epub_path))
        title, author, metadata, chapters = parse_epub_content(book)
        
        # Формируем статистику
        statistics = format_statistics(title, author, chapters)
        
        # Выводим результат
        if args.compact:
            json_output = json.dumps(statistics, ensure_ascii=False)
        else:
            json_output = json.dumps(statistics, ensure_ascii=False, indent=2)
        
        # Определяем путь к выходному файлу
        if args.stdout:
            # Выводим в stdout
            print(json_output)
        else:
            if args.output:
                # Используем указанный путь
                output_path = Path(args.output)
            else:
                # Создаем имя файла на основе названия книги
                safe_title = sanitize_filename(title)
                output_path = Path(f"{safe_title}_statistics.json")
            
            # Сохраняем в файл
            output_path.parent.mkdir(parents=True, exist_ok=True)
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(json_output)
            print(f"Статистика сохранена в файл: {output_path}")
    
    except Exception as e:
        print(f"Ошибка при обработке EPUB файла: {e}", file=sys.stderr)
        import traceback
        traceback.print_exc()
        sys.exit(1)


if __name__ == '__main__':
    main()
