import tkinter as tk
import math
import random

# ========================
# 全局配置
# ========================
WIDTH, HEIGHT = 900, 600
FPS = 60

# ========================
# 全局变量（✅ 全部提前定义，绝不漏）
# ========================
angle = 90
power = 50
bullets = []
fishes = []
explosions = []
particles = []
items = []
bubbles = []

coins = 100
ammo = 30
score = 0
combo = 0
wave = 1
game_over = False
paused = False
difficulty = "normal"

# ========================
# Tkinter
# ========================
root = tk.Tk()
root.title("🎣 捕鱼达人 · 终极封死版")
root.resizable(False, False)

canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, highlightthickness=0)
canvas.pack()

panel = tk.Frame(root)
panel.pack(fill="x")

info = tk.Label(panel, font=("Consolas", 10))
info.pack(side="left", padx=10)

# ========================
# 主题
# ========================
themes = {
    "🌊 经典海洋": {"bg": "#0B3D91", "fg": "#FFFFFF"},
    "🌑 深海夜钓": {"bg": "#02010A", "fg": "#CCCCCC"},
    "🪸 珊瑚礁": {"bg": "#0077B6", "fg": "#FFD166"},
    "🧊 冰海": {"bg": "#CAF0F8", "fg": "#023047"},
    "🌋 熔岩海": {"bg": "#6F1A07", "fg": "#FFBA08"},
    "✨ 荧光海": {"bg": "#03045E", "fg": "#9D4EDD"},
}

def apply_theme(name):
    t = themes[name]
    root.configure(bg=t["bg"])
    panel.configure(bg=t["bg"])
    info.configure(bg=t["bg"], fg=t["fg"])
    canvas.configure(background=t["bg"])

# ========================
# 鱼类生成
# ========================
def spawn_fish():
    kinds = [
        {"name": "小鱼", "r": 8, "c": "#EF476F", "hp": 1, "spd": 3, "scr": 10, "coin": 5},
        {"name": "中鱼", "r": 12, "c": "#FFD166", "hp": 2, "spd": 2, "scr": 25, "coin": 12},
        {"name": "大鱼", "r": 18, "c": "#06D6A0", "hp": 4, "spd": 1.5, "scr": 60, "coin": 30},
        {"name": "金鱼", "r": 10, "c": "#FFD700", "hp": 1, "spd": 4, "scr": 100, "coin": 50},
        {"name": "鲨鱼", "r": 28, "c": "#118AB2", "hp": 8, "spd": 1, "scr": 200, "coin": 80},
        {"name": "Boss", "r": 40, "c": "#EF233C", "hp": 20, "spd": 0.5, "scr": 500, "coin": 200},
        {"name": "水母", "r": 14, "c": "#9D4EDD", "hp": 1, "spd": 0.8, "scr": 40, "coin": 20},
    ]
    k = random.choice(kinds)
    fishes.append({
        "x": WIDTH + random.randint(0, 200),
        "y": random.randint(100, HEIGHT - 100),
        "dx": -k["spd"] * (1 + wave * 0.1),
        "dy": random.uniform(-0.3, 0.3),
        "r": k["r"],
        "color": k["c"],
        "hp": k["hp"],
        "max_hp": k["hp"],
        "score": k["scr"],
        "coin": k["coin"],
        "name": k["name"]
    })

# ========================
# 道具生成
# ========================
def spawn_item(x, y):
    if random.random() < 0.15:
        t = random.choice(["coin", "ammo", "bomb"])
        items.append({"x": x, "y": y, "t": t, "dy": -2})

# ========================
# 海水背景
# ========================
def draw_sea():
    canvas.delete("sea")
    for y in range(HEIGHT):
        ratio = y / HEIGHT
        r = int(5 + 30 * ratio)
        g = int(30 + 80 * ratio)
        b = int(100 + 100 * ratio)
        canvas.create_line(0, y, WIDTH, y, fill=f"#{r:02x}{g:02x}{b:02x}", tags="sea")

# ========================
# 炮台
# ========================
def draw_cannon():
    canvas.delete("cannon")
    cx, cy = WIDTH // 2, HEIGHT - 60
    rad = math.radians(angle)
    ex = cx + math.cos(rad) * 50
    ey = cy - math.sin(rad) * 50

    canvas.create_oval(cx - 25, cy - 25, cx + 25, cy + 25,
                       fill="#8D775A", outline="#5C3D2E", width=3, tags="cannon")
    canvas.create_line(cx, cy, ex, ey, fill="#5C3D2E", width=10, tags="cannon")
    canvas.create_oval(ex - 6, ey - 6, ex + 6, ey + 6,
                       fill="#FFD166", outline="", tags="cannon")

