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

DATA_FILE = "votes.json"

class VotingSystemApp:
    def __init__(self, root):
        self.root = root
        self.root.title("043. 模拟投票 / 调查系统")
        self.root.geometry("680x560")
        self.root.resizable(False, False)

        self.votes = {}
        self.current_topic = None
        self.voted = set()

        self.load_data()
        self.build_ui()
        self.refresh_list()

    # ========== 数据持久化 ==========
    def load_data(self):
        if os.path.exists(DATA_FILE):
            try:
                with open(DATA_FILE, "r", encoding="utf-8") as f:
                    self.votes = json.load(f)
            except:
                self.votes = {}
        else:
            self.votes = {}

    def save_data(self):
        with open(DATA_FILE, "w", encoding="utf-8") as f:
            json.dump(self.votes, f, ensure_ascii=False, indent=2)

    # ========== UI ==========
    def build_ui(self):
        # 标题
        tk.Label(
            self.root, text="🗳️ 模拟投票 / 调查系统",
            font=("微软雅黑", 18, "bold")
        ).pack(pady=10)

        # ===== 左侧：投票列表 =====
        left = tk.LabelFrame(self.root, text="投票主题", font=("微软雅黑", 10))
        left.place(x=20, y=50, width=240, height=480)

        self.topic_list = tk.Listbox(left, font=("微软雅黑", 10))
        self.topic_list.pack(fill=tk.BOTH, expand=True, padx=8, pady=5)
        self.topic_list.bind("<<ListboxSelect>>", self.on_select_topic)

        tk.Button(left, text="新建投票", width=12,
                  bg="#4CAF50", fg="white",
                  command=self.create_vote).pack(pady=3)
        tk.Button(left, text="删除投票", width=12,
                  bg="#f44336", fg="white",
                  command=self.delete_vote).pack(pady=3)

        # ===== 右侧：投票区 =====
        right = tk.Frame(self.root)
        right.place(x=280, y=50, width=380, height=480)

        # 主题
        self.topic_label = tk.Label(
            right, text="请选择或创建一个投票主题",
            font=("微软雅黑", 12, "bold"), fg="#1565C0"
        )
        self.topic_label.pack(pady=10)

        # 选项区
        self.options_frame = tk.LabelFrame(right, text="选项", font=("微软雅黑", 10))
        self.options_frame.pack(fill=tk.X, padx=10, pady=5)

        # 投票按钮
        btn_frame = tk.Frame(right)
        btn_frame.pack(pady=5)

        self.vote_btn = tk.Button(
            btn_frame, text="✅ 投票",
            width=12, height=2,
            bg="#4CAF50", fg="white",
            font=("微软雅黑", 11, "bold"),
            command=self.cast_vote,
            state="disabled"
        )
        self.vote_btn.pack(side=tk.LEFT, padx=5)

        tk.Button(
            btn_frame, text="添加选项",
            width=12, bg="#FF9800", fg="white",
            command=self.add_option
        ).pack(side=tk.LEFT, padx=5)

        tk.Button(
            btn_frame, text="刷新",
            width=8, bg="#2196F3", fg="white",
            command=self.refresh_vote_display
        ).pack(side=tk.LEFT, padx=5)

        # 结果区
        result_frame = tk.LabelFrame(right, text="实时结果", font=("微软雅黑", 10))
        result_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        self.result_text = tk.Text(
            result_frame, font=("Consolas", 10),
            wrap=tk.WORD, state=tk.DISABLED
        )
        self.result_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 底部
        tk.Button(
            self.root, text="导出全部结果",
            bg="#9C27B0", fg="white",
            command=self.export_all
        ).place(x=20, y=540)

    # ========== 投票逻辑 ==========
    def create_vote(self):
        topic = simpledialog.askstring("新建投票", "请输入投票主题：")
        if not topic or not topic.strip():
            return

        if topic in self.votes:
            messagebox.showwarning("提示", "该投票主题已存在！")
            return

        self.votes[topic] = {}
        self.save_data()
        self.refresh_list()
        self.topic_list.selection_clear(0, tk.END)
        # 选中新建的
        idx = list(self.votes.keys()).index(topic)
        self.topic_list.selection_set(idx)
        self.on_select_topic(None)

        messagebox.showinfo("成功", f"投票主题「{topic}」已创建！\n请添加选项。")

    def delete_vote(self):
        if not self.current_topic:
            messagebox.showwarning("提示", "请先选择投票主题！")
            return
        if messagebox.askyesno("确认", f"删除投票「{self.current_topic}」？\n此操作不可恢复！"):
            del self.votes[self.current_topic]
            self.current_topic = None
            self.save_data()
            self.refresh_list()
            self.topic_label.config(text="请选择或创建一个投票主题")
            self.clear_options()
            self.result_text.config(state=tk.NORMAL)
            self.result_text.delete("1.0", tk.END)
            self.result_text.config(state=tk.DISABLED)
            self.vote_btn.config(state="disabled")

    def on_select_topic(self, e):
        sel = self.topic_list.curselection()
        if not sel:
            return
        self.current_topic = self.topic_list.get(sel[0])
        self.topic_label.config(text=f"📋 {self.current_topic}")
        self.refresh_vote_display()
        self.vote_btn.config(state="normal")

    def add_option(self):
        if not self.current_topic:
            messagebox.showwarning("提示", "请先选择投票主题！")
            return

        option = simpledialog.askstring("添加选项", "请输入选项名称：")
        if not option or not option.strip():
            return

        option = option.strip()
        if option in self.votes[self.current_topic]:
            messagebox.showwarning("提示", "该选项已存在！")
            return

        self.votes[self.current_topic][option] = 0
        self.save_data()
        self.refresh_vote_display()

    def cast_vote(self):
        if not self.current_topic:
            return

        selected = self.option_var.get() if hasattr(self, 'option_var') else None
        if not selected:
            messagebox.showwarning("提示", "请先选择一个选项！")
            return

        if self.current_topic in self.voted:
            messagebox.showinfo("提示", "您已经投过票了！")
            return

        self.votes[self.current_topic][selected] += 1
        self.voted.add(self.current_topic)
        self.save_data()
        self.refresh_vote_display()
        messagebox.showinfo("成功", f"感谢您的投票！您选择了「{selected}」")

    def refresh_vote_display(self):
        if not self.current_topic:
            return

        # 清空选项区
        self.clear_options()

        options = self.votes[self.current_topic]
        if not options:
            tk.Label(self.options_frame, text="暂无选项，请添加",
                      font=("微软雅黑", 9), fg="#999").pack(pady=10)
            self.vote_btn.config(state="disabled")
            self.update_result("暂无投票数据")
            return

        self.option_var = tk.StringVar()

        for opt in options:
            rb = tk.Radiobutton(
                self.options_frame, text=opt,
                variable=self.option_var, value=opt,
                font=("微软雅黑", 9)
            )
            rb.pack(anchor="w", padx=10, pady=2)

        # 更新结果
        total = sum(options.values())
        lines = []
        for opt, count in options.items():
            pct = (count / total * 100) if total > 0 else 0
            bar_len = int(pct / 2)  # 最长 50 字符
            bar = "█" * bar_len + "░" * (50 - bar_len)
            lines.append(f"  {opt:<15s} | {bar} {count} 票 ({pct:.1f}%)")

        lines.append(f"\n  总投票数：{total}")
        self.update_result("\n".join(lines))

        if self.current_topic in self.voted:
            self.vote_btn.config(state="disabled")
        else:
            self.vote_btn.config(state="normal")

    def update_result(self, text):
        self.result_text.config(state=tk.NORMAL)
        self.result_text.delete("1.0", tk.END)
        self.result_text.insert("1.0", text)
        self.result_text.config(state=tk.DISABLED)

    def clear_options(self):
        for w in self.options_frame.winfo_children():
            w.destroy()

    def refresh_list(self):
        self.topic_list.delete(0, tk.END)
        for topic in self.votes:
            count = sum(self.votes[topic].values())
            self.topic_list.insert(tk.END, f"{topic} ({count} 票)")

    def export_all(self):
        if not self.votes:
            messagebox.showwarning("提示", "暂无投票数据！")
            return

        with open("投票结果.txt", "w", encoding="utf-8") as f:
            for topic, options in self.votes.items():
                total = sum(options.values())
                f.write(f"\n{'='*50}\n")
                f.write(f"投票主题：{topic}\n")
                f.write(f"{'='*50}\n")
                for opt, count in options.items():
                    pct = (count / total * 100) if total > 0 else 0
                    f.write(f"  {opt}: {count} 票 ({pct:.1f}%)\n")
                f.write(f"  总投票数：{total}\n")

        messagebox.showinfo("导出成功", "投票结果已导出为：投票结果.txt")


if __name__ == "__main__":
    root = tk.Tk()
    VotingSystemApp(root)
    root.mainloop()