import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox, filedialog
import json
import os
import random
from pathlib import Path


class TangPoetryApp:
    def __init__(self, root):
        self.root = root
        self.root.title("唐诗三百首")
        self.root.geometry("800x600")

        # 获取程序所在目录
        self.app_dir = Path(
            __file__).parent if "__file__" in locals() else Path.cwd()
        self.data_file = self.app_dir / "tang_poetry.json"

        # 加载数据
        self.poems = self.load_poems()

        # 创建界面
        self.create_widgets()

    def load_poems(self):
        """加载或创建示例唐诗数据"""
        try:
            if self.data_file.exists():
                with open(self.data_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
            else:
                return self.create_sample_data()
        except json.JSONDecodeError:
            messagebox.showwarning("数据错误", "数据文件格式错误，将使用示例数据")
            return self.create_sample_data()
        except Exception as e:
            messagebox.showwarning("加载失败", f"加载数据失败: {str(e)}\n将使用示例数据")
            return self.create_sample_data()

    def create_sample_data(self):
        """创建示例唐诗数据"""
        sample_poems = [
            {
                "id": 1,
                "title": "静夜思",
                "author": "李白",
                "dynasty": "唐",
                "content": "床前明月光，疑是地上霜。\n举头望明月，低头思故乡。",
                "tags": ["思乡", "月亮", "五言绝句"]
            },
            {
                "id": 2,
                "title": "春晓",
                "author": "孟浩然",
                "dynasty": "唐",
                "content": "春眠不觉晓，处处闻啼鸟。\n夜来风雨声，花落知多少。",
                "tags": ["春天", "自然", "五言绝句"]
            },
            {
                "id": 3,
                "title": "登鹳雀楼",
                "author": "王之涣",
                "dynasty": "唐",
                "content": "白日依山尽，黄河入海流。\n欲穷千里目，更上一层楼。",
                "tags": ["哲理", "景色", "五言绝句"]
            },
            {
                "id": 4,
                "title": "相思",
                "author": "王维",
                "dynasty": "唐",
                "content": "红豆生南国，春来发几枝。\n愿君多采撷，此物最相思。",
                "tags": ["爱情", "相思", "五言绝句"]
            },
            {
                "id": 5,
                "title": "将进酒",
                "author": "李白",
                "dynasty": "唐",
                "content": "君不见黄河之水天上来，奔流到海不复回。\n君不见高堂明镜悲白发，朝如青丝暮成雪。\n人生得意须尽欢，莫使金樽空对月。\n天生我材必有用，千金散尽还复来。",
                "tags": ["豪放", "饮酒", "乐府诗"]
            },
            {
                "id": 6,
                "title": "望庐山瀑布",
                "author": "李白",
                "dynasty": "唐",
                "content": "日照香炉生紫烟，遥看瀑布挂前川。\n飞流直下三千尺，疑是银河落九天。",
                "tags": ["山水", "瀑布", "七言绝句"]
            },
            {
                "id": 7,
                "title": "早发白帝城",
                "author": "李白",
                "dynasty": "唐",
                "content": "朝辞白帝彩云间，千里江陵一日还。\n两岸猿声啼不住，轻舟已过万重山。",
                "tags": ["行旅", "山水", "七言绝句"]
            }
        ]

        # 尝试保存示例数据
        try:
            with open(self.data_file, 'w', encoding='utf-8') as f:
                json.dump(sample_poems, f, ensure_ascii=False, indent=2)
        except Exception as e:
            messagebox.showwarning("保存失败", f"无法保存示例数据: {str(e)}")

        return sample_poems

    def save_poems(self):
        """保存诗歌数据"""
        try:
            # 确保目录存在
            self.data_file.parent.mkdir(parents=True, exist_ok=True)

            # 保存数据
            with open(self.data_file, 'w', encoding='utf-8') as f:
                json.dump(self.poems, f, ensure_ascii=False, indent=2)
            return True
        except PermissionError:
            messagebox.showerror("权限错误", f"没有权限写入文件: {self.data_file}")
            return False
        except Exception as e:
            messagebox.showerror("保存失败", f"保存数据失败: {str(e)}")
            return False

    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = tk.Frame(self.root)
        main_frame.pack(fill='both', expand=True, padx=10, pady=10)

        # 左侧：搜索和列表区域
        left_frame = tk.Frame(main_frame)
        left_frame.pack(side=tk.LEFT, fill='both', expand=True, padx=(0, 5))

        # 搜索区域
        search_frame = tk.LabelFrame(left_frame, text="搜索筛选", padx=10, pady=10)
        search_frame.pack(fill='x', pady=(0, 10))

        # 搜索关键词
        tk.Label(search_frame, text="关键词:").grid(
            row=0, column=0, sticky='w', pady=2)
        self.search_var = tk.StringVar()
        self.search_entry = tk.Entry(
            search_frame, textvariable=self.search_var, width=25)
        self.search_entry.grid(row=0, column=1, padx=5, pady=2)
        self.search_entry.bind('<KeyRelease>', self.search_poems)

        # 作者筛选
        tk.Label(search_frame, text="作者:").grid(
            row=0, column=2, sticky='w', pady=2, padx=(10, 0))
        self.author_var = tk.StringVar()
        self.author_combo = ttk.Combobox(
            search_frame, textvariable=self.author_var, width=12, state='readonly')
        self.author_combo.grid(row=0, column=3, padx=5, pady=2)
        self.author_combo['values'] = ['全部作者'] + \
            sorted(set(poem['author'] for poem in self.poems))
        self.author_combo.current(0)
        self.author_combo.bind('<<ComboboxSelected>>', self.search_poems)

        # 标签筛选
        tk.Label(search_frame, text="标签:").grid(
            row=1, column=0, sticky='w', pady=2)
        self.tag_var = tk.StringVar()
        tags = []
        for poem in self.poems:
            tags.extend(poem['tags'])
        unique_tags = sorted(set(tags))
        self.tag_combo = ttk.Combobox(
            search_frame, textvariable=self.tag_var, width=12, state='readonly')
        self.tag_combo.grid(row=1, column=1, padx=5, pady=2)
        self.tag_combo['values'] = ['全部标签'] + unique_tags
        self.tag_combo.current(0)
        self.tag_combo.bind('<<ComboboxSelected>>', self.search_poems)

        # 列表区域
        list_frame = tk.LabelFrame(left_frame, text="诗歌列表")
        list_frame.pack(fill='both', expand=True)

        # 创建列表
        columns = ('序号', '诗名', '作者', '朝代')
        self.tree = ttk.Treeview(
            list_frame, columns=columns, show='headings', height=15)

        # 设置列标题
        for col in columns:
            self.tree.heading(col, text=col)
            if col == '序号':
                self.tree.column(col, width=60, anchor='center')
            elif col == '诗名':
                self.tree.column(col, width=150)
            elif col == '作者':
                self.tree.column(col, width=100)
            else:
                self.tree.column(col, width=80)

        # 滚动条
        scrollbar = ttk.Scrollbar(
            list_frame, orient=tk.VERTICAL, command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)

        self.tree.pack(side=tk.LEFT, fill='both', expand=True)
        scrollbar.pack(side=tk.RIGHT, fill='y')

        # 绑定选择事件
        self.tree.bind('<<TreeviewSelect>>', self.show_poem_detail)

        # 右侧：详情区域
        right_frame = tk.Frame(main_frame)
        right_frame.pack(side=tk.RIGHT, fill='both', expand=True, padx=(5, 0))

        # 详情显示区域
        detail_frame = tk.LabelFrame(right_frame, text="诗歌详情")
        detail_frame.pack(fill='both', expand=True)

        self.detail_text = scrolledtext.ScrolledText(
            detail_frame, font=("楷体", 12), wrap=tk.WORD)
        self.detail_text.pack(fill='both', expand=True, padx=5, pady=5)

        # 标签显示区域
        tag_frame = tk.LabelFrame(right_frame, text="标签", height=80)
        tag_frame.pack(fill='x', pady=(10, 0))
        tag_frame.pack_propagate(False)  # 固定高度

        self.tag_canvas = tk.Canvas(tag_frame)
        scrollbar_tags = ttk.Scrollbar(
            tag_frame, orient='horizontal', command=self.tag_canvas.xview)
        tag_inner_frame = tk.Frame(self.tag_canvas)

        self.tag_canvas.configure(xscrollcommand=scrollbar_tags.set)

        scrollbar_tags.pack(side=tk.BOTTOM, fill='x')
        self.tag_canvas.pack(side=tk.TOP, fill='both', expand=True)
        self.tag_canvas.create_window(
            (0, 0), window=tag_inner_frame, anchor='nw')

        self.tag_inner_frame = tag_inner_frame

        # 按钮区域
        button_frame = tk.Frame(right_frame)
        button_frame.pack(fill='x', pady=(10, 0))

        buttons = [
            ("随机一首", self.random_poem),
            ("添加新诗", self.add_poem),
            ("修改", self.edit_poem),
            ("删除", self.delete_poem),
            ("导出", self.export_data),
            ("导入", self.import_data)
        ]

        for i, (text, command) in enumerate(buttons):
            btn = tk.Button(button_frame, text=text, command=command, width=10)
            btn.grid(row=0, column=i, padx=2)

        # 状态栏
        self.status_var = tk.StringVar(value=f"共 {len(self.poems)} 首诗歌")
        status_bar = tk.Label(
            self.root, textvariable=self.status_var, bd=1, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill='x')

        # 初始化列表
        self.refresh_list()

    def refresh_list(self, poems=None):
        """刷新诗歌列表"""
        # 清空当前列表
        for item in self.tree.get_children():
            self.tree.delete(item)

        # 显示诗歌列表
        display_list = poems if poems is not None else self.poems
        for poem in display_list:
            self.tree.insert('', tk.END, values=(
                poem['id'],
                poem['title'],
                poem['author'],
                poem['dynasty']
            ))

        # 更新状态栏
        self.status_var.set(f"共 {len(display_list)} 首诗歌")

        # 更新作者下拉框
        authors = ['全部作者'] + sorted(set(poem['author']
                                        for poem in display_list))
        self.author_combo['values'] = authors

    def search_poems(self, event=None):
        """搜索诗歌"""
        search_text = self.search_var.get().lower()
        author_filter = self.author_var.get()
        tag_filter = self.tag_var.get()

        filtered_poems = []
        for poem in self.poems:
            # 搜索文本匹配
            text_match = (not search_text or
                          search_text in poem['title'].lower() or
                          search_text in poem['content'].lower())

            # 作者筛选
            author_match = (author_filter in [
                            '全部作者', ''] or author_filter == poem['author'])

            # 标签筛选
            tag_match = (tag_filter in ['全部标签', '']
                         or tag_filter in poem['tags'])

            if text_match and author_match and tag_match:
                filtered_poems.append(poem)

        self.refresh_list(filtered_poems)

    def show_poem_detail(self, event=None):
        """显示选中的诗歌详情"""
        selection = self.tree.selection()
        if not selection:
            return

        item = self.tree.item(selection[0])
        poem_id = item['values'][0]

        poem = next((p for p in self.poems if p['id'] == poem_id), None)
        if poem:
            # 显示诗歌内容
            detail = f"《{poem['title']}》\n"
            detail += f"作者：{poem['author']}（{poem['dynasty']}）\n"
            detail += "=" * 30 + "\n\n"
            detail += poem['content'] + "\n\n"
            detail += "=" * 30 + "\n"

            self.detail_text.delete(1.0, tk.END)
            self.detail_text.insert(tk.END, detail)

            # 显示标签
            for widget in self.tag_inner_frame.winfo_children():
                widget.destroy()

            for tag in poem['tags']:
                tag_label = tk.Label(self.tag_inner_frame, text=tag, bg='lightblue',
                                     relief=tk.RAISED, padx=5, pady=2)
                tag_label.pack(side=tk.LEFT, padx=2, pady=5)

            self.tag_canvas.configure(scrollregion=self.tag_canvas.bbox("all"))

    def add_poem(self):
        """添加新诗"""
        self.create_edit_dialog("添加新诗", None)

    def edit_poem(self):
        """编辑选中的诗歌"""
        selection = self.tree.selection()
        if not selection:
            messagebox.showwarning("提示", "请先选择一首诗")
            return

        item = self.tree.item(selection[0])
        poem_id = item['values'][0]

        poem = next((p for p in self.poems if p['id'] == poem_id), None)
        if poem:
            self.create_edit_dialog("编辑诗歌", poem)

    def create_edit_dialog(self, title, poem):
        """创建编辑对话框"""
        dialog = tk.Toplevel(self.root)
        dialog.title(title)
        dialog.geometry("500x450")
        dialog.transient(self.root)
        dialog.grab_set()

        # 表单框架
        form_frame = tk.Frame(dialog, padx=20, pady=20)
        form_frame.pack(fill='both', expand=True)

        # 诗名
        tk.Label(form_frame, text="诗名：").grid(
            row=0, column=0, sticky='w', pady=8)
        title_var = tk.StringVar(value=poem['title'] if poem else "")
        tk.Entry(form_frame, textvariable=title_var,
                 width=40).grid(row=0, column=1, pady=8)

        # 作者
        tk.Label(form_frame, text="作者：").grid(
            row=1, column=0, sticky='w', pady=8)
        author_var = tk.StringVar(value=poem['author'] if poem else "")
        tk.Entry(form_frame, textvariable=author_var,
                 width=40).grid(row=1, column=1, pady=8)

        # 朝代
        tk.Label(form_frame, text="朝代：").grid(
            row=2, column=0, sticky='w', pady=8)
        dynasty_var = tk.StringVar(value=poem['dynasty'] if poem else "唐")
        tk.Entry(form_frame, textvariable=dynasty_var,
                 width=40).grid(row=2, column=1, pady=8)

        # 内容
        tk.Label(form_frame, text="内容：").grid(
            row=3, column=0, sticky='nw', pady=8)
        content_text = scrolledtext.ScrolledText(
            form_frame, height=10, width=30)
        content_text.grid(row=3, column=1, pady=8)
        if poem:
            content_text.insert(1.0, poem['content'])

        # 标签
        tk.Label(form_frame, text="标签（用逗号分隔）：").grid(
            row=4, column=0, sticky='w', pady=8)
        tags_var = tk.StringVar(value=', '.join(poem['tags']) if poem else "")
        tk.Entry(form_frame, textvariable=tags_var,
                 width=40).grid(row=4, column=1, pady=8)

        def save_poem():
            """保存诗歌"""
            title = title_var.get().strip()
            author = author_var.get().strip()
            dynasty = dynasty_var.get().strip()
            content = content_text.get(1.0, tk.END).strip()
            tags_str = tags_var.get().strip()

            if not title or not author or not content:
                messagebox.showwarning("输入错误", "请填写诗名、作者和内容")
                return

            new_poem = {
                'id': poem['id'] if poem else max([p['id'] for p in self.poems], default=0) + 1,
                'title': title,
                'author': author,
                'dynasty': dynasty or "唐",
                'content': content,
                'tags': [tag.strip() for tag in tags_str.split(',') if tag.strip()]
            }

            if poem:
                # 更新现有诗歌
                index = self.poems.index(poem)
                self.poems[index] = new_poem
            else:
                # 添加新诗
                self.poems.append(new_poem)

            # 保存到文件
            if self.save_poems():
                self.refresh_list()
                self.search_poems()  # 重新搜索以更新筛选
                dialog.destroy()

        # 按钮框架
        button_frame = tk.Frame(dialog)
        button_frame.pack(pady=(0, 20))

        tk.Button(button_frame, text="保存", command=save_poem,
                  width=15).pack(side=tk.LEFT, padx=5)
        tk.Button(button_frame, text="取消", command=dialog.destroy,
                  width=15).pack(side=tk.LEFT, padx=5)

    def delete_poem(self):
        """删除选中的诗歌"""
        selection = self.tree.selection()
        if not selection:
            messagebox.showwarning("提示", "请先选择一首诗")
            return

        item = self.tree.item(selection[0])
        poem_title = item['values'][1]

        if not messagebox.askyesno("确认删除", f"确定要删除《{poem_title}》吗？"):
            return

        poem_id = item['values'][0]

        # 从列表中删除
        self.poems = [p for p in self.poems if p['id'] != poem_id]

        # 保存到文件
        if self.save_poems():
            self.refresh_list()
            self.detail_text.delete(1.0, tk.END)
            for widget in self.tag_inner_frame.winfo_children():
                widget.destroy()
            messagebox.showinfo("成功", "删除成功！")

    def random_poem(self):
        """随机显示一首诗"""
        if not self.poems:
            messagebox.showinfo("提示", "诗歌列表为空")
            return

        random_poem = random.choice(self.poems)

        # 在列表中选中
        for item in self.tree.get_children():
            if self.tree.item(item)['values'][0] == random_poem['id']:
                self.tree.selection_set(item)
                self.tree.see(item)
                self.show_poem_detail()
                break

    def export_data(self):
        """导出数据"""
        filename = filedialog.asksaveasfilename(
            title="导出数据",
            defaultextension=".json",
            filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")]
        )

        if filename:
            try:
                with open(filename, 'w', encoding='utf-8') as f:
                    json.dump(self.poems, f, ensure_ascii=False, indent=2)
                messagebox.showinfo("成功", f"数据已导出到：\n{filename}")
            except Exception as e:
                messagebox.showerror("导出失败", f"导出失败：{str(e)}")

    def import_data(self):
        """导入数据"""
        filename = filedialog.askopenfilename(
            title="导入数据",
            filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")]
        )

        if filename:
            try:
                with open(filename, 'r', encoding='utf-8') as f:
                    imported_poems = json.load(f)

                if not isinstance(imported_poems, list):
                    messagebox.showerror("导入失败", "数据格式错误")
                    return

                # 合并数据
                existing_ids = {p['id'] for p in self.poems}
                max_id = max(existing_ids) if existing_ids else 0

                for poem in imported_poems:
                    if poem['id'] in existing_ids:
                        poem['id'] = max_id + 1
                        max_id += 1
                    self.poems.append(poem)

                if self.save_poems():
                    self.refresh_list()
                    self.search_poems()
                    messagebox.showinfo(
                        "成功", f"成功导入 {len(imported_poems)} 首诗歌")

            except json.JSONDecodeError:
                messagebox.showerror("导入失败", "JSON文件格式错误")
            except Exception as e:
                messagebox.showerror("导入失败", f"导入失败：{str(e)}")


def main():
    root = tk.Tk()
    app = TangPoetryApp(root)
    root.mainloop()


if __name__ == "__main__":
    main()