# ========================
# 鱼类
# ========================
def draw_fishes():
    canvas.delete("fish")
    for f in fishes:
        canvas.create_oval(f["x"] - f["r"], f["y"] - f["r"],
                           f["x"] + f["r"], f["y"] + f["r"],
                           fill=f["color"], outline="", tags="fish")
        if f["hp"] < f["max_hp"]:
            bx = f["x"] - f["r"]
            by = f["y"] - f["r"] - 8
            bw = f["r"] * 2
            canvas.create_rectangle(bx, by, bx + bw, by + 5,
                                    outline="#FFFFFF", width=1, tags="fish")
            canvas.create_rectangle(bx, by,
                                    bx + bw * f["hp"] / f["max_hp"],
                                    by + 5, fill="#EF233C", outline="", tags="fish")

# ========================
# 子弹
# ========================
def draw_bullets():
    canvas.delete("bullet")
    for b in bullets:
        canvas.create_oval(b["x"] - 5, b["y"] - 5,
                           b["x"] + 5, b["y"] + 5,
                           fill="#FFD166", outline="", tags="bullet")
        for i in range(3):
            trail = b["x"] - b["dx"] * i * 2
            traily = b["y"] - b["dy"] * i * 2
            canvas.create_oval(trail - 2, traily - 2,
                               trail + 2, traily + 2,
                               fill="#FFD166", outline="", tags="bullet")

# ========================
# 爆炸（✅ 拼写正确）
# ========================
def draw_explosions():
    canvas.delete("explosion")
    for e in explosions[:]:
        r = e["r"] * (1 - e["life"] / 15)
        canvas.create_oval(e["x"] - r, e["y"] - r,
                           e["x"] + r, e["y"] + r,
                           fill="#FF9E00", outline="", tags="explosion")
        e["life"] -= 1
        if e["life"] <= 0:
            explosions.remove(e)

# ========================
# 粒子
# ========================
def draw_particles():
    canvas.delete("particle")
    for p in particles[:]:
        canvas.create_oval(p["x"] - 2, p["y"] - 2,
                           p["x"] + 2, p["y"] + 2,
                           fill=p["c"], outline="", tags="particle")
        p["x"] += p["dx"]
        p["y"] += p["dy"]
        p["life"] -= 1
        if p["life"] <= 0:
            particles.remove(p)

# ========================
# 道具
# ========================
def draw_items():
    canvas.delete("item")
    for it in items[:]:
        if it["t"] == "coin":
            canvas.create_oval(it["x"] - 8, it["y"] - 8,
                               it["x"] + 8, it["y"] + 8,
                               fill="#FFD700", outline="#B8860B", tags="item")
            canvas.create_text(it["x"], it["y"], text="$", fill="#8B7500", font=("", 8), tags="item")
        elif it["t"] == "ammo":
            canvas.create_rectangle(it["x"] - 8, it["y"] - 8,
                                    it["x"] + 8, it["y"] + 8,
                                    fill="#4CAF50", outline="#2E7D32", tags="item")
            canvas.create_text(it["x"], it["y"], text="+", fill="#FFFFFF", font=("", 10), tags="item")
        else:
            canvas.create_oval(it["x"] - 10, it["y"] - 10,
                               it["x"] + 10, it["y"] + 10,
                               fill="#F44336", outline="#B71C1C", tags="item")
            canvas.create_text(it["x"], it["y"], text="B", fill="#FFFFFF", font=("", 10), tags="item")
        it["y"] += it["dy"]
        if it["y"] < 0:
            items.remove(it)

# ========================
# 气泡
# ========================
def draw_bubbles():
    canvas.delete("bubble")
    while len(bubbles) < 20:
        bubbles.append([random.randint(0, WIDTH), HEIGHT + 10])
    for b in bubbles[:]:
        b[1] -= random.uniform(0.5, 1.5)
        if b[1] < 0:
            bubbles.remove(b)
        else:
            canvas.create_oval(b[0] - 4, b[1] - 4,
                               b[0] + 4, b[1] + 4,
                               fill="#CAF0F8", outline="", tags="bubble")

# ========================
# UI
# ========================
def draw_ui():
    canvas.delete("ui")
    canvas.create_text(20, 20, anchor="nw",
                       text=f"💰 {coins}  🔫 {ammo}  🏆 {score}  🔥 {combo}  🌊 {wave}",
                       fill="#FFFFFF", font=("Consolas", 12), tags="ui")
    canvas.create_text(WIDTH - 20, 20, anchor="ne",
                       text=f"角度:{angle}°  力度:{power}%",
                       fill="#FFFFFF", font=("Consolas", 12), tags="ui")

# ========================
# 更新逻辑
# ========================
def update_bullets():
    global ammo, coins, score, combo, wave, game_over

    for b in bullets[:]:
        b["x"] += b["dx"]
        b["y"] += b["dy"]
        if b["x"] < 0 or b["x"] > WIDTH or b["y"] < 0 or b["y"] > HEIGHT:
            bullets.remove(b)
            continue

        for f in fishes[:]:
            if math.hypot(b["x"] - f["x"], b["y"] - f["y"]) < f["r"] + 5:
                f["hp"] -= 1
                if f["hp"] <= 0:
                    coins += f["coin"]
                    score += int(f["score"] * (1 + combo * 0.1))
                    combo += 1
                    explosions.append({"x": f["x"], "y": f["y"], "r": f["r"], "life": 15})
                    for _ in range(10):
                        particles.append({
                            "x": f["x"], "y": f["y"],
                            "dx": random.uniform(-3, 3),
                            "dy": random.uniform(-3, 3),
                            "c": f["color"], "life": 20
                        })
                    spawn_item(f["x"], f["y"])
                    fishes.remove(f)
                if b in bullets:
                    bullets.remove(b)
                break

