import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
import datetime
import json
import os
from PIL import Image, ImageTk  # 可选，用于图片展示

# ========== 英雄数据管理 ==========
class HeroDatabase:
    def __init__(self, db_file="heroes_db.json"):
        self.db_file = db_file
        self.heroes = []  # 每个英雄：{id, name, category, era, deeds, quote, image_path, added_date}
        self.categories = ["历史英雄", "革命先烈", "平凡英雄", "科学巨匠", "文化名人", "当代楷模", "其他"]
        self.load_data()
        self.next_id = max([h["id"] for h in self.heroes], default=0) + 1
    
    def add_hero(self, name, category, era, deeds, quote="", image_path=""):
        """添加英雄"""
        hero = {
            "id": self.next_id,
            "name": name.strip(),
            "category": category,
            "era": era.strip(),
            "deeds": deeds.strip(),
            "quote": quote.strip(),
            "image_path": image_path,
            "added_date": datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
        }
        self.heroes.append(hero)
        self.next_id += 1
        self.save_data()
        return hero
    
    def delete_hero(self, hero_id):
        """删除英雄"""
        for i, h in enumerate(self.heroes):
            if h["id"] == hero_id:
                deleted = self.heroes.pop(i)
                self.save_data()
                return deleted
        return None
    
    def update_hero(self, hero_id, **kwargs):
        """更新英雄信息"""
        for h in self.heroes:
            if h["id"] == hero_id:
                for key, value in kwargs.items():
                    if key in h and value:
                        h[key] = value
                self.save_data()
                return h
        return None
    
    def search_heroes(self, keyword="", category=""):
        """搜索英雄"""
        results = self.heroes
        if keyword:
            keyword = keyword.lower()
            results = [h for h in results if 
                      keyword in h["name"].lower() or 
                      keyword in h["deeds"].lower() or
                      keyword in h["era"].lower()]
        if category and category != "全部":
            results = [h for h in results if h["category"] == category]
        return results
    
    def get_categories(self):
        return self.categories
    
    def save_data(self):
        with open(self.db_file, "w", encoding="utf-8") as f:
            json.dump(self.heroes, f, ensure_ascii=False, indent=2)
    
    def load_data(self):
        if os.path.exists(self.db_file):
            try:
                with open(self.db_file, "r", encoding="utf-8") as f:
                    self.heroes = json.load(f)
            except:
                self.heroes = []

