import streamlit as st
import requests
from bs4 import BeautifulSoup
import os
import docx
from PIL import Image
import io
import pytesseract
from pdf2image import convert_from_path
import random
import tempfile
import shutil
import threading
from concurrent.futures import ThreadPoolExecutor, as_completed

# Устанавливаем путь к исполняемому файлу Tesseract OCR
pytesseract.pytesseract.tesseract_cmd = r"/usr/bin/tesseract"  # Укажите путь к tesseract в вашей системе

# Настройка заголовка приложения
st.set_page_config(page_title="Система обработки учебных материалов", layout="wide")
st.title("Система обработки учебных материалов")

# Функция поиска учебников
def search_textbooks(keywords, year):
    # Используем альтернативный метод поиска, например, через API какого-либо открытого ресурса
    # Поскольку прямой парсинг Google запрещен, здесь мы будем использовать Open Library Search API
    base_url = "http://openlibrary.org/search.json"
    params = {
        'title': keywords,
        'language': 'rus',
        'published_in': str(year)
    }
    response = requests.get(base_url, params=params)
    if response.status_code != 200:
        st.error("Ошибка при поиске учебников")
        return []

    data = response.json()
    textbooks = []
    for doc in data.get('docs', []):
        title = doc.get('title')
        authors = doc.get('author_name', [])
        publish_year = doc.get('first_publish_year')
        if title and publish_year and publish_year >= year:
            textbooks.append({
                'title': title,
                'authors': ", ".join(authors),
                'year': publish_year,
                'url': f"http://openlibrary.org{doc.get('key')}"
            })
    return textbooks

# Оптимизированная функция для конвертации PDF в DOCX
@st.cache(allow_output_mutation=True)
def convert_to_doc(file):
    try:
        with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
            tmp_file.write(file.read())
            tmp_file_path = tmp_file.name

        images = convert_from_path(tmp_file_path, dpi=300)
        
        def process_image(image):
            return pytesseract.image_to_string(image, lang='rus')

        with ThreadPoolExecutor(max_workers=4) as executor:
            future_to_image = {executor.submit(process_image, image): image for image in images}
            text_parts = []
            for future in as_completed(future_to_image):
                text_parts.append(future.result())

        text = "\n".join(text_parts)

        doc = docx.Document()
        doc.add_paragraph(text)
        output_path = "converted_file.docx"
        doc.save(output_path)
        return output_path
    except Exception as e:
        st.error(f"Ошибка при конвертации: {e}")
        return None
    finally:
        if 'tmp_file_path' in locals():
            os.unlink(tmp_file_path)

# Оптимизированная функция для разделения на главы
def split_into_chapters(doc_file):
    try:
        doc = docx.Document(doc_file)
        chapters = []
        current_chapter = []
        for para in doc.paragraphs:
            if para.style.name.startswith('Heading'):
                if current_chapter:
                    chapters.append("\n".join(current_chapter))
                    current_chapter = []
            current_chapter.append(para.text)
            
            # Добавляем проверку прогресса
            if len(chapters) % 10 == 0:
                yield len(chapters)  # Возвращаем прогресс
        
        if current_chapter:
            chapters.append("\n".join(current_chapter))
        
        yield chapters  # Возвращаем финальный результат
    except Exception as e:
        st.error(f"Ошибка при разделении на главы: {e}")
        yield []

# Функция для генерации тестовых вопросов
def generate_test(chapters, num_questions_per_chapter):
    questions = []
    for idx, chapter in enumerate(chapters):
        # Разбиваем текст главы на предложения
        sentences = chapter.split('.')
        random.shuffle(sentences)
        # Извлекаем первые N предложений для создания вопросов
        for i in range(min(num_questions_per_chapter, len(sentences))):
            sentence = sentences[i].strip()
            if len(sentence) > 20:
                question = f"Что подразумевается под следующим утверждением: '{sentence}'?"
                questions.append((f"Глава {idx+1}", question))
    return questions

# Интерфейс поиска учебников
st.header("1. Поиск учебников")
keywords = st.text_input("Введите ключевые слова для поиска:")
year = st.number_input("Минимальный год издания:", min_value=1900, max_value=2023, value=2019)
if st.button("Поиск"):
    results = search_textbooks(keywords, year)
    st.write("Результаты поиска:")
    if results:
        for book in results:
            st.markdown(f"**{book['title']}**")
            st.write(f"Авторы: {book['authors']}")
            st.write(f"Год издания: {book['year']}")
            st.write(f"[Перейти к источнику]({book['url']})")
            st.write("---")
    else:
        st.write("Учебники не найдены. Попробуйте изменить параметры поиска.")

# Оптимизированный интерфейс загрузки и обработки файлов
st.header("2. Загрузка и обработка файлов")
uploaded_file = st.file_uploader("Выберите файл для загрузки", type=["pdf"])
if uploaded_file is not None:
    st.write(f"Файл **{uploaded_file.name}** успешно загружен")
    if st.button("Конвертировать и обработать файл"):
        progress_bar = st.progress(0)
        status_text = st.empty()
        
        status_text.text("Конвертация файла...")
        doc_file = convert_to_doc(uploaded_file)
        
        if doc_file:
            st.write(f"Файл конвертирован: {doc_file}")
            status_text.text("Разделение на главы...")
            
            chapter_generator = split_into_chapters(doc_file)
            chapters = []
            for result in chapter_generator:
                if isinstance(result, int):
                    progress = min(result / 100, 0.9)  # Предполагаем максимум 100 глав
                    progress_bar.progress(progress)
                else:
                    chapters = result
            
            progress_bar.progress(1.0)
            status_text.text("Обработка завершена!")
            
            if chapters:
                st.write("Файл разделен на главы:")
                for i, chapter in enumerate(chapters, 1):
                    st.markdown(f"### Глава {i}")
                    st.write(chapter[:500] + "...")  # Выводим первые 500 символов каждой главы
            else:
                st.error("Не удалось разделить документ на главы.")
        else:
            st.error("Не удалось конвертировать файл.")

# Интерфейс генерации тестов
st.header("3. Генерация тестов")
if 'chapters' in locals() and chapters:
    num_questions = st.slider("Выберите количество вопросов на главу:", min_value=1, max_value=10, value=5)
    if st.button("Сгенерировать тест"):
        questions = generate_test(chapters, num_questions)
        if questions:
            st.write("Сгенерированные вопросы:")
            for chapter_title, question in questions:
                st.markdown(f"**{chapter_title}**")
                st.write(question)
                st.write("---")
            # Сохраняем вопросы в файл
            test_doc = docx.Document()
            test_doc.add_heading("Тестовые вопросы", level=1)
            for chapter_title, question in questions:
                test_doc.add_paragraph(f"{chapter_title}\n{question}")
            test_doc_path = "test_questions.docx"
            test_doc.save(test_doc_path)
            with open(test_doc_path, "rb") as f:
                st.download_button(
                    label="Скачать файл с вопросами",
                    data=f,
                    file_name="test_questions.docx",
                    mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
                )
        else:
            st.error("Не удалось сгенерировать вопросы.")
else:
    st.info("Сначала загрузите и обработайте файл для генерации тестов.")

# Дополнительная информация
st.sidebar.header("О приложении")
st.sidebar.info(
    "Это система обработки учебных материалов. Вы можете искать учебники, загружать и обрабатывать свои файлы, а также генерировать тестовые вопросы на основе содержимого."
) приразделении пдф файла на глав скрипт зависает сделай масимальную оптимизацию процессе разделения на главы