import tkinter as tk
from tkinter import messagebox
import json
import os

# データの保存先ファイル名（プログラムと同じフォルダに作られます）
DATA_FILE = "cards_data.json"

class KyodaiCardApp:
    def __init__(self, root):
        self.root = root
        self.root.title("京大カード風 暗記カード")
        self.root.geometry("750x480") # 左右の一覧が見やすくなるようサイズを調整

        # データの読み込み
        self.cards = self.load_data()
        self.current_index = 0
        self.editing_idx = None # 現在修正中のカードの番号（Noneなら新規登録）

        # メインフレーム
        self.main_frame = tk.Frame(root, bg="#FFFDF0")
        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=15, pady=15)

        self.create_mode_selection()

    # ------------------ データの保存・読み込み ------------------
    def load_data(self):
        """ファイルを読み込む。なければ初期データを返す"""
        if os.path.exists(DATA_FILE):
            try:
                with open(DATA_FILE, "r", encoding="utf-8") as f:
                    return json.load(f)
            except Exception:
                pass
        # 初期データ
        return [{"title": "サンプル語句", "body": "ここに詳しい説明が表示されます。\n作成モードで自由に追加・修正・削除ができます。"}]

    def save_data_to_file(self):
        """現在のカードデータをファイルに保存する"""
        try:
            with open(DATA_FILE, "w", encoding="utf-8") as f:
                json.dump(self.cards, f, ensure_ascii=False, indent=4)
        except Exception as e:
            messagebox.showerror("エラー", f"データの保存に失敗しました:\n{e}")

    # ------------------ 画面切り替え ------------------
    def create_mode_selection(self):
        """最初のモード選択画面"""
        self.clear_frame()
        self.editing_idx = None

        lbl = tk.Label(self.main_frame, text="モードを選んでください", font=("MS Gothic", 16), bg="#FFFDF0")
        lbl.pack(pady=60)

        btn_create = tk.Button(self.main_frame, text="作成・修正モード", font=("MS Gothic", 14), command=self.init_create_mode, width=18, height=2)
        btn_create.pack(pady=10)

        btn_study = tk.Button(self.main_frame, text="確認モード", font=("MS Gothic", 14), command=self.init_study_mode, width=18, height=2)
        btn_study.pack(pady=10)

    def clear_frame(self):
        # メインフレームの中にある子ウィジェットを強制的にすべて削除する
        for widget in self.main_frame.pack_slaves() + self.main_frame.grid_slaves() + self.main_frame.winfo_children():
            try:
                widget.destroy()
            except:
                pass

    # ------------------ 作成・修正モード ------------------
    def init_create_mode(self):
        self.clear_frame()

        # 戻るボタン
        tk.Button(self.main_frame, text="◀ モード選択へ", command=self.create_mode_selection).pack(anchor="w")

        # 左右に並べるベースの上下余白（pady）を 10 から 20 へ
        content_box = tk.Frame(self.main_frame, bg="#FFFDF0")
        content_box.pack(fill=tk.BOTH, expand=True, pady=20)

        # 【修正】右側フレームを「最初」に作成・配置（幅250px固定）
        right_frame = tk.Frame(content_box, bg="#FFFDF0", width=250)
        right_frame.pack(side=tk.RIGHT, fill=tk.Y, padx=(15, 0))
        right_frame.pack_propagate(False)

        # 【修正】左側フレームを「次」に配置（残りスペース全体に広がる）
        left_frame = tk.Frame(content_box, bg="#FFFDF0")
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 30))

        # --- 左側：入力フォームの配置 ---
        tk.Label(left_frame, text="語句（見出し）:", font=("MS Gothic", 11), bg="#FFFDF0").pack(anchor="w", pady=(5, 0))
        self.entry_title = tk.Entry(left_frame, font=("MS Gothic", 16, "bold"))
        self.entry_title.pack(fill=tk.X, pady=5, ipady=8)

        # 京大カード風の青い太仕切線
        separator = tk.Frame(left_frame, height=4, bg="#005CAF")
        separator.pack(fill=tk.X, pady=15)

        tk.Label(left_frame, text="説明（本文）:", font=("MS Gothic", 11), bg="#FFFDF0").pack(anchor="w")
        self.text_body = tk.Text(left_frame, font=("MS Gothic", 14), height=6)
        self.text_body.pack(fill=tk.BOTH, expand=True, pady=5)

        # ボタン関係
        self.btn_save_text = tk.StringVar(value="新規カードを登録")
        self.btn_save = tk.Button(left_frame, textvariable=self.btn_save_text, font=("MS Gothic", 11, "bold"), command=self.save_card, bg="#D4EFDF")
        self.btn_save.pack(fill=tk.X, pady=5)

        self.btn_cancel_edit = tk.Button(left_frame, text="修正をキャンセル", font=("MS Gothic", 10), command=self.cancel_edit, bg="#E6B0AA")

        # --- 右側：一覧リストの配置（重複をなくし、ここにカウンターを合流） ---
        # 1. カウンター（青い文字）を最上部に配置
        self.lbl_counter = tk.Label(right_frame, text="現在の登録数: 0枚", font=("MS Gothic", 11, "bold"), fg="#005CAF", bg="#FFFDF0")
        self.lbl_counter.pack(anchor="w", pady=(0, 10))

        # 2. リストの見出し
        tk.Label(right_frame, text="登録済み一覧 (クリックで修正)", font=("MS Gothic", 10), bg="#FFFDF0").pack(anchor="w")

        # 3. リストコンテナと中身
        list_container = tk.Frame(right_frame)
        list_container.pack(fill=tk.BOTH, expand=True, pady=5)

        self.card_listbox = tk.Listbox(list_container, font=("MS Gothic", 11), selectmode=tk.SINGLE)
        self.card_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        scrollbar = tk.Scrollbar(list_container, orient=tk.VERTICAL, command=self.card_listbox.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.card_listbox.config(yscrollcommand=scrollbar.set)

        # クリックイベント
        self.card_listbox.bind('<<ListboxSelect>>', self.on_list_select)

        # 削除ボタン
        btn_delete = tk.Button(right_frame, text="選択したカードを削除", font=("MS Gothic", 10), command=self.delete_card, bg="#FADBD8")
        btn_delete.pack(fill=tk.X, pady=5)

        # 画面を開いた時にリストを最新にする
        self.update_listbox()

    def update_listbox(self):
        """一覧リストを表示・更新する"""
        self.card_listbox.delete(0, tk.END)
        for card in self.cards:
            self.card_listbox.insert(tk.END, f" {card['title']}")

        # 【追加】現在の配列（self.cards）の要素数をカウントしてラベルを書き換える
        self.lbl_counter.config(text=f"現在の登録数: {len(self.cards)}枚")

    def on_list_select(self, event):
        """右側の一覧がクリックされたら修正モードに切り替える"""
        selection = self.card_listbox.curselection()
        if not selection:
            return

        # 安全にインデックス番号を取得
        idx = selection[0]
        self.editing_idx = idx
        card = self.cards[idx]

        # 左側の入力欄に表示を復元
        self.entry_title.delete(0, tk.END)
        self.entry_title.insert(0, card["title"])
        self.text_body.delete("1.0", tk.END)
        self.text_body.insert("1.0", card["body"])

        # ボタンを修正用に変更
        self.btn_save_text.set("カードの内容を修正（更新）")
        self.btn_save.config(bg="#AED6F1")
        self.btn_cancel_edit.pack(fill=tk.X, pady=2)

    def cancel_edit(self):
        """修正をキャンセルして新規作成状態に戻す"""
        self.editing_idx = None
        self.entry_title.delete(0, tk.END)
        self.text_body.delete("1.0", tk.END)
        self.btn_save_text.set("新規カードを登録")
        self.btn_save.config(bg="#D4EFDF")
        self.btn_cancel_edit.pack_forget()
        self.card_listbox.selection_clear(0, tk.END)

    def save_card(self):
        """登録、または修正の実行"""
        title = self.entry_title.get().strip()
        body = self.text_body.get("1.0", tk.END).strip()

        if not title or not body:
            messagebox.showwarning("警告", "語句と説明の両方を入力してください。")
            return

        if self.editing_idx is not None:
            # 修正保存
            self.cards[self.editing_idx] = {"title": title, "body": body}
            messagebox.showinfo("完了", f"「{title}」の修正を保存しました。")
        else:
            # 新規登録
            self.cards.append({"title": title, "body": body})
            messagebox.showinfo("完了", f"「{title}」を新しく登録しました。")

        self.save_data_to_file() # ファイルに自動保存

        # 画面の表示を最新にする（既存の処理）
        self.update_listbox()

        # 【ここに追加！】新規登録して、キリのいい枚数になったらお祝いを出す
        current_count = len(self.cards)
        milestones = [10, 30, 50, 100, 200, 300, 500]  # お祝いする枚数の節目

        if current_count in milestones:
            messagebox.showinfo(
                "おめでとうございます！🎉",
                f"素晴らしいです！現在の登録数が【 {current_count} 枚 】に達しました！\n"
                "着実に自分だけのデータベースが育っていますね。この調子で応援しています！"
            )

        self.cancel_edit()

    def delete_card(self):
        """カードの削除"""
        selection = self.card_listbox.curselection()
        if not selection:
            messagebox.showwarning("警告", "削除するカードを一覧から選択してください。")
            return

        idx = selection[0]
        title = self.cards[idx]["title"]

        if messagebox.askyesno("確認", f"「{title}」を削除してもよろしいですか？"):
            del self.cards[idx]
            self.save_data_to_file() # 削除後の状態をファイルに保存
            self.update_listbox()
            self.cancel_edit()

    # ------------------ 確認モード ------------------
    def init_study_mode(self):
        if not self.cards:
            messagebox.showinfo("情報", "カードがありません。作成モードで追加してください。")
            return

        self.clear_frame()
        self.current_index = 0

        tk.Button(self.main_frame, text="◀ モード選択へ", command=self.create_mode_selection).pack(anchor="w")

        # カード外枠
        card_canvas = tk.Frame(self.main_frame, bg="#FFFFFF", highlightbackground="#BDC3C7", highlightthickness=2)
        card_canvas.pack(fill=tk.BOTH, expand=True, pady=10)

        self.lbl_study_title = tk.Label(card_canvas, text="", font=("MS Gothic", 18, "bold"), bg="#FFFFFF", anchor="w", justify=tk.LEFT)
        self.lbl_study_title.pack(fill=tk.X, padx=15, pady=15)

        self.line = tk.Frame(card_canvas, height=3, bg="#005CAF")
        self.line.pack(fill=tk.X, padx=10)

        self.lbl_study_body = tk.Label(card_canvas, text="", font=("MS Gothic", 14), bg="#FFFFFF", anchor="nw", justify=tk.LEFT)
        self.lbl_study_body.pack(fill=tk.BOTH, expand=True, padx=15, pady=15)

        btn_frame = tk.Frame(self.main_frame, bg="#FFFDF0")
        btn_frame.pack(fill=tk.X)

        self.btn_show = tk.Button(btn_frame, text="答えを表示", font=("MS Gothic", 12), command=self.show_body, width=12)
        self.btn_show.pack(side=tk.LEFT, padx=5)

        self.btn_next = tk.Button(btn_frame, text="次のカード ➔", font=("MS Gothic", 12), command=self.next_card, width=12)
        self.btn_next.pack(side=tk.RIGHT, padx=5)

        self.show_card_data()

    def show_card_data(self):
        card = self.cards[self.current_index]
        self.lbl_study_title.config(text=card["title"])
        self.lbl_study_body.config(text="（ボタンを押すと説明が表示されます）", fg="#95A5A6")
        self.btn_show.config(state=tk.NORMAL)

    def show_body(self):
        card = self.cards[self.current_index]
        self.lbl_study_body.config(text=card["body"], fg="#000000")
        self.btn_show.config(state=tk.DISABLED)

    def next_card(self):
        """次のカードへ進む（最後まで行ったら最初に戻る）"""
        if self.current_index < len(self.cards) - 1:
            self.current_index += 1
        else:
            self.current_index = 0
            messagebox.showinfo("一周しました", "最初のカードに戻ります。")
        self.show_card_data()

if __name__ == "__main__":
    # アプリケーションの起動処理
    root = tk.Tk()
    app = KyodaiCardApp(root)
    root.mainloop()
