#
# convert HTML to PDF
#
import os
import chardet
from xhtml2pdf import pisa
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from bs4 import BeautifulSoup

# ミラーリングしたフォルダのパスを指定
mirrored_folder_path = './ss1.xrea.com'

# 出力フォルダのパスを指定
output_folder_path = './pdf_output'

def register_fonts():
    pdfmetrics.registerFont(TTFont('IPAexGothic', 'ipaexg.ttf'))
    pdfmetrics.registerFont(TTFont('IPAexMincho', 'ipaexm.ttf'))

def add_font_face_css(html_content):
    font_face_css = """
    <style>
    @font-face {
        font-family: "IPAexGothic";
        src: url("ipaexg.ttf");
    }
    body {
        font-family: IPAexGothic, sans-serif;
        font-size: 12pt;
        line-height: 1.5;
    }
    </style>
    """
    soup = BeautifulSoup(html_content, 'html.parser')
    head = soup.find('head')
    if head:
        head.insert(0, BeautifulSoup(font_face_css, 'html.parser'))
    else:
        body = soup.find('body')
        if body:
            body.insert(0, BeautifulSoup(font_face_css, 'html.parser'))
        else:
            soup.insert(0, BeautifulSoup(font_face_css, 'html.parser'))
    return str(soup)

def detect_encoding(file_path):
    """
    ファイルのエンコーディングを検出する関数
    """
    with open(file_path, 'rb') as f:
        result = chardet.detect(f.read())
    return result['encoding']

def read_file_with_encoding(file_path):
    """
    ファイルを指定されたエンコーディングで読み込む関数
    """
    encoding = detect_encoding(file_path)
    try:
        with open(file_path, 'r', encoding=encoding) as f:
            return f.read()
    except UnicodeDecodeError:
        # エンコーディングの検出に失敗した場合、SJISで試す
        try:
            with open(file_path, 'r', encoding='shift_jis') as f:
                return f.read()
        except UnicodeDecodeError:
            # それでも失敗した場合、UTF-8で試す
            with open(file_path, 'r', encoding='utf-8') as f:
                return f.read()

def flatten_nested_tables(table):
    """
    入れ子になったテーブルをフラット化する関数
    """
    # 表の内容をHTMLタグを含むテキストとして抽出
    html_content = ""
    for row in table.find_all('tr'):
        for cell in row.find_all(['th', 'td']):
            # セル内のテーブルを再帰的に処理
            nested_tables = cell.find_all('table')
            for nested_table in nested_tables:
                html_content += flatten_nested_tables(nested_table)
            # セルの内容を追加
            html_content += str(cell)
        html_content += "\n"
    return html_content

def convert_html_to_pdf(html_file_path, output_pdf_path):
    try:
        # ファイルを適切なエンコーディングで読み込む
        html_content = read_file_with_encoding(html_file_path)

        # HTMLコンテンツをUTF-8に変換
        html_content = html_content.encode('utf-8').decode('utf-8')

        # 表をテキストとして扱うための処理
        soup = BeautifulSoup(html_content, 'html.parser')
        tables = soup.find_all('table')

        for table in tables:
            # 表の内容をフラット化
            flat_content = flatten_nested_tables(table)

            # 表をフラット化した内容で置換
            parent = table.parent
            if parent:
                new_div = BeautifulSoup(f"<div>{flat_content}</div>", 'html.parser')
                parent.insert(parent.index(table), new_div)
                table.decompose()  # 表を削除

        html_content = str(soup)
        html_content = add_font_face_css(html_content)

        # デバッグ用
        #with open(output_pdf_path + ".html", 'w') as html_file:
        #    html_file.write(html_content)

        with open(output_pdf_path, 'wb') as pdf_file:
            pisa_status = pisa.CreatePDF(
                html_content,
                dest=pdf_file,
                encoding='utf-8',
                font_path='ipaexg.ttf',
                font_name='IPAexGothic'
            )
            if pisa_status.err:
                print(f"PDF変換エラー: {html_file_path} -> {pisa_status.err}")
    except Exception as e:
        print(f"エラー: {html_file_path} -> {str(e)}")

def create_directory_structure(input_dir, output_dir):
    for root, dirs, files in os.walk(input_dir):
        relative_path = os.path.relpath(root, input_dir)
        output_subdir = os.path.join(output_dir, relative_path)
        if not os.path.exists(output_subdir):
            os.makedirs(output_subdir)

def process_html_files_in_directory(input_directory_path, output_directory_path):
    # フォントの登録
    register_fonts()

    # ディレクトリ構造を作成
    create_directory_structure(input_directory_path, output_directory_path)

    for root, _, files in os.walk(input_directory_path):
        for file in files:
            if file.endswith('.html'):
                html_file_path = os.path.join(root, file)
                relative_path = os.path.relpath(root, input_directory_path)
                output_subdir = os.path.join(output_directory_path, relative_path)
                pdf_file_name = os.path.splitext(file)[0] + '.pdf'
                pdf_file_path = os.path.join(output_subdir, pdf_file_name)

                convert_html_to_pdf(html_file_path, pdf_file_path)
                print(f"変換完了: {html_file_path} -> {pdf_file_path}")

if __name__ == '__main__':
    # HTML ファイルを PDF に変換
    process_html_files_in_directory(mirrored_folder_path, output_folder_path)
