#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import fitz  # PyMuPDF for PDF handling
import ebooklib
from ebooklib import epub
from bs4 import BeautifulSoup
from odf import opendocument, teletype, text
import docx

class FileParser:
    """
    A utility class to extract plain text from various document formats
    including TXT, PDF, EPUB, ODT, and DOCX.
    """

    @staticmethod
    def extract_text(file_path):
        """
        Main entry point: detects the file extension and selects the appropriate parser.
        """
        if not file_path or not os.path.exists(file_path):
            return ""

        ext = os.path.splitext(file_path)[1].lower()
        
        try:
            if ext == ".txt":
                return FileParser._parse_txt(file_path)
            elif ext == ".pdf":
                return FileParser._parse_pdf(file_path)
            elif ext == ".epub":
                return FileParser._parse_epub(file_path)
            elif ext == ".odt":
                return FileParser._parse_odt(file_path)
            elif ext == ".docx":
                return FileParser._parse_docx(file_path)
            elif ext == ".doc":
                return "The .doc format (legacy Word) is not supported. Please save it as .odt or .docx using LibreOffice."
            else:
                return f"Format {ext} not supported."
        except Exception as e:
            return f"Error while reading {ext} file: {str(e)}"

    @staticmethod
    def _parse_txt(file_path):
        """Reads plain text files."""
        with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
            return f.read().strip()

    @staticmethod
    def _parse_pdf(file_path):
        """Extracts text from PDF using PyMuPDF."""
        doc = fitz.open(file_path)
        text = ""
        for page in doc:
            text += page.get_text() + "\n"
        doc.close()
        return text.strip()

    @staticmethod
    def _parse_odt(file_path):
        """Extracts text from LibreOffice ODT files using odfpy."""
        # Load the ODT document
        textdoc = opendocument.load(file_path)
        
        # CORRECT LOGIC: 
        # Paragraphs in ODT are 'text:p' elements, represented by text.P in odfpy
        all_paragraphs = textdoc.getElementsByType(text.P)
        
        extracted_lines = []
        for p in all_paragraphs:
            # Use teletype to extract all text content from the paragraph element
            line = teletype.extractText(p)
            if line.strip():
                extracted_lines.append(line)
        
        return "\n\n".join(extracted_lines).strip()

    @staticmethod
    def _parse_docx(file_path):
        """Extracts text from Microsoft Word DOCX files."""
        doc = docx.Document(file_path)
        full_text = []
        for para in doc.paragraphs:
            full_text.append(para.text)
        return "\n".join(full_text).strip()

    @staticmethod
    def _parse_epub(file_path):
        """Extracts text from EPUB eBooks while cleaning HTML tags."""
        book = epub.read_epub(file_path)
        chapters = []
        for item in book.get_items():
            # Look only for document items (chapters)
            if item.get_type() == ebooklib.ITEM_DOCUMENT:
                soup = BeautifulSoup(item.get_content(), 'html.parser')
                # Remove script and style tags that might be embedded in the EPUB
                for script_or_style in soup(["script", "style"]):
                    script_or_style.decompose()
                chapters.append(soup.get_text())
        
        return "\n\n".join(chapters).strip()
