import tkinter as tk
from tkinter import messagebox, font
import random
import time
import threading
import math

class Game:
    def __init__(self, root):
        self.root = root
        self.root.title("彩虹六号:炸弹冲锋2D简化版")
        self.root.geometry("1024x768")
        self.root.resizable(False, False)
        self.font_family = "SimHei"
        self.init_game_states()
        self.obstacles = self.load_obstacles()
        self.bank_structure = self.load_bank_structure()
        self.create_start_screen()

    def init_game_states(self):
        self.game_active = False
        self.defender_turn = self.attacker_turn = False
        self.bomb_planted = self.bomb_defused = False
        self.defender_wins = self.attacker_wins = False
        self.defense_timer = 60
        self.game_timer = 300
        self.timer_running = False
        self.player_count, self.ai_count = 1, 4
        self.defenders = self.attackers = []
        self.defense_objects = []
        self.bomb_site = {"x": 512, "y": 384, "radius": 50}
        self.defuser = None
        self.player_speed = 5
        self.key_pressed = {"w": False, "a": False, "s": False, "d": False}
        self.mouse_x = self.mouse_y = 512
        self.player_direction = 0

    def load_obstacles(self):
        return [
            (50, 50, 974, 100), (50, 618, 974, 668),
            (50, 50, 100, 618), (924, 50, 974, 618),
            (200, 200, 250, 250), (400, 200, 450, 250),
            (600, 200, 650, 250), (800, 200, 850, 250),
            (200, 400, 250, 450), (400, 400, 450, 450),
            (600, 400, 650, 450), (800, 400, 850, 450),
            (450, 300, 574, 350), (450, 424, 574, 474),
            (450, 300, 500, 474), (524, 300, 574, 474),
            (475, 325, 550, 450),
            (300, 150, 350, 300), (650, 150, 700, 300),
            (300, 400, 350, 550), (650, 400, 700, 550),
            (350, 250, 674, 300),
            (150, 150, 200, 200, "breakable"),
            (824, 150, 874, 200, "breakable"),
            (150, 450, 200, 500, "breakable"),
            (824, 450, 874, 500, "breakable"),
        ]

    def load_bank_structure(self):
        return {
            "floors": 2,
            "elevators": [{"x": 200, "y": 300, "width": 50, "height": 50},
                          {"x": 800, "y": 300, "width": 50, "height": 50}],
            "doors": [{"x": 100, "y": 300, "width": 50, "height": 50, "state": "closed"},
                      {"x": 924, "y": 300, "width": 50, "height": 50, "state": "closed"},
                      {"x": 500, "y": 300, "width": 24, "height": 50, "state": "locked"}]
        }

    def create_start_screen(self):
        for widget in self.root.winfo_children(): widget.destroy()
        start_frame = tk.Frame(self.root, bg="#1a1a2e")
        start_frame.pack(fill=tk.BOTH, expand=True)
        
        title_font = font.Font(family=self.font_family, size=36, weight="bold")
        tk.Label(start_frame, text="彩虹六号:炸弹冲锋2D简化版", font=title_font, fg="#e94560", bg="#1a1a2e").pack(pady=50)
        
        button_frame = tk.Frame(start_frame, bg="#1a1a2e")
        button_frame.pack(pady=100)
        
        tk.Button(button_frame, text="选择防守方", command=self.select_defender,
                  font=(self.font_family, 16), bg="#4CAF50", fg="white", width=15, height=2, cursor="hand2").pack(side=tk.LEFT, padx=20)
        
        tk.Button(button_frame, text="选择进攻方", command=self.select_attacker,
                  font=(self.font_family, 16), bg="#F44336", fg="white", width=15, height=2, cursor="hand2").pack(side=tk.LEFT, padx=20)

    def select_defender(self):
        self.defender_turn = True
        self.create_game_screen()
        self.initialize_players("defender")
        self.start_defense_prep_phase()
        self.setup_controls()

    def select_attacker(self):
        self.attacker_turn = True
        self.create_game_screen()
        self.initialize_players("attacker")
        self.start_attack_phase()
        self.setup_controls()

    def create_game_screen(self):
        for widget in self.root.winfo_children(): widget.destroy()
        self.game_frame = tk.Frame(self.root, bg="#0f3460")
        self.game_frame.pack(fill=tk.BOTH, expand=True)
        
        self.canvas = tk.Canvas(self.game_frame, bg="#16213e", width=1024, height=668)
        self.canvas.pack()
        self.draw_bank_map()
        
        self.status_frame = tk.Frame(self.game_frame, bg="#0f3460", height=100)
        self.status_frame.pack(fill=tk.X)
        self.timer_label = tk.Label(self.status_frame, text="01:00", font=(self.font_family, 24), fg="white", bg="#0f3460")
        self.timer_label.pack(side=tk.LEFT, padx=20)

    def draw_bank_map(self):
        self.canvas.create_rectangle(50, 50, 974, 618, fill="#2c497f", outline="#e94560", width=2)
        self.canvas.create_rectangle(100, 100, 924, 568, fill="#16213e", outline="#2c497f", width=5)
        
        for x in [200, 400, 600, 800] for y in [200, 400]:
            self.canvas.create_oval(x-20, y-20, x+20, y+20, fill="#d0d0d0", outline="#a0a0a0")
            self.canvas.create_rectangle(x-15, y-20, x+15, y+100, fill="#e0e0e0", outline="#c0c0c0")
            self.canvas.create_oval(x-20, y+100, x+20, y+120, fill="#d0d0d0", outline="#a0a0a0")
        
        self.canvas.create_text(512, 75, text="BANK OF RAINBOW", font=(self.font_family, 24, "bold"), fill="#e94560")
        self.canvas.create_rectangle(*self.bomb_site_coords(), fill="#1a1a2e", outline="#e94560", width=3)

    def bomb_site_coords(self):
        return (self.bomb_site["x"] - self.bomb_site["radius"], 
                self.bomb_site["y"] - self.bomb_site["radius"],
                self.bomb_site["x"] + self.bomb_site["radius"], 
                self.bomb_site["y"] + self.bomb_site["radius"])

    def initialize_players(self, role):
        self.defenders = self.attackers = []
        if role == "defender":
            self.add_player("defender", (512, 384))
            for _ in range(self.ai_count): self.add_ai("defender")
        else:
            self.add_player("attacker", (100, 334))
            for _ in range(self.ai_count): self.add_ai("attacker", is_left=random.choice([True, False]))

    def add_player(self, role, pos):
        unit = {
            "id": 0, "x": pos[0], "y": pos[1], "health": 100, "is_player": True,
            "role": role, "state": "idle", "path": [], "target": None,
            "color": "blue" if role == "defender" else "red"
        }
        self.draw_unit(unit)
        (self.defenders if role == "defender" else self.attackers).append(unit)

    def add_ai(self, role, is_left=True):
        x, y = (100, random.randint(284, 384)) if is_left else (924, random.randint(284, 384))
        unit = {
            "id": len(self.defenders)+len(self.attackers), "x": x, "y": y, "health": 100, "is_player": False,
            "role": role, "state": "patrol", "path": [], "target": None,
            "color": "blue" if role == "defender" else "red",
            "difficulty": random.randint(1, 3), "behavior": random.choice(["aggressive", "cautious"])
        }
        self.draw_unit(unit)
        (self.defenders if role == "defender" else self.attackers).append(unit)

    def draw_unit(self, unit):
        size = 15 if unit["is_player"] else 10
        unit["canvas_obj"] = self.canvas.create_oval(
            unit["x"] - size, unit["y"] - size,
            unit["x"] + size, unit["y"] + size,
            fill=unit["color"]
        )
        self.canvas.create_text(unit["x"], unit["y"], text=str(unit["id"]), fill="white", font=(self.font_family, 10))

    def setup_controls(self):
        self.root.bind("<KeyPress>", self.on_key_press)
        self.root.bind("<KeyRelease>", self.on_key_release)
        self.canvas.bind("<Motion>", self.on_mouse_move)
        self.canvas.bind("<Button-1>", self.on_mouse_click)

    def on_key_press(self, event):
        if event.keysym.lower() in self.key_pressed:
            self.key_pressed[event.keysym.lower()] = True

    def on_key_release(self, event):
        if event.keysym.lower() in self.key_pressed:
            self.key_pressed[event.keysym.lower()] = False

    def on_mouse_move(self, event):
        self.mouse_x, self.mouse_y = event.x, event.y
        self.update_player_direction()

    def update_player_direction(self):
        if not self.defenders and not self.attackers: return
        player = self.defenders[0] if self.defender_turn else self.attackers[0]
        dx = self.mouse_x - player["x"]
        dy = self.mouse_y - player["y"]
        player["direction"] = math.atan2(dy, dx)
        self.update_aim_indicator(player)

    def update_aim_indicator(self, player):
        if "direction_line" in player:
            self.canvas.delete(player["direction_line"])
        player["direction_line"] = self.canvas.create_line(
            player["x"], player["y"],
            player["x"] + math.cos(player["direction"]) * 20,
            player["y"] + math.sin(player["direction"]) * 20,
            fill="yellow", width=2
        )

    def on_mouse_click(self, event):
        if not self.game_active: return
        player = self.defenders[0] if self.defender_turn else self.attackers[0]
        self.shoot(player, event.x, event.y)

    def shoot(self, shooter, mx, my):
        angle = math.atan2(my - shooter["y"], mx - shooter["x"])
        dx, dy = math.cos(angle) * 300, math.sin(angle) * 300
        x1, y1, x2, y2 = shooter["x"], shooter["y"], shooter["x"]+dx, shooter["y"]+dy
        
        for obs in self.obstacles:
            if len(obs) >= 4 and self.line_intersects_rect(x1, y1, x2, y2, *obs[:4]):
                x2, y2 = self.get_intersection(x1, y1, x2, y2, *obs[:4])
                break
        
        self.canvas.create_line(x1, y1, x2, y2, fill="yellow", width=2)
        self.damage_nearby_units(shooter, x2, y2, angle)

    def damage_nearby_units(self, shooter, x, y, angle):
        targets = self.defenders if shooter["role"] == "attacker" else self.attackers
        for target in targets:
            if target["health"] <= 0: continue
            dist = math.hypot(x - target["x"], y - target["y"])
            if dist < 20 and self.has_line_of_sight(shooter, target):
                target["health"] -= 25
                if target["health"] <= 0: self.delete_unit(target)

    def has_line_of_sight(self, unit1, unit2):
        x1, y1, x2, y2 = unit1["x"], unit1["y"], unit2["x"], unit2["y"]
        for obs in self.obstacles:
            if len(obs) >= 4 and self.line_intersects_rect(x1, y1, x2, y2, *obs[:4]):
                return False
        return True

    def line_intersects_rect(self, x1, y1, x2, y2, rx1, ry1, rx2, ry2):
        dx = x2 - x1; dy = y2 - y1
        t = [(rx1 - x1)/dx, (rx2 - x1)/dx] if dx != 0 else [0, 0]
        u = [(ry1 - y1)/dy, (ry2 - y1)/dy] if dy != 0 else [0, 0]
        tmin = max(min(t), min(u))
        tmax = min(max(t), max(u))
        return tmin <= tmax and tmin >= 0 and tmax <= 1

    def get_intersection(self, x1, y1, x2, y2, rx1, ry1, rx2, ry2):
        dx = x2 - x1; dy = y2 - y1
        t = ( (rx1 - x1)*dy - (ry1 - y1)*dx, (rx2 - x1)*dy - (ry2 - y1)*dx )
        if dx != 0: t = (t[0]/dx, t[1]/dx)
        if dy != 0: t = (t[0]/dy, t[1]/dy)
        t = max(min(t), 0) if dx != 0 or dy != 0 else 0
        return x1 + dx*t, y1 + dy*t

    def delete_unit(self, unit):
        self.canvas.delete(unit["canvas_obj"])
        if "direction_line"