import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import json
import os
from datetime import datetime

class VotingSystem:
    def __init__(self, root):
        self.root = root
        self.root.title("模拟投票调查系统")
        self.root.geometry("750x550")
        self.root.resizable(False, False)
        
        # 数据存储
        self.vote_data = {
            "title": "您最喜欢的编程语言是？",
            "options": ["Python", "Java", "C++", "JavaScript", "Go"],
            "votes": [0, 0, 0, 0, 0],
            "voted_ips": [],
            "create_time": ""
        }
        self.data_file = "vote_data.json"
        
        # 加载已有数据
        self.load_data()
        
        # 设置样式
        self.setup_style()
        
        # 创建界面
        self.create_widgets()
        
    def setup_style(self):
        style = ttk.Style()
        style.theme_use('clam')
        style.configure('TButton', font=('微软雅黑', 10), padding=6)
        style.configure('TLabel', font=('微软雅黑', 10))
        style.configure('Title.TLabel', font=('微软雅黑', 16, 'bold'))
        style.configure('Result.Horizontal.TProgressbar', thickness=25)
        
    def create_widgets(self):
        # 标题区域
        title_frame = ttk.Frame(self.root, padding=20)
        title_frame.pack(fill=tk.X)
        
        self.title_label = ttk.Label(
            title_frame, 
            text=self.vote_data["title"],
            style='Title.TLabel'
        )
        self.title_label.pack()
        
        # 主内容区
        main_frame = ttk.Frame(self.root, padding=20)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 左侧：投票区
        left_frame = ttk.LabelFrame(main_frame, text="投票区", padding=15)
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))
        
        self.vote_frame = ttk.Frame(left_frame)
        self.vote_frame.pack(fill=tk.BOTH, expand=True)
        
        self.selected_var = tk.StringVar()
        self.refresh_vote_options()
        
        # 投票按钮
        vote_btn = ttk.Button(
            left_frame, 
            text="提交投票", 
            command=self.submit_vote,
            width=20
        )
        vote_btn.pack(pady=(15, 0))
        
        # 右侧：结果统计区
        right_frame = ttk.LabelFrame(main_frame, text="实时结果统计", padding=15)
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(10, 0))
        
        self.result_frame = ttk.Frame(right_frame)
        self.result_frame.pack(fill=tk.BOTH, expand=True)
        
        self.total_label = ttk.Label(right_frame, text="总票数：0 票")
        self.total_label.pack(pady=(10, 0), anchor=tk.W)
        
        self.refresh_results()
        
        # 底部操作区
        bottom_frame = ttk.Frame(self.root, padding=20)
        bottom_frame.pack(fill=tk.X)
        
        btn_frame = ttk.Frame(bottom_frame)
        btn_frame.pack()
        
        ttk.Button(
            btn_frame, 
            text="新建投票", 
            command=self.create_new_vote,
            width=15
        ).pack(side=tk.LEFT, padx=5)
        
        ttk.Button(
            btn_frame, 
            text="重置票数", 
            command=self.reset_votes,
            width=15
        ).pack(side=tk.LEFT, padx=5)
        
        ttk.Button(
            btn_frame, 
            text="保存数据", 
            command=self.save_data,
            width=15
        ).pack(side=tk.LEFT, padx=5)
        
    def refresh_vote_options(self):
        # 清空现有选项
        for widget in self.vote_frame.winfo_children():
            widget.destroy()
            
        self.selected_var.set("")
        
        for i, option in enumerate(self.vote_data["options"]):
            rb = ttk.Radiobutton(
                self.vote_frame,
                text=option,
                variable=self.selected_var,
                value=option
            )
            rb.pack(anchor=tk.W, pady=8)
            
    def refresh_results(self):
        # 清空现有结果
        for widget in self.result_frame.winfo_children():
            widget.destroy()
            
        total = sum(self.vote_data["votes"])
        
        for i, option in enumerate(self.vote_data["options"]):
            votes = self.vote_data["votes"][i]
            percent = (votes / total * 100) if total > 0 else 0
            
            # 选项名称
            label = ttk.Label(self.result_frame, text=f"{option}: {votes}票 ({percent:.1f}%)")
            label.pack(anchor=tk.W, pady=(5, 2))
            
            # 进度条
            pb = ttk.Progressbar(
                self.result_frame,
                orient=tk.HORIZONTAL,
                length=200,
                mode='determinate',
                style='Result.Horizontal.TProgressbar'
            )
            pb['value'] = percent
            pb.pack(fill=tk.X, pady=(0, 8))
            
        self.total_label.config(text=f"总票数：{total} 票")
        
    def submit_vote(self):
        selected = self.selected_var.get()
        if not selected:
            messagebox.showwarning("提示", "请先选择一个选项！")
            return
            
        # 简单防重复：使用时间戳模拟
        vote_id = str(hash(datetime.now().strftime("%Y%m%d%H%M%S%f")))
        if vote_id in self.vote_data["voted_ips"]:
            messagebox.showwarning("提示", "您已经投过票了！")
            return
            
        # 记录投票
        idx = self.vote_data["options"].index(selected)
        self.vote_data["votes"][idx] += 1
        self.vote_data["voted_ips"].append(vote_id)
        
        # 更新界面
        self.refresh_results()
        messagebox.showinfo("成功", f"您已成功为「{selected}」投票！")
        self.selected_var.set("")
        
    def create_new_vote(self):
        # 输入标题
        title = simpledialog.askstring("新建投票", "请输入投票标题：", parent=self.root)
        if not title:
            return
            
        # 输入选项数量
        try:
            num = simpledialog.askinteger(
                "新建投票", 
                "请输入选项数量（2-10）：", 
                parent=self.root,
                minvalue=2,
                maxvalue=10
            )
        except:
            return
            
        if not num:
            return
            
        # 逐个输入选项
        options = []
        for i in range(num):
            opt = simpledialog.askstring(
                "新建投票", 
                f"请输入第 {i+1} 个选项：", 
                parent=self.root
            )
            if not opt:
                messagebox.showwarning("提示", "选项不能为空，创建已取消")
                return
            options.append(opt)
            
        # 确认创建
        if messagebox.askyesno("确认", "确定创建新投票吗？当前数据将被覆盖。"):
            self.vote_data = {
                "title": title,
                "options": options,
                "votes": [0] * num,
                "voted_ips": [],
                "create_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }
            self.title_label.config(text=title)
            self.refresh_vote_options()
            self.refresh_results()
            self.save_data()
            messagebox.showinfo("成功", "新投票创建完成！")
            
    def reset_votes(self):
        if messagebox.askyesno("确认", "确定要重置所有票数吗？此操作不可撤销。"):
            self.vote_data["votes"] = [0] * len(self.vote_data["options"])
            self.vote_data["voted_ips"] = []
            self.refresh_results()
            messagebox.showinfo("成功", "票数已重置")
            
    def save_data(self):
        try:
            with open(self.data_file, 'w', encoding='utf-8') as f:
                json.dump(self.vote_data, f, ensure_ascii=False, indent=2)
            messagebox.showinfo("成功", "投票数据已保存到本地")
        except Exception as e:
            messagebox.showerror("错误", f"保存失败：{str(e)}")
            
    def load_data(self):
        if os.path.exists(self.data_file):
            try:
                with open(self.data_file, 'r', encoding='utf-8') as f:
                    self.vote_data = json.load(f)
            except:
                pass
                
    def on_closing(self):
        self.save_data()
        self.root.destroy()

def main():
    root = tk.Tk()
    app = VotingSystem(root)
    root.protocol("WM_DELETE_WINDOW", app.on_closing)
    root.mainloop()

if __name__ == "__main__":
    main()