def update_fishes():
    global wave, game_over
    for f in fishes[:]:
        f["x"] += f["dx"]
        f["y"] += f["dy"]
        if f["x"] < -100:
            fishes.remove(f)

    if len(fishes) < 5 + wave * 2:
        spawn_fish()

    if len(fishes) == 0 and ammo <= 0 and coins < 10:
        game_over = True

def update_items():
    global coins, ammo
    for it in items[:]:
        if math.hypot(WIDTH // 2 - it["x"], HEIGHT - 60 - it["y"]) < 40:
            if it["t"] == "coin":
                coins += 20
            elif it["t"] == "ammo":
                ammo += 10
            elif it["t"] == "bomb":
                for f in fishes[:]:
                    f["hp"] -= 5
                    if f["hp"] <= 0:
                        coins += f["coin"]
                        score += f["score"]
                        explosions.append({"x": f["x"], "y": f["y"], "r": f["r"], "life": 15})
                        fishes.remove(f)
            items.remove(it)

# ========================
# 场景绘制
# ========================
def draw_scene():
    draw_sea()
    draw_bubbles()
    draw_items()
    draw_fishes()
    draw_bullets()
    draw_explosions()
    draw_particles()
    draw_cannon()
    draw_ui()

# ========================
# 游戏循环
# ========================
def game_loop():
    global paused, game_over
    if paused or game_over:
        return

    update_bullets()
    update_fishes()
    update_items()
    draw_scene()

    if game_over:
        canvas.create_text(WIDTH // 2, HEIGHT // 2,
                           text="💀 GAME OVER\n按 R 重开",
                           fill="#EF233C",
                           font=("Consolas", 28, "bold"))

    root.after(int(1000 / FPS), game_loop)

# ========================
# 控制
# ========================
def key_down(e):
    global angle, power, bullets, ammo, paused, game_over
    global coins, score, combo, wave, fishes, explosions, particles, items

    if game_over:
        if e.keysym == "r":
            game_over = False
            coins = 100
            ammo = 30
            score = combo = wave = 0
            bullets.clear()
            fishes.clear()
            explosions.clear()
            particles.clear()
            items.clear()
        return

    if e.keysym in ("a", "Left"):
        angle = min(180, angle + 5)
    if e.keysym in ("d", "Right"):
        angle = max(0, angle - 5)
    if e.keysym in ("w", "Up"):
        power = min(100, power + 5)
    if e.keysym in ("s", "Down"):
        power = max(10, power - 5)
    if e.keysym == "space":
        if ammo > 0:
            rad = math.radians(angle)
            bullets.append({
                "x": WIDTH // 2 + math.cos(rad) * 50,
                "y": HEIGHT - 60 - math.sin(rad) * 50,
                "dx": math.cos(rad) * (power / 15),
                "dy": -math.sin(rad) * (power / 15)
            })
            ammo -= 1
            for _ in range(5):
                particles.append({
                    "x": WIDTH // 2 + math.cos(rad) * 50,
                    "y": HEIGHT - 60 - math.sin(rad) * 50,
                    "dx": -math.cos(rad) * random.uniform(1, 3),
                    "dy": math.sin(rad) * random.uniform(1, 3),
                    "c": "#FFD166", "life": 10
                })
    if e.keysym == "p":
        paused = not paused
    if e.keysym == "r":
        coins = 100
        ammo = 30
        score = combo = wave = 0
        bullets.clear()
        fishes.clear()
        explosions.clear()
        particles.clear()
        items.clear()

root.bind("<KeyPress>", key_down)

# ========================
# 难度按钮
# ========================
tk.Button(panel, text="🌊 简单", command=lambda: set_difficulty("easy")).pack(side="left", padx=2)
tk.Button(panel, text="🔥 困难", command=lambda: set_difficulty("hard")).pack(side="left", padx=2)
tk.Button(panel, text="💀 噩梦", command=lambda: set_difficulty("nightmare")).pack(side="left", padx=2)

def set_difficulty(d):
    global difficulty, wave
    difficulty = d
    wave = {"easy": 1, "hard": 3, "nightmare": 5}[d]

# ========================
# 换肤按钮
# ========================
for name in themes:
    tk.Button(panel, text=name, command=lambda n=name: apply_theme(n)).pack(side="right", padx=2)

# ========================
# 启动
# ========================
apply_theme("🌊 经典海洋")
for _ in range(10):
    spawn_fish()
game_loop()
root.mainloop()