import tkinter as tk
from tkinter import ttk, messagebox, colorchooser
import math
import random
import json
import os
from datetime import datetime
import time
import threading

class SpinningWheel:
    def __init__(self, root):
        self.root = root
        self.root.title("🎡 幸运大转盘")
        self.root.geometry("800x750")
        
        # 颜色方案
        self.colors = [
            '#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4',
            '#FFEAA7', '#DDA0DD', '#98D8C8', '#F7DC6F',
            '#BB8FCE', '#85C1E9', '#F0B27A', '#82E0AA',
            '#F1948A', '#85929E', '#73C6B6', '#E59866'
        ]
        
        # 默认奖品
        self.default_prizes = [
            "一等奖\niPhone 15", "二等奖\nAirPods", "三等奖\n充电宝",
            "四等奖\n优惠券", "五等奖\n红包", "六等奖\n谢谢参与",
            "七等奖\n小礼品", "八等奖\n再来一次"
        ]
        
        self.prizes = self.default_prizes.copy()
        self.prize_counts = [1] * len(self.prizes)  # 各奖品剩余数量
        
        # 转盘参数
        self.rotation_angle = 0
        self.is_spinning = False
        self.speed = 0
        self.target_angle = 0
        self.history = []
        
        # 创建界面
        self.create_widgets()
        
        # 加载数据
        self.load_data()
        
    def create_widgets(self):
        # 主框架
        main_frame = ttk.Frame(self.root, padding=10)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 左侧控制面板
        control_frame = ttk.LabelFrame(main_frame, text="控制面板", padding=10)
        control_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10))
        
        # 奖品设置
        tk.Label(control_frame, text="奖品设置:", font=("微软雅黑", 10, "bold")).pack(anchor='w', pady=(0, 5))
        
        self.prize_text = tk.Text(control_frame, width=25, height=8, font=("微软雅黑", 9))
        self.prize_text.pack(pady=(0, 5))
        self.prize_text.insert('1.0', '\n'.join(self.prizes))
        
        # 按钮
        btn_frame = tk.Frame(control_frame)
        btn_frame.pack(fill=tk.X, pady=5)
        
        tk.Button(btn_frame, text="更新奖品", command=self.update_prizes, 
                 bg="#3498db", fg="white", width=10).pack(side=tk.LEFT, padx=2)
        tk.Button(btn_frame, text="重置奖品", command=self.reset_prizes, 
                 bg="#e67e22", fg="white", width=10).pack(side=tk.LEFT, padx=2)
        
        # 抽奖控制
        tk.Label(control_frame, text="抽奖控制:", font=("微软雅黑", 10, "bold")).pack(anchor='w', pady=(10, 5))
        
        self.spin_btn = tk.Button(control_frame, text="🎯 开始抽奖", command=self.start_spin,
                                 bg="#e74c3c", fg="white", font=("微软雅黑", 14, "bold"),
                                 width=20, height=2)
        self.spin_btn.pack(pady=10)
        
        # 结果
        tk.Label(control_frame, text="抽奖结果:", font=("微软雅黑", 10, "bold")).pack(anchor='w', pady=(5, 5))
        self.result_var = tk.StringVar(value="点击开始抽奖")
        tk.Label(control_frame, textvariable=self.result_var, 
                font=("微软雅黑", 12, "bold"), fg="#e74c3c", wraplength=200).pack(pady=5)
        
        # 统计信息
        tk.Label(control_frame, text="统计信息:", font=("微软雅黑", 10, "bold")).pack(anchor='w', pady=(10, 5))
        self.stats_var = tk.StringVar(value="总抽奖: 0 次")
        tk.Label(control_frame, textvariable=self.stats_var, font=("微软雅黑", 9)).pack(anchor='w')
        
        # 右侧转盘区域
        wheel_frame = ttk.LabelFrame(main_frame, text="转盘", padding=10)
        wheel_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
        
        # 转盘画布
        self.canvas = tk.Canvas(wheel_frame, width=450, height=480, bg='white', highlightthickness=0)
        self.canvas.pack()
        
        # 指针
        self.canvas.create_polygon(225, 20, 210, 70, 240, 70, fill="#e74c3c", outline="black", width=2)
        self.canvas.create_circle(225, 470, 10, fill="#e74c3c", outline="black", width=2)
        
        # 绘制转盘
        self.draw_wheel()
        
        # 历史记录
        history_frame = ttk.LabelFrame(self.root, text="中奖记录", padding=5)
        history_frame.pack(fill=tk.X, padx=10, pady=(0, 10))
        
        # 创建Treeview
        columns = ('time', 'prize', 'count')
        self.history_tree = ttk.Treeview(history_frame, columns=columns, show='headings', height=4)
        
        self.history_tree.heading('time', text='时间')
        self.history_tree.heading('prize', text='奖品')
        self.history_tree.heading('count', text='剩余')
        
        self.history_tree.column('time', width=150)
        self.history_tree.column('prize', width=200)
        self.history_tree.column('count', width=50)
        
        self.history_tree.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        scrollbar = ttk.Scrollbar(history_frame, orient=tk.VERTICAL, command=self.history_tree.yview)
        self.history_tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
    def draw_wheel(self):
        """绘制转盘"""
        self.canvas.delete("wheel")
        
        cx, cy = 245, 260  # 中心点
        radius = 210
        
        n = len(self.prizes)
        if n == 0:
            return
            
        angle_step = 2 * math.pi / n
        
        for i in range(n):
            start_angle = self.rotation_angle + i * angle_step
            end_angle = start_angle + angle_step
            
            # 计算扇形路径
            points = [(cx, cy)]
            steps = 30
            for j in range(steps + 1):
                angle = start_angle + (end_angle - start_angle) * j / steps
                x = cx + radius * math.cos(angle)
                y = cy + radius * math.sin(angle)
                points.append((x, y))
            
            # 绘制扇形
            color = self.colors[i % len(self.colors)]
            self.canvas.create_polygon(points, fill=color, outline="white", width=2, tags="wheel")
            
            # 绘制文字
            mid_angle = (start_angle + end_angle) / 2
            text_radius = radius * 0.62
            tx = cx + text_radius * math.cos(mid_angle)
            ty = cy + text_radius * math.sin(mid_angle)
            
            # 分行显示
            prize_lines = self.prizes[i].split('\n')
            for li, line in enumerate(prize_lines):
                line_radius = text_radius - li * 15
                lx = cx + line_radius * math.cos(mid_angle)
                ly = cy + line_radius * math.sin(mid_angle)
                
                self.canvas.create_text(lx, ly, text=line, 
                                       font=("微软雅黑", 8, "bold"), 
                                       fill="white", angle=math.degrees(mid_angle),
                                       tags="wheel")
        
        # 绘制中心圆
        self.canvas.create_oval(cx-30, cy-30, cx+30, cy+30, 
                               fill="#2c3e50", outline="white", width=3, tags="wheel")
        self.canvas.create_text(cx, cy, text="抽奖", 
                               font=("微软雅黑", 12, "bold"), fill="white", tags="wheel")
        
        # 绘制外圈装饰
        self.canvas.create_oval(cx-radius-10, cy-radius-10, cx+radius+10, cy+radius+10,
                               outline="#f1c40f", width=5, tags="wheel")
        
        # 绘制灯泡装饰
        for i in range(20):
            angle = 2 * math.pi * i / 20
            bx = cx + (radius + 15) * math.cos(angle)
            by = cy + (radius + 15) * math.sin(angle)
            bulb_color = "#f1c40f" if i % 2 == 0 else "#e74c3c"
            self.canvas.create_oval(bx-5, by-5, bx+5, by+5, 
                                   fill=bulb_color, outline="", tags="wheel")
            
    def start_spin(self):
        """开始抽奖"""
        if self.is_spinning:
            return
            
        if not self.prizes:
            messagebox.showwarning("警告", "请先设置奖品！")
            return
            
        # 检查是否还有奖品
        if sum(self.prize_counts) == 0:
            messagebox.showinfo("提示", "所有奖品已抽完！")
            return
            
        self.is_spinning = True
        self.spin_btn.config(state='disabled')
        
        # 随机目标角度
        self.target_angle = random.uniform(720, 1440)  # 2-4圈
        self.speed = random.uniform(15, 25)
        
        # 开始动画
        self.animate_spin()
        
    def animate_spin(self):
        """旋转动画"""
        if self.speed > 0.5:
            # 减速
            self.speed *= 0.97
            self.rotation_angle += self.speed
            
            # 更新转盘
            self.draw_wheel()
            
            # 继续动画
            self.root.after(20, self.animate_spin)
        else:
            # 停止转动
            self.is_spinning = False
            self.spin_btn.config(state='normal')
            self.determine_prize()
            
    def determine_prize(self):
        """确定中奖奖品"""
        n = len(self.prizes)
        if n == 0:
            return
            
        # 计算指针指向的奖品
        normalized_angle = self.rotation_angle % (2 * math.pi)
        angle_step = 2 * math.pi / n
        prize_index = int(normalized_angle / angle_step)
        
        # 检查奖品是否还有剩余
        if self.prize_counts[prize_index] <= 0:
            # 奖品已抽完，随机分配其他奖品
            available = [i for i, count in enumerate(self.prize_counts) if count > 0]
            if available:
                prize_index = random.choice(available)
            else:
                messagebox.showinfo("提示", "所有奖品已抽完！")
                return
        
        # 减少奖品数量
        self.prize_counts[prize_index] -= 1
        
        # 获取奖品名称
        prize_name = self.prizes[prize_index].replace('\n', ' ')
        
        # 显示结果
        self.result_var.set(f"🎉 恭喜获得：{prize_name}")
        
        # 添加历史记录
        timestamp = datetime.now().strftime('%H:%M:%S')
        self.history_tree.insert('', 'end', values=(timestamp, prize_name, self.prize_counts[prize_index]))
        
        # 更新统计
        total = sum(self.prize_counts)
        total_spins = len(self.history_tree.get_children())
        self.stats_var.set(f"总抽奖: {total_spins} 次 | 剩余奖品: {total} 个")
        
        # 保存数据
        self.save_data()
        
    def update_prizes(self):
        """更新奖品"""
        text = self.prize_text.get('1.0', tk.END).strip()
        if not text:
            messagebox.showwarning("警告", "请输入奖品！")
            return
            
        new_prizes = text.split('\n')
        if len(new_prizes) < 2:
            messagebox.showwarning("警告", "至少需要2个奖品！")
            return
            
        if len(new_prizes) > 16:
            messagebox.showwarning("警告", "最多16个奖品！")
            return
            
        self.prizes = new_prizes
        self.prize_counts = [999] * len(new_prizes)  # 默认大量剩余
        
        # 重绘转盘
        self.draw_wheel()
        self.save_data()
        messagebox.showinfo("成功", f"已更新 {len(new_prizes)} 个奖品！")
        
    def reset_prizes(self):
        """重置奖品"""
        self.prizes = self.default_prizes.copy()
        self.prize_counts = [999] * len(self.prizes)
        
        self.prize_text.delete('1.0', tk.END)
        self.prize_text.insert('1.0', '\n'.join(self.prizes))
        
        self.draw_wheel()
        self.save_data()
        messagebox.showinfo("成功", "已恢复默认奖品！")
        
    def save_data(self):
        """保存数据"""
        data = {
            'prizes': self.prizes,
            'prize_counts': self.prize_counts,
            'history': [(self.history_tree.item(item)['values'][0],
                        self.history_tree.item(item)['values'][1],
                        self.history_tree.item(item)['values'][2])
                       for item in self.history_tree.get_children()]
        }
        
        try:
            with open('wheel_data.json', 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
        except:
            pass
            
    def load_data(self):
        """加载数据"""
        try:
            if os.path.exists('wheel_data.json'):
                with open('wheel_data.json', 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    
                self.prizes = data.get('prizes', self.default_prizes)
                self.prize_counts = data.get('prize_counts', [999] * len(self.prizes))
                
                # 更新显示
                self.prize_text.delete('1.0', tk.END)
                self.prize_text.insert('1.0', '\n'.join(self.prizes))
                
                # 加载历史
                history = data.get('history', [])
                for item in history:
                    self.history_tree.insert('', 'end', values=item)
                    
                # 更新统计
                total = sum(self.prize_counts)
                total_spins = len(self.history_tree.get_children())
                self.stats_var.set(f"总抽奖: {total_spins} 次 | 剩余奖品: {total} 个")
                
                # 重绘转盘
                self.draw_wheel()
        except:
            pass

# 添加canvas的create_circle方法
def _create_circle(self, x, y, r, **kwargs):
    return self.create_oval(x-r, y-r, x+r, y+r, **kwargs)
tk.Canvas.create_circle = _create_circle

# 运行程序
if __name__ == "__main__":
    root = tk.Tk()
    app = SpinningWheel(root)
    root.mainloop()