import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import json
import os

# 示例诗集（把这里扩展为完整 300 首或从文件加载）
poems = [
    {
        "title": "静夜思",
        "author": "李白",
        "content": "床前明月光，疑是地上霜。举头望明月，低头思故乡。",
        "annotation": "思乡名篇，意境清朗。"
    },
    {
        "title": "春晓",
        "author": "孟浩然",
        "content": "春眠不觉晓，处处闻啼鸟。夜来风雨声，花落知多少。",
        "annotation": "描写春日晨起所见与感受。"
    },
    {
        "title": "静夜思（变体示例）",
        "author": "李白",
        "content": "床前明月光，疑似地上霜。举头望明月，低头思故乡。",
        "annotation": ""
    },
    {
        "title": "登鹳雀楼",
        "author": "王之涣",
        "content": "白日依山尽，黄河入海流。欲穷千里目，更上一层楼。",
        "annotation": ""
    },
    # ... 在此处继续添加，或从外部文件加载
]

FAVORITES_FILE = "favorites.json"

class TangViewer(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("唐诗三百首 阅读器")
        self.geometry("800x600")
        self.minsize(640, 480)

        self.poems = poems[:]  # 可替换为从文件加载的完整列表
        self.filtered = self.poems[:]  # 当前过滤结果
        self.favorites = self._load_favorites()

        self._create_widgets()
        self._populate_list()

    def _create_widgets(self):
        # 左侧搜索与列表
        left_frame = ttk.Frame(self)
        left_frame.pack(side='left', fill='y')

        search_frame = ttk.Frame(left_frame)
        search_frame.pack(fill='x', padx=6, pady=6)

        ttk.Label(search_frame, text="搜索 (标题/作者/内容)：").pack(side='left')
        self.search_var = tk.StringVar()
        search_entry = ttk.Entry(search_frame, textvariable=self.search_var)
        search_entry.pack(side='left', fill='x', expand=True, padx=4)
        search_entry.bind('<Return>', lambda e: self.on_search())
        ttk.Button(search_frame, text="搜索", command=self.on_search).pack(side='left', padx=4)
        ttk.Button(search_frame, text="重置", command=self.on_reset).pack(side='left')

        list_frame = ttk.Frame(left_frame)
        list_frame.pack(fill='both', expand=True, padx=6, pady=6)

        self.listbox = tk.Listbox(list_frame, width=30)
        self.listbox.pack(side='left', fill='both', expand=True)
        self.listbox.bind('<<ListboxSelect>>', lambda e: self.on_select())

        scrollbar = ttk.Scrollbar(list_frame, orient='vertical', command=self.listbox.yview)
        scrollbar.pack(side='right', fill='y')
        self.listbox.config(yscrollcommand=scrollbar.set)

        # 右侧显示区
        right_frame = ttk.Frame(self)
        right_frame.pack(side='right', fill='both', expand=True)

        # 标题和作者
        title_frame = ttk.Frame(right_frame)
        title_frame.pack(fill='x', padx=8, pady=8)
        self.title_var = tk.StringVar()
        self.author_var = tk.StringVar()
        ttk.Label(title_frame, textvariable=self.title_var, font=('Helvetica', 16, 'bold')).pack(anchor='w')
        ttk.Label(title_frame, textvariable=self.author_var, font=('Helvetica', 12, 'italic')).pack(anchor='w')

        # 内容显示（只读 Text）
        content_frame = ttk.Frame(right_frame)
        content_frame.pack(fill='both', expand=True, padx=8, pady=8)
        self.text = tk.Text(content_frame, wrap='word', font=('SimSun', 14))
        self.text.pack(fill='both', expand=True, side='left')
        self.text.configure(state='disabled')

        text_scroll = ttk.Scrollbar(content_frame, orient='vertical', command=self.text.yview)
        text_scroll.pack(side='right', fill='y')
        self.text.config(yscrollcommand=text_scroll.set)

        # 底部按钮
        btn_frame = ttk.Frame(right_frame)
        btn_frame.pack(fill='x', padx=8, pady=6)
        ttk.Button(btn_frame, text="收藏/取消收藏", command=self.toggle_favorite).pack(side='left')
        ttk.Button(btn_frame, text="导出为文本", command=self.export_current).pack(side='left', padx=6)
        ttk.Button(btn_frame, text="导出全部（txt）", command=self.export_all).pack(side='left')
        ttk.Button(btn_frame, text="显示收藏", command=self.show_favorites).pack(side='left', padx=6)

    def _populate_list(self):
        self.listbox.delete(0, tk.END)
        for idx, p in enumerate(self.filtered):
            mark = "★ " if self._is_favorite(p) else ""
            self.listbox.insert(tk.END, f"{mark}{p['title']} — {p['author']}")

    def on_search(self):
        kw = self.search_var.get().strip().lower()
        if not kw:
            self.filtered = self.poems[:]
        else:
            res = []
            for p in self.poems:
                if kw in p['title'].lower() or kw in p['author'].lower() or kw in p['content'].lower():
                    res.append(p)
            self.filtered = res
        self._populate_list()

    def on_reset(self):
        self.search_var.set("")
        self.filtered = self.poems[:]
        self._populate_list()

    def on_select(self):
        sel = self.listbox.curselection()
        if not sel:
            return
        idx = sel[0]
        poem = self.filtered[idx]
        self._show_poem(poem)

    def _show_poem(self, poem):
        self.current_poem = poem
        self.title_var.set(poem['title'])
        self.author_var.set(f"作者：{poem.get('author','')}")
        self.text.configure(state='normal')
        self.text.delete('1.0', tk.END)
        self.text.insert(tk.END, poem['content'] + "\n\n")
        if poem.get('annotation'):
            self.text.insert(tk.END, "注释：\n" + poem['annotation'])
        self.text.configure(state='disabled')

    def toggle_favorite(self):
        if not hasattr(self, 'current_poem') or not self.current_poem:
            messagebox.showinfo("提示", "请先选择一首诗。")
            return
        key = self._poem_key(self.current_poem)
        if key in self.favorites:
            del self.favorites[key]
            messagebox.showinfo("提示", "已取消收藏。")
        else:
            self.favorites[key] = self.current_poem
            messagebox.showinfo("提示", "已加入收藏。")
        self._save_favorites()
        self._populate_list()

    def _poem_key(self, poem):
        return f"{poem.get('title','')}@@{poem.get('author','')}"

    def _is_favorite(self, poem):
        return self._poem_key(poem) in self.favorites

    def _load_favorites(self):
        if os.path.exists(FAVORITES_FILE):
            try:
                with open(FAVORITES_FILE, 'r', encoding='utf-8') as f:
                    return json.load(f)
            except Exception:
                return {}
        return {}

    def _save_favorites(self):
        try:
            with open(FAVORITES_FILE, 'w', encoding='utf-8') as f:
                json.dump(self.favorites, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print("保存收藏失败：", e)

    def export_current(self):
        if not hasattr(self, 'current_poem') or not self.current_poem:
            messagebox.showinfo("提示", "请先选择一首诗。")
            return
        p = self.current_poem
        default = f"{p['title']}-{p.get('author','')}.txt"
        path = filedialog.asksaveasfilename(defaultextension=".txt", initialfile=default,
                                            filetypes=[("Text files", "*.txt"), ("All files", "*.*")])
        if not path:
            return
        try:
            with open(path, 'w', encoding='utf-8') as f:
                f.write(f"{p['title']}\n{p.get('author','')}\n\n{p['content']}\n")
                if p.get('annotation'):
                    f.write("\n注释：\n" + p['annotation'])
            messagebox.showinfo("导出成功", f"已导出到 {path}")
        except Exception as e:
            messagebox.showerror("错误", f"导出失败：{e}")

    def export_all(self):
        path = filedialog.asksaveasfilename(defaultextension=".txt", initialfile="tang_poems.txt",
                                            filetypes=[("Text files", "*.txt"), ("All files", "*.*")])
        if not path:
            return
        try:
            with open(path, 'w', encoding='utf-8') as f:
                for p in self.poems:
                    f.write(f"{p['title']} — {p.get('author','')}\n{p['content']}\n\n")
            messagebox.showinfo("导出成功", f"已导出到 {path}")
        except Exception as e:
            messagebox.showerror("错误", f"导出失败：{e}")

    def show_favorites(self):
        favs = list(self.favorites.values())
        if not favs:
            messagebox.showinfo("收藏", "当前没有收藏。")
            return
        # 弹出对话框显示收藏列表，允许选择
        top = tk.Toplevel(self)
        top.title("收藏")
        top.geometry("400x400")
        lb = tk.Listbox(top)
        lb.pack(fill='both', expand=True)
        for p in favs:
            lb.insert(tk.END, f"{p['title']} — {p.get('author','')}")
        def on_pick(evt):
            sel = lb.curselection()
            if not sel:
                return
            poem = favs[sel[0]]
            self._show_poem(poem)
            top.destroy()
        lb.bind('<<ListboxSelect>>', on_pick)

if __name__ == "__main__":
    app = TangViewer()
    app.mainloop()