import pdfplumber
import re
from collections import defaultdict

class PDFTextExtractor:
    def __init__(self, pdf_path):
        """
        PDFテキスト抽出クラスの初期化
        
        Args:
            pdf_path (str): PDFファイルのパス
        """
        self.pdf_path = pdf_path
        self.pdf = pdfplumber.open(pdf_path)
        
    def extract_basic_text(self):
        """
        基本的なテキスト抽出を行う
        
        Returns:
            list: ページごとのテキストのリスト
        """
        text_by_page = []
        for page in self.pdf.pages:
            text = page.extract_text()
            if text:
                text_by_page.append(text.strip())
        return text_by_page
    
    def extract_structured_text(self):
        """
        構造化されたテキスト抽出を行う
        段落、ヘッダー、フッターなどを識別
        
        Returns:
            dict: 構造化されたテキスト情報
        """
        structured_content = defaultdict(list)
        
        for page_num, page in enumerate(self.pdf.pages, 1):
            # テキストブロックを抽出
            text_blocks = page.extract_words(
                keep_blank_chars=True,
                x_tolerance=3,
                y_tolerance=3
            )
            
            # ページの寸法を取得
            page_height = page.height
            page_width = page.width
            
            # テキストブロックを位置に基づいて分類
            for block in text_blocks:
                # 位置情報
                x0, top, x1, bottom = block['x0'], block['top'], block['x1'], block['bottom']
                text = block['text']
                
                # ヘッダーの判定（ページ上部20%以内）
                if top < page_height * 0.2:
                    structured_content['headers'].append({
                        'page': page_num,
                        'text': text,
                        'position': (x0, top, x1, bottom)
                    })
                
                # フッターの判定（ページ下部20%以内）
                elif bottom > page_height * 0.8:
                    structured_content['footers'].append({
                        'page': page_num,
                        'text': text,
                        'position': (x0, top, x1, bottom)
                    })
                
                # 本文の判定
                else:
                    structured_content['body'].append({
                        'page': page_num,
                        'text': text,
                        'position': (x0, top, x1, bottom)
                    })
        
        return structured_content
    
    def format_text(self, text, formatting_options=None):
        """
        テキストを整形する
        
        Args:
            text (str): 整形する対象のテキスト
            formatting_options (dict): 整形オプション
        
        Returns:
            str: 整形されたテキスト
        """
        if formatting_options is None:
            formatting_options = {
                'remove_extra_spaces': True,
                'normalize_newlines': True,
                'remove_empty_lines': True,
                'join_hyphenated_words': True
            }
        
        # 余分な空白の削除
        if formatting_options.get('remove_extra_spaces'):
            text = re.sub(r'\s+', ' ', text)
        
        # 改行の正規化
        if formatting_options.get('normalize_newlines'):
            text = re.sub(r'\r\n|\r|\n', '\n', text)
        
        # 空行の削除
        if formatting_options.get('remove_empty_lines'):
            text = re.sub(r'\n\s*\n', '\n', text)
        
        # ハイフネーションの結合
        if formatting_options.get('join_hyphenated_words'):
            text = re.sub(r'(\w)-\n(\w)', r'\1\2', text)
        
        return text.strip()
    
    def extract_tables(self):
        """
        PDFから表を抽出する
        
        Returns:
            list: 表データのリスト
        """
        tables = []
        for page_num, page in enumerate(self.pdf.pages, 1):
            found_tables = page.extract_tables()
            if found_tables:
                tables.extend({
                    'page': page_num,
                    'table': table
                } for table in found_tables)
        return tables
    
    def close(self):
        """
        PDFファイルを閉じる
        """
        self.pdf.close()

def process_pdf_text(pdf_path, custom_formatting=None):
    """
    PDFを処理して整形されたテキストを取得する
    
    Args:
        pdf_path (str): PDFファイルのパス
        custom_formatting (dict): カスタム整形オプション
    
    Returns:
        dict: 処理結果
    """
    extractor = PDFTextExtractor(pdf_path)
    
    try:
        # 基本テキストの抽出と整形
        basic_text = extractor.extract_basic_text()
        formatted_text = [extractor.format_text(text, custom_formatting) 
                         for text in basic_text]
        
        # 構造化テキストの抽出
        structured_content = extractor.extract_structured_text()
        
        # 表の抽出
        tables = extractor.extract_tables()
        
        return {
            'formatted_text': formatted_text,
            'structured_content': structured_content,
            'tables': tables
        }
        
    finally:
        extractor.close()

# 使用例
if __name__ == "__main__":
    # カスタム整形オプションの設定例
    custom_format_options = {
        'remove_extra_spaces': True,
        'normalize_newlines': True,
        'remove_empty_lines': True,
        'join_hyphenated_words': True
    }
    
    # PDFの処理
    result = process_pdf_text('/var/www/html/zoom/staging/※取扱注意※【エージェント様向け】 Visional_26卒ビジネス職新卒採用共有.pdf', custom_format_options)
    
    # 結果の出力例
    print("=== Formatted Text ===")
    for page_num, text in enumerate(result['formatted_text'], 1):
        print(f"Page {page_num}:")
        print(text)
        print("-" * 50)