import os
import sys
from dotenv import load_dotenv
import pathlib
import chardet
import re
import google.generativeai as genai

from tkai_lib import *


input_path = "input.txt"
output_path = None

config_path = "translate.env"
if not os.path.exists(config_path):
    script_dir = pathlib.Path(__file__).parent
    config_path = script_dir / config_path

gemini_model = 'gemini-2.5-flash'
# AIへのプロンプトテンプレート
PROMPT_TEMPLATE = """
あなたは半導体の専門家で、特に専門用語の使い方については熟知しています。
以下の文章は文字起こしをしたもので多くの誤字・誤変換を含んでいますが、文脈を理解し、半導体専門家の講義として適切な内容に直してください。
発言者を推測するとともに、なるべくもとの発言の文章に忠実に単語等を修正してください。全ての文章の修正をお願いします

---
文字起こしテキスト:
{{content}}
---

修正後テキスト（発言者と講義内容として自然な形に修正）:
"""

show_api_key = True

# 各チャンクに投入する最大バイト数（目安）。Geminiのトークン数制限を考慮。
MAX_BYTES_PER_CHUNK = 20000
# チャンク間のオーバーラップ行数。
OVERLAP_LINES = 5


model = genai.GenerativeModel(gemini_model)
read_ai_config(config_path)
if show_api_key:
    print(f"GOOGLE_API_KEY: {os.environ.get('GOOGLE_API_KEY', 'not set')}")
    print(f"OPENAI_API_KEY: {os.environ.get('OPENAI_API_KEY', 'not set')}")

argv = sys.argv
nargv = len(argv)
if nargv > 1:
    input_path = argv[1]
if nargv > 2:
    output_path = argv[2]

if output_path is None:
    input_file = pathlib.Path(input_path)
    output_path = os.path.join(input_file.parent, f"{input_file.stem}-corrected.txt")

print()
print(f"入力ファイル: {input_path}")
print(f"出力ファイル: {output_path}")

try:
    genai.configure(api_key=os.environ["GOOGLE_API_KEY"])
except KeyError:
    print("エラー: APIキーが設定されていません。環境変数 'GOOGLE_API_KEY' を設定してください。")
    sys.exit(1)

def correct_semiconductor_text_chunked(input_path: str, output_path: str, max_bytes_per_chunk: int, overlap_lines: int, prompt_template: str):
    """
    半導体専門家として文字起こしテキストの誤字・誤変換を修正し、講義として適切な内容に変換します。
    大きなファイルをチャンクに分割して処理します。

    Args:
        input_path (str): 読み込む入力ファイルのパス。
        output_path (str): 結果を保存する出力ファイルのパス。
        max_bytes_per_chunk (int): 各チャンクの最大バイト数（目安）。
        overlap_lines (int): チャンク間のオーバーラップ行数。
        prompt_template (str): テキスト挿入用のプレースホルダーを含むプロンプトテンプレート。
    """

    try:
        with open(input_path, "rb") as f:
            raw_content = f.read()
            result = chardet.detect(raw_content)
            encoding = result['encoding']
            print(f"推定文字コード: {encoding}")
    except FileNotFoundError:
        print(f"エラー: 入力ファイル '{input_path}' が見つかりません。")
        return
    except Exception as e:
        print(f"入力ファイルの文字コード推定中にエラーが発生しました: {e}")
        return

    try:
        with open(input_path, 'r', encoding=encoding) as f:
            lines = f.readlines()
    except Exception as e:
        print(f"入力ファイルの読み込み中にエラーが発生しました: {e}")
        return

    total_lines = len(lines)
    corrected_full_text = []
    current_line_index = 0
    chunk_count = 0

    print("AIによる修正を開始します。ファイルサイズにより時間がかかります...")

    while current_line_index < total_lines:
        chunk_count += 1
        # start_line_for_chunk は、デバッグ表示用として残しておきます
        start_line_for_chunk = current_line_index

        # オーバーラップ部分の追加
        if current_line_index > 0 and overlap_lines > 0:
            start_line_for_overlap = max(0, current_line_index - overlap_lines)
            chunk_content_lines = list(lines[start_line_for_overlap : current_line_index])
        else:
            chunk_content_lines = []

        # 現在のチャンクの本文を追加
        temp_current_line_index = current_line_index
        while temp_current_line_index < total_lines:
            line_to_add = lines[temp_current_line_index]
            # 新しい行を追加した場合のバイト数をチェック
            test_content = "".join(chunk_content_lines + [line_to_add])
            if len(test_content.encode(encoding)) <= max_bytes_per_chunk:
                chunk_content_lines.append(line_to_add)
                temp_current_line_index += 1
            else:
                break

        chunk_content = "".join(chunk_content_lines)

        # チャンクが空の場合は処理をスキップ
        if not chunk_content.strip():
            current_line_index = temp_current_line_index
            continue

        end_line_for_chunk = temp_current_line_index
        print(f"--- チャンク {chunk_count} の処理 ({start_line_for_chunk + 1}行目〜{end_line_for_chunk}行目) ---")
        print(f"チャンク内容バイト数: {len(chunk_content.encode(encoding))} バイト")

        # re.sub を使用してプレースホルダーを置換
        prompt = re.sub(r'\{\{content\}\}', chunk_content, prompt_template)

        try:
            response = model.generate_content(prompt)
            corrected_chunk_text = response.text

            # オーバーラップ部分を考慮した修正結果の追加
            # ここが重要です。Geminiがオーバーラップ部分を修正して返す場合、
            # 単純に結合すると重複が生じます。
            # 理想的には、Geminiに「本編だけ修正し、参照部分はそのまま出力しろ」と指示するか、
            # 修正されたテキストからオーバーラップ部分を正確に特定し除去する必要があります。
            # しかし、Geminiの修正でテキストが変わるため、厳密な行数での除去は困難です。
            
            # 今回の修正では、シンプルに修正されたテキストを全て結合します。
            # 必要であれば、結合後に重複部分を手動で調整するか、
            # より高度なオーバーラップ除去ロジックを検討してください。
            corrected_full_text.append(corrected_chunk_text)

            current_line_index = end_line_for_chunk # 次のチャンクの開始位置を更新

        except Exception as e:
            print(f"エラー: AIによるテキスト修正中にエラーが発生しました（チャンク {chunk_count}）: {e}")
            print("このチャンクはスキップされます。")
            current_line_index = end_line_for_chunk
            time.sleep(5)

    final_corrected_text = "".join(corrected_full_text)

    try:
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(final_corrected_text)
        print(f"\n修正されたテキストが '{output_path}' に保存されました。")
    except Exception as e:
        print(f"エラー: 出力ファイルの書き込み中にエラーが発生しました: {e}")

if __name__ == "__main__":
    correct_semiconductor_text_chunked(input_path, output_path, MAX_BYTES_PER_CHUNK, OVERLAP_LINES, PROMPT_TEMPLATE)
    