import os
import shutil
import subprocess
from pathlib import Path
from datetime import datetime
from PIL import Image

BASE_DIR = Path("/home/dayhanbiz/public_html/Библиотека 3-DAMJA")
STORAGE_DIR = Path("/home/dayhanbiz/public_html/3-damja.science/storage")
ARCHIVE_DIR = STORAGE_DIR / "archive_originals"
ARCHIVE_DIR.mkdir(parents=True, exist_ok=True)

SOURCES = [
    STORAGE_DIR / "history_books",
    STORAGE_DIR / "history_pdf",
    STORAGE_DIR / "history_vostlit",
    STORAGE_DIR / "water_vam"
]

SUPPORTED_EXTENSIONS = {'.pdf', '.djvu', '.doc', '.docx', '.txt', '.html', '.htm'}

def compress_pdf_with_ghostscript(input_pdf: Path, output_pdf: Path):
    cmd = [
        "gs",
        "-sDEVICE=pdfwrite",
        "-dCompatibilityLevel=1.4",
        "-dPDFSETTINGS=/ebook",
        "-dNOPAUSE",
        "-dBATCH",
        f"-sOutputFile={output_pdf}",
        str(input_pdf)
    ]
    try:
        subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
        return True
    except Exception as e:
        print(f"   ⚠️ Ошибка сжатия Ghostscript для {input_pdf.name}: {e}")
        return False

def convert_djvu_to_pdf(djvu_path: Path, target_pdf: Path) -> bool:
    """
    Конвертация DjVu через постраничный рендеринг в TIFF с помощью ddjvu,
    и сборка страниц в единый PDF с помощью Python (PIL), что обходит лимиты длины командной строки.
    """
    temp_dir = djvu_path.parent / f"temp_djvu_{djvu_path.stem}"
    temp_dir.mkdir(exist_ok=True)
    temp_raw_pdf = djvu_path.with_suffix(".raw.pdf")
    try:
        # 1. Извлекаем страницы DjVu в виде отдельных tiff файлов
        cmd_render = [
            "ddjvu",
            "-format=tiff",
            "-mode=black",
            str(djvu_path),
            str(temp_dir / "page-%04d.tiff")
        ]
        res = subprocess.run(cmd_render, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        
        if res.returncode != 0:
            cmd_render_color = [
                "ddjvu",
                "-format=tiff",
                "-mode=color",
                str(djvu_path),
                str(temp_dir / "page-%04d.tiff")
            ]
            subprocess.run(cmd_render_color, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

        tiff_files = sorted(list(temp_dir.glob("page-*.tiff")))
        if not tiff_files:
            print(f"   ❌ Не удалось извлечь страницы из DjVu: {djvu_path.name}")
            return False

        # 2. Собираем TIFF страницы в PDF через Python PIL (безопасно для любого числа страниц)
        images = []
        for tiff_file in tiff_files:
            img = Image.open(tiff_file)
            if img.mode in ("RGBA", "P"):
                img = img.convert("RGB")
            images.append(img)

        if images:
            # Сохраняем первую страницу с добавлением остальных
            images[0].save(
                temp_raw_pdf, "PDF", resolution=150.0, save_all=True, append_images=images[1:]
            )
            for img in images:
                img.close()

        # 3. Финальная оптимизация Ghostscript
        if temp_raw_pdf.exists():
            success = compress_pdf_with_ghostscript(temp_raw_pdf, target_pdf)
            temp_raw_pdf.unlink()
            return success
        
        return False
    except Exception as e:
        print(f"   ❌ Ошибка альтернативной конвертации DjVu {djvu_path.name}: {e}")
        return False
    finally:
        if temp_dir.exists():
            shutil.rmtree(temp_dir, ignore_errors=True)

def convert_office_to_pdf(file_path: Path, output_dir: Path) -> bool:
    try:
        cmd = [
            "libreoffice",
            "--headless",
            "--convert-to", "pdf",
            "--outdir", str(output_dir),
            str(file_path)
        ]
        subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        return True
    except Exception as e:
        print(f"   ❌ Ошибка конвертации Office/Text файла {file_path.name}: {e}")
        return False

def run_conversion():
    print("=== Запуск уніфікованого конвертера файлов в PDF (00_converter.py) ===")
    print(f"Время: {datetime.now()}\n")

    for source_dir in SOURCES:
        if not source_dir.exists():
            print(f"⚠️ Директория не найдена: {source_dir}")
            continue

        print(f"📂 Обработка папки: {source_dir.name}")
        
        for file_path in source_dir.rglob("*"):
            if not file_path.is_file() or file_path.suffix.lower() not in SUPPORTED_EXTENSIONS:
                continue
            
            ext = file_path.suffix.lower()
            parent_dir = file_path.parent
            
            if ext == '.pdf':
                continue

            print(f"   🔄 Конвертация: {file_path.name} ({ext})")
            target_pdf = parent_dir / f"{file_path.stem}.pdf"

            success = False
            if ext == '.djvu':
                success = convert_djvu_to_pdf(file_path, target_pdf)
            elif ext in ['.doc', '.docx', '.txt', '.html', '.htm']:
                success = convert_office_to_pdf(file_path, parent_dir)
                if success and ext != '.docx' and ext != '.doc':
                    if target_pdf.exists():
                        temp_opt = parent_dir / f"{file_path.stem}_opt.pdf"
                        if compress_pdf_with_ghostscript(target_pdf, temp_opt):
                            temp_opt.replace(target_pdf)

            if success and target_pdf.exists():
                rel_path = file_path.relative_to(STORAGE_DIR)
                archive_dest = ARCHIVE_DIR / rel_path.parent
                archive_dest.mkdir(parents=True, exist_ok=True)
                
                shutil.move(str(file_path), str(archive_dest / file_path.name))
                print(f"      ✅ Успешно. Оригинал перемещен в архив.")
            else:
                print(f"      ⚠️ Не удалось конвертировать файл: {file_path.name}")

    print("\n=== Конвертация и подготовка файлов завершена ===")

if __name__ == "__main__":
    run_conversion()
