import difflib
import os
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext


class TextDiffApp:

    def __init__(self, root):
        self.root = root
        self.root.title("テキスト差分比較ツール")
        self.root.geometry("900x600")

        # ファイルパスの保存用
        self.file1_path = ""
        self.file2_path = ""

        # 画面のレイアウト作成
        self.create_widgets()

    def create_widgets(self):
        # ----------------------------------------------------
        # 1. 上部：ファイル選択エリア
        # ----------------------------------------------------
        top_frame = tk.Frame(self.root, pady=10)
        top_frame.pack(fill=tk.X)

        # ファイル1の選択
        f1_frame = tk.Frame(top_frame)
        f1_frame.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=10)
        tk.Button(
            f1_frame, text="ファイル1 を選択", command=self.load_file1, width=15
        ).pack(side=tk.LEFT)
        self.lbl_file1 = tk.Label(
            f1_frame, text="選択されていません", fg="gray", anchor="w"
        )
        self.lbl_file1.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)

        # ファイル2の選択
        f2_frame = tk.Frame(top_frame)
        f2_frame.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=10)
        tk.Button(
            f2_frame, text="ファイル2 を選択", command=self.load_file2, width=15
        ).pack(side=tk.LEFT)
        self.lbl_file2 = tk.Label(
            f2_frame, text="選択されていません", fg="gray", anchor="w"
        )
        self.lbl_file2.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)

        # ----------------------------------------------------
        # 2. 中央：テキスト表示エリア (左右2分割)
        # ----------------------------------------------------
        main_frame = tk.Frame(self.root, padx=10)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 左側：ファイル1の中身
        t1_frame = tk.Frame(main_frame)
        t1_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5))
        tk.Label(t1_frame, text="【ファイル1 (比較元)】", font=("Arial", 9, "bold")).pack(
            anchor="w"
        )
        self.txt_file1 = scrolledtext.ScrolledText(
            t1_frame, font=("Consolas", 10), wrap=tk.WORD
        )
        self.txt_file1.pack(fill=tk.BOTH, expand=True)

        # 右側：ファイル2の中身 (結果表示)
        t2_frame = tk.Frame(main_frame)
        t2_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(5, 0))
        tk.Label(
            t2_frame,
            text="【ファイル2 (比較結果: ＋追加 / －削除 / 変更)】",
            font=("Arial", 9, "bold"),
        ).pack(anchor="w")
        self.txt_file2 = scrolledtext.ScrolledText(
            t2_frame, font=("Consolas", 10), wrap=tk.WORD
        )
        self.txt_file2.pack(fill=tk.BOTH, expand=True)

        # 【修正箇所】カラーコードを明確に background と foreground で指定
        self.txt_file2.tag_config(
            "added", background="#e6ffed", foreground="#22863a"
        )  # 追加：薄い緑
        self.txt_file2.tag_config(
            "removed", background="#ffeef0", foreground="#cb2431"
        )  # 削除：薄い赤
        self.txt_file2.tag_config(
            "changed", background="#fff5b1", foreground="#735c0f"
        )  # 変更：薄い黄

        # ----------------------------------------------------
        # 3. 下部：アクションエリア
        # ----------------------------------------------------
        bottom_frame = tk.Frame(self.root, pady=15)
        bottom_frame.pack(fill=tk.X, side=tk.BOTTOM)

        self.btn_compare = tk.Button(
            bottom_frame,
            text="差分を比較する",
            command=self.compare_texts,
            font=("Arial", 11, "bold"),
            bg="#007BFF",
            fg="white",
            padx=30,
            pady=5,
        )
        self.btn_compare.pack()

    def load_file1(self):
        """ファイル1を読み込む"""
        path = filedialog.askopenfilename(
            filetypes=[("Text files", "*.txt"), ("All files", "*.*")]
        )
        if path:
            self.file1_path = path
            self.lbl_file1.config(text=os.path.basename(path), fg="black")
            try:
                with open(path, "r", encoding="utf-8") as f:
                    content = f.read()
                self.txt_file1.delete("1.0", tk.END)
                self.txt_file1.insert(tk.END, content)
            except Exception as e:
                messagebox.showerror("エラー", f"ファイル1の読み込みに失敗しました:\n{e}")

    def load_file2(self):
        """ファイル2を読み込む"""
        path = filedialog.askopenfilename(
            filetypes=[("Text files", "*.txt"), ("All files", "*.*")]
        )
        if path:
            self.file2_path = path
            self.lbl_file2.config(text=os.path.basename(path), fg="black")
            try:
                with open(path, "r", encoding="utf-8") as f:
                    content = f.read()
                self.txt_file2.delete("1.0", tk.END)
                self.txt_file2.insert(tk.END, content)
            except Exception as e:
                messagebox.showerror("エラー", f"ファイル2の読み込みに失敗しました:\n{e}")

    def compare_texts(self):
        """2つのテキストの差分を計算して右側の画面に色付きで表示する"""
        text1_lines = self.txt_file1.get("1.0", tk.END).splitlines()
        text2_lines = self.txt_file2.get("1.0", tk.END).splitlines()

        differ = difflib.Differ()
        diff_result = list(differ.compare(text1_lines, text2_lines))

        self.txt_file2.delete("1.0", tk.END)

        for line in diff_result:
            status = line[:2]
            content = line[2:]

            if status == "  ":
                self.txt_file2.insert(tk.END, content + "\n")
            elif status == "+ ":
                self.txt_file2.insert(tk.END, "[＋] " + content + "\n", "added")
            elif status == "- ":
                self.txt_file2.insert(tk.END, "[－] " + content + "\n", "removed")
            elif status == "? ":
                self.txt_file2.insert(
                    tk.END, "      " + content + " (変更箇所)\n", "changed"
                )


if __name__ == "__main__":
    root = tk.Tk()
    app = TextDiffApp(root)
    root.mainloop()