# ========== 图形界面 ==========
class HeroApp:
    def __init__(self, root):
        self.root = root
        self.root.title("🦸 英雄事迹记录器")
        self.root.geometry("1000x750")
        self.root.resizable(True, True)
        
        # 初始化数据库
        self.db = HeroDatabase()
        
        # 设置样式
        style = ttk.Style()
        style.theme_use('clam')
        
        # ---------- 主框架 ----------
        main_frame = ttk.Frame(root, padding="15")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 标题
        title_frame = ttk.Frame(main_frame)
        title_frame.pack(fill=tk.X, pady=(0, 10))
        
        title = ttk.Label(title_frame, text="🦸 英雄事迹记录器", font=('Arial', 20, 'bold'))
        title.pack(side=tk.LEFT)
        
        stats_label = ttk.Label(title_frame, text=f"📊 共 {len(self.db.heroes)} 位英雄")
        stats_label.pack(side=tk.RIGHT)
        
        # ---------- 搜索和筛选 ----------
        search_frame = ttk.LabelFrame(main_frame, text="🔍 搜索与筛选", padding="10")
        search_frame.pack(fill=tk.X, pady=(0, 10))
        
        ttk.Label(search_frame, text="关键词:").grid(row=0, column=0, padx=5)
        self.search_var = tk.StringVar()
        self.search_entry = ttk.Entry(search_frame, textvariable=self.search_var, width=25)
        self.search_entry.grid(row=0, column=1, padx=5)
        self.search_entry.bind("<KeyRelease>", lambda e: self.refresh_list())
        
        ttk.Label(search_frame, text="分类:").grid(row=0, column=2, padx=(20, 5))
        self.category_filter_var = tk.StringVar(value="全部")
        self.category_filter = ttk.Combobox(search_frame, textvariable=self.category_filter_var,
                                            values=["全部"] + self.db.get_categories(), width=15)
        self.category_filter.grid(row=0, column=3, padx=5)
        self.category_filter.bind("<<ComboboxSelected>>", lambda e: self.refresh_list())
        
        ttk.Button(search_frame, text="🔍 搜索", command=self.refresh_list).grid(row=0, column=4, padx=10)
        ttk.Button(search_frame, text="🔄 重置", command=self.reset_search).grid(row=0, column=5)
        
        # ---------- 左右两栏 ----------
        paned = ttk.PanedWindow(main_frame, orient=tk.HORIZONTAL)
        paned.pack(fill=tk.BOTH, expand=True)
        
        # ---- 左栏：英雄列表 ----
        left_frame = ttk.LabelFrame(paned, text="📋 英雄列表", padding="5")
        paned.add(left_frame, weight=2)
        
        # 列表树
        columns = ("ID", "姓名", "分类", "时代", "添加日期")
        self.tree = ttk.Treeview(left_frame, columns=columns, show="headings", height=12)
        
        for col in columns:
            self.tree.heading(col, text=col)
            self.tree.column(col, width=80 if col == "ID" else 120, anchor=tk.CENTER if col != "姓名" else tk.W)
        self.tree.column("姓名", width=150)
        
        scrollbar = ttk.Scrollbar(left_frame, orient=tk.VERTICAL, command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        
        self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        self.tree.bind("<<TreeviewSelect>>", self.on_select_hero)
        
        # 列表底部按钮
        list_btn_frame = ttk.Frame(left_frame)
        list_btn_frame.pack(fill=tk.X, pady=(5, 0))
        
        ttk.Button(list_btn_frame, text="🗑️ 删除选中", command=self.delete_hero).pack(side=tk.LEFT, padx=2)
        ttk.Button(list_btn_frame, text="📤 导出全部", command=self.export_all).pack(side=tk.LEFT, padx=2)
        
        # ---- 右栏：英雄详情与编辑 ----
        right_frame = ttk.LabelFrame(paned, text="📝 英雄档案", padding="10")
        paned.add(right_frame, weight=3)
        
        # 详情显示区域（不可编辑）
        self.detail_text = scrolledtext.ScrolledText(right_frame, wrap=tk.WORD, height=12, font=('微软雅黑', 11))
        self.detail_text.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
        self.detail_text.config(state=tk.DISABLED)
        
        # 添加/编辑表单
        edit_frame = ttk.LabelFrame(right_frame, text="✏️ 添加新英雄", padding="10")
        edit_frame.pack(fill=tk.X)
        
        # 姓名
        ttk.Label(edit_frame, text="姓名 *:").grid(row=0, column=0, sticky=tk.W, pady=3)
        self.name_entry = ttk.Entry(edit_frame, width=20)
        self.name_entry.grid(row=0, column=1, pady=3, padx=5, sticky=tk.W)
        
        # 分类
        ttk.Label(edit_frame, text="分类 *:").grid(row=0, column=2, sticky=tk.W, pady=3, padx=(15,0))
        self.category_var = tk.StringVar()
        self.category_combo = ttk.Combobox(edit_frame, textvariable=self.category_var,
                                           values=self.db.get_categories(), width=12)
        self.category_combo.grid(row=0, column=3, pady=3, padx=5, sticky=tk.W)
        self.category_combo.current(0)
        
        # 时代
        ttk.Label(edit_frame, text="时代 *:").grid(row=0, column=4, sticky=tk.W, pady=3, padx=(15,0))
        self.era_entry = ttk.Entry(edit_frame, width=15)
        self.era_entry.grid(row=0, column=5, pady=3, padx=5, sticky=tk.W)
        
        # 事迹
        ttk.Label(edit_frame, text="主要事迹 *:").grid(row=1, column=0, sticky=tk.W, pady=3)
        self.deeds_entry = tk.Text(edit_frame, height=3, width=40)
        self.deeds_entry.grid(row=1, column=1, columnspan=5, pady=3, padx=5, sticky=tk.W+tk.E)
        
        # 名言
        ttk.Label(edit_frame, text="名言:").grid(row=2, column=0, sticky=tk.W, pady=3)
        self.quote_entry = ttk.Entry(edit_frame, width=50)
        self.quote_entry.grid(row=2, column=1, columnspan=5, pady=3, padx=5, sticky=tk.W)
        
        # 按钮
        btn_frame = ttk.Frame(edit_frame)
        btn_frame.grid(row=3, column=0, columnspan=6, pady=10)
        
        self.add_btn = ttk.Button(btn_frame, text="➕ 添加英雄", command=self.add_hero)
        self.add_btn.pack(side=tk.LEFT, padx=5)
        
        self.clear_btn = ttk.Button(btn_frame, text="🧹 清空表单", command=self.clear_form)
        self.clear_btn.pack(side=tk.LEFT, padx=5)
        
        self.update_btn = ttk.Button(btn_frame, text="💾 更新英雄", command=self.update_hero, state=tk.DISABLED)
        self.update_btn.pack(side=tk.LEFT, padx=5)
        
        self.cancel_btn = ttk.Button(btn_frame, text="❌ 取消编辑", command=self.cancel_edit, state=tk.DISABLED)
        self.cancel_btn.pack(side=tk.LEFT, padx=5)
        
        # ---------- 底部状态 ----------
        status_frame = ttk.Frame(main_frame)
        status_frame.pack(fill=tk.X, pady=(10, 0))
        
        self.status_label = ttk.Label(status_frame, text="💡 就绪", foreground="gray")
        self.status_label.pack(side=tk.LEFT)
        
        # 初始化
        self.current_hero_id = None
        self.refresh_list()
        self.update_stats()
    
    # ---------- 核心功能 ----------
    def refresh_list(self):
        """刷新英雄列表"""
        keyword = self.search_var.get().strip()
        category = self.category_filter_var.get()
        
        if category == "全部":
            category = ""
        
        heroes = self.db.search_heroes(keyword, category)
        
        for item in self.tree.get_children():
            self.tree.delete(item)
        
        for h in heroes:
            self.tree.insert("", tk.END, values=(
                h["id"],
                h["name"],
                h["category"],
                h["era"],
                h["added_date"]
            ))
        
        self.update_stats()
    
    def reset_search(self):
        """重置搜索"""
        self.search_var.set("")
        self.category_filter_var.set("全部")
        self.refresh_list()
    
    def on_select_hero(self, event):
        """选中英雄时显示详情"""
        selected = self.tree.selection()
        if not selected:
            return
        
        item = selected[0]
        values = self.tree.item(item, "values")
        hero_id = int(values[0])
        
        # 查找英雄
        hero = None
        for h in self.db.heroes:
            if h["id"] == hero_id:
                hero = h
                break
        
        if hero:
            self.show_hero_detail(hero)
            self.current_hero_id = hero_id
            # 启用更新按钮
            self.update_btn.config(state=tk.NORMAL)
            self.cancel_btn.config(state=tk.NORMAL)
            # 填入表单
            self.name_entry.delete(0, tk.END)
            self.name_entry.insert(0, hero["name"])
            self.category_var.set(hero["category"])
            self.era_entry.delete(0, tk.END)
            self.era_entry.insert(0, hero["era"])
            self.deeds_entry.delete(1.0, tk.END)
            self.deeds_entry.insert(1.0, hero["deeds"])
            self.quote_entry.delete(0, tk.END)
            self.quote_entry.insert(0, hero["quote"])
            self.add_btn.config(text="➕ 添加新英雄")
    
    def show_hero_detail(self, hero):
        """在详情区域显示英雄信息"""
        self.detail_text.config(state=tk.NORMAL)
        self.detail_text.delete(1.0, tk.END)
        
        detail = f"""
{'='*50}
🦸 姓名：{hero['name']}
📂 分类：{hero['category']}
📅 时代：{hero['era']}
📝 添加时间：{hero['added_date']}

📖 主要事迹：
{hero['deeds']}

💬 名言：
{hero['quote'] if hero['quote'] else '（暂无记录）'}

{'='*50}
        """
        self.detail_text.insert(tk.END, detail)
        self.detail_text.config(state=tk.DISABLED)
    
    def add_hero(self):
        """添加新英雄"""
        name = self.name_entry.get().strip()
        category = self.category_var.get()
        era = self.era_entry.get().strip()
        deeds = self.deeds_entry.get(1.0, tk.END).strip()
        quote = self.quote_entry.get().strip()
        
        if not all([name, category, era, deeds]):
            messagebox.showwarning("提示", "请填写所有必填项（姓名、分类、时代、事迹）")
            return
        
        hero = self.db.add_hero(name, category, era, deeds, quote)
        self.clear_form()
        self.refresh_list()
        self.status_label.config(text=f"✅ 已添加英雄：{hero['name']}", foreground="green")
        messagebox.showinfo("成功", f"🦸 英雄「{hero['name']}」已成功添加！")
    
    def update_hero(self):
        """更新当前英雄"""
        if self.current_hero_id is None:
            return
        
        name = self.name_entry.get().strip()
        category = self.category_var.get()
        era = self.era_entry.get().strip()
        deeds = self.deeds_entry.get(1.0, tk.END).strip()
        quote = self.quote_entry.get().strip()
        
        if not all([name, category, era, deeds]):
            messagebox.showwarning("提示", "请填写所有必填项")
            return
        
        hero = self.db.update_hero(self.current_hero_id, 
                                   name=name, category=category, era=era, 
                                   deeds=deeds, quote=quote)
        if hero:
            self.refresh_list()
            self.show_hero_detail(hero)
            self.status_label.config(text=f"✅ 已更新英雄：{hero['name']}", foreground="green")
            messagebox.showinfo("成功", f"🦸 英雄「{hero['name']}」已更新！")
    
    def delete_hero(self):
        """删除选中英雄"""
        selected = self.tree.selection()
        if not selected:
            messagebox.showwarning("提示", "请先选择一个英雄")
            return
        
        item = selected[0]
        values = self.tree.item(item, "values")
        hero_id = int(values[0])
        hero_name = values[1]
        
        if messagebox.askyesno("确认删除", f"确定要删除英雄「{hero_name}」吗？\n此操作不可恢复！"):
            deleted = self.db.delete_hero(hero_id)
            if deleted:
                self.refresh_list()
                self.detail_text.config(state=tk.NORMAL)
                self.detail_text.delete(1.0, tk.END)
                self.detail_text.config(state=tk.DISABLED)
                self.clear_form()
                self.current_hero_id = None
                self.update_btn.config(state=tk.DISABLED)
                self.cancel_btn.config(state=tk.DISABLED)
                self.status_label.config(text=f"🗑️ 已删除英雄：{deleted['name']}", foreground="red")
    
    def clear_form(self):
        """清空表单"""
        self.name_entry.delete(0, tk.END)
        self.era_entry.delete(0, tk.END)
        self.deeds_entry.delete(1.0, tk.END)
        self.quote_entry.delete(0, tk.END)
        self.category_combo.current(0)
        self.add_btn.config(text="➕ 添加英雄")
        self.current_hero_id = None
        self.update_btn.config(state=tk.DISABLED)
        self.cancel_btn.config(state=tk.DISABLED)
    
    def cancel_edit(self):
        """取消编辑"""
        self.clear_form()
        self.detail_text.config(state=tk.NORMAL)
        self.detail_text.delete(1.0, tk.END)
        self.detail_text.config(state=tk.DISABLED)
        self.status_label.config(text="❌ 已取消编辑", foreground="gray")
    
    def export_all(self):
        """导出所有英雄为文本"""
        if not self.db.heroes:
            messagebox.showinfo("提示", "没有英雄可导出")
            return
        
        filename = f"英雄志_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
        try:
            with open(filename, "w", encoding="utf-8") as f:
                f.write("="*60 + "\n")
                f.write("🦸 英雄志\n")
                f.write(f"📅 导出时间：{datetime.datetime.now().strftime('%Y-%m-%d %H:%M')}\n")
                f.write("="*60 + "\n\n")
                
                for idx, h in enumerate(self.db.heroes, 1):
                    f.write(f"{idx}. {h['name']}\n")
                    f.write(f"   分类：{h['category']}\n")
                    f.write(f"   时代：{h['era']}\n")
                    f.write(f"   事迹：{h['deeds']}\n")
                    if h['quote']:
                        f.write(f"   名言：{h['quote']}\n")
                    f.write(f"   记录时间：{h['added_date']}\n")
                    f.write("-"*40 + "\n\n")
                
                f.write(f"\n📊 共收录 {len(self.db.heroes)} 位英雄\n")
            
            messagebox.showinfo("导出成功", f"英雄志已导出到：{filename}")
            self.status_label.config(text=f"✅ 已导出：{filename}", foreground="green")
        except Exception as e:
            messagebox.showerror("导出失败", f"导出时出错：{str(e)}")
    
    def update_stats(self):
        """更新统计信息"""
        total = len(self.db.heroes)
        # 更新主窗口标题
        self.root.title(f"🦸 英雄事迹记录器 - 共 {total} 位英雄")

# ========== 启动程序 ==========
if __name__ == "__main__":
    root = tk.Tk()
    app = HeroApp(root)
    root.mainloop()