import datetime
import json
import os
import tkinter as tk
from tkinter import messagebox, ttk

# 設定
WINDOW_SIZE = "360x450"
DB_FILE = os.path.join(os.path.dirname(__file__), "anybox_data.json")


# 【追加】必要なときだけ表示される自動スクロールバークラス
class AutoScrollbar(ttk.Scrollbar):
    def set(self, low, high):
        if float(low) <= 0.0 and float(high) >= 1.0:
            self.grid_remove()  # スクロール不要なら非表示
        else:
            self.grid()         # 必要なら表示
        super().set(low, high)


class AnyBoxApp:

    def __init__(self, root):
        self.root = root
        self.root.title("何でもボックス")
        self.root.geometry(WINDOW_SIZE)

        # データの読み込み
        self.data_store = self.load_data()

        self.create_widgets()

    def create_widgets(self):
        """UIコンポーネントの配置"""
        # --- スタイルの設定（Treeviewの色変更用） ---
        style = ttk.Style()
        style.theme_use("default")

        # リスト（Treeview）の背景色と文字色、選択時の色を設定
        style.configure(
            "Treeview",
            background="#cdfaeb",
            foreground="#035449",
            rowheight=22,
            fieldbackground="#ebfaf8"
        )
        style.map(
            "Treeview",
            background=[("selected", "#4682b4")],  # 選択時はスチールブルー
            foreground=[("selected", "white")]
        )

        # リストのヘッダー（見出し）の色を設定
        style.configure(
            "Treeview.Heading",
            background="#dcfcfc",      # ライトグレー
            foreground="#1c228c",
            font=("Noto Serif JP", 9, "bold")
        )

        # 上部：検索・保存エリア
        top_frame = ttk.Frame(self.root, padding=5)
        top_frame.pack(fill=tk.X)

        self.search_entry = ttk.Entry(top_frame)
        self.search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=2)
        self.search_entry.bind("<KeyRelease>", self.search_data)

        # 「検索」ボタンを着色（薄い緑）
        search_btn = tk.Button(
            top_frame, text="検索", command=self.search_data,
            bg="#fcc2ea", fg="#bd045a", relief=tk.GROOVE, bd=1, padx=8
        )
        search_btn.pack(side=tk.LEFT, padx=2)

        # 「保存」ボタンを着色（薄い青）
        save_btn = tk.Button(
            top_frame, text="保存", command=self.save_data,
            bg="#e3f2fd", fg="#0d47a1", relief=tk.GROOVE, bd=1, padx=8
        )
        save_btn.pack(side=tk.RIGHT, padx=2)

        # 中央：スクロールバー付きテキストボックス
        text_frame = ttk.Frame(self.root, padding=5)
        text_frame.pack(fill=tk.BOTH)

        self.text_box = tk.Text(text_frame, width=45, height=13, wrap=tk.WORD)
        scrollbar = ttk.Scrollbar(
            text_frame, orient=tk.VERTICAL, command=self.text_box.yview
        )
        self.text_box.configure(yscrollcommand=scrollbar.set)

        self.text_box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 下部：検索結果リスト
        list_frame = ttk.Frame(self.root, padding=5)
        list_frame.pack(fill=tk.BOTH, expand=True)

        ttk.Label(list_frame, text="検索結果 (クリックでコピー):").grid(
            row=0, column=0, columnspan=2, sticky=tk.W, pady=(0, 2)
        )

        # 【変更】Treeviewとスクロールバーをgridで配置
        # columnsに非表示用の"full_content"を追加
        self.result_list = ttk.Treeview(
            list_frame, columns=("date", "snippet", "full_content"), show="headings", height=5, style="Treeview"
        )
        self.result_list.heading("date", text="日付")
        self.result_list.heading("snippet", text="内容（前後10文字）")

        # 3列目はユーザーに見せないよう幅0かつ非表示設定にする
        self.result_list.column("date", width=90, stretch=False)
        self.result_list.column("snippet", width=230)
        self.result_list.column("full_content", width=0, minwidth=0, stretch=False)

        # 【追加】自動スクロールバーの作成と紐付け
        list_scrollbar = AutoScrollbar(
            list_frame, orient=tk.VERTICAL, command=self.result_list.yview
        )
        self.result_list.configure(yscrollcommand=list_scrollbar.set)

        # grid配置とリサイズ設定
        self.result_list.grid(row=1, column=0, sticky=tk.NSEW)
        list_scrollbar.grid(row=1, column=1, sticky=tk.NS)

        list_frame.grid_rowconfigure(1, weight=1)
        list_frame.grid_columnconfigure(0, weight=1)

        self.result_list.bind("<<TreeviewSelect>>", self.on_list_click)

    # --- データ管理機能 ---

    def load_data(self):
        """JSONファイルからデータを読み込む"""
        if os.path.exists(DB_FILE):
            try:
                with open(DB_FILE, "r", encoding="utf-8") as f:
                    return json.load(f)
            except Exception:
                messagebox.showerror(
                    "エラー", "JSONファイルの読み込みに失敗しました。"
                )
        return {}

    def get_today(self):
        """今日の日付を YYYY-MM-DD 形式で取得"""
        return datetime.date.today().isoformat()

    def save_data(self):
        """現在の日付キーでJSONファイルに『追記』して保存"""
        today = self.get_today()
        new_content = self.text_box.get("1.0", tk.END).strip()

        if not new_content:
            messagebox.showwarning("警告", "保存するデータが空です。")
            return

        if today in self.data_store and self.data_store[today]:
            self.data_store[today] = self.data_store[today] + "\n" + new_content
        else:
            self.data_store[today] = new_content

        try:
            with open(DB_FILE, "w", encoding="utf-8") as f:
                json.dump(self.data_store, f, ensure_ascii=False, indent=4)

            self.text_box.delete("1.0", tk.END)
            messagebox.showinfo("成功", f"データを追記保存しました。\n({today})")

            # 保存成功後にリストボックスを更新するため検索を再実行
            self.search_data()
        except Exception as e:
            messagebox.showerror(
                "エラー", f"保存に失敗しました:\n{e}"
            )

    # --- 検索・連携機能 ---

    def search_data(self, event=None):
        """全日付のデータから文字を検索し、前後10文字をリストアップ"""
        keyword = self.search_entry.get().strip()

        for item in self.result_list.get_children():
            self.result_list.delete(item)

        if not keyword:
            return

        for date, content in self.data_store.items():
            idx = content.find(keyword)
            while idx != -1:
                start = max(0, idx - 10)
                end = min(len(content), idx + len(keyword) + 10)
                snippet = content[start:end].replace("\n", " ")

                self.result_list.insert(
                    "", tk.END, values=(date, snippet, content)
                )
                idx = content.find(keyword, idx + 1)

    def on_list_click(self, event):
        """リストクリック時にテキスト表示＆クリップボードコピー"""
        selected = self.result_list.selection()
        if not selected:
            return

        item_values = self.result_list.item(selected, "values")
        if len(item_values) < 3:
            return

        full_content = item_values[2]

        self.text_box.delete("1.0", tk.END)
        self.text_box.insert(tk.END, full_content)

        self.root.clipboard_clear()
        self.root.clipboard_append(full_content)


if __name__ == "__main__":
    root = tk.Tk()
    app = AnyBoxApp(root)
    root.mainloop()
