import tkinter as tk
from tkinter import messagebox, ttk
import random
import json
import os

# ==================== 配置 ====================
SAVE_FILE = "survival_save.json"

# 颜色主题
C_BG = "#1a2a3a"
C_PANEL = "#0f1d2b"
C_TEXT = "#e0e0e0"
C_ACCENT = "#4CAF50"
C_WARN = "#FF9800"
C_DANGER = "#F44336"
C_WATER = "#42A5F5"
C_HUNGER = "#FFC107"
C_HEALTH = "#EF5350"
C_ENERGY = "#AB47BC"
C_LOG_BG = "#0a1520"

# 初始物品
STARTING_ITEMS = {"木头": 0, "石头": 0, "纤维": 0, "食物": 0, "淡水": 1, "草药": 0}

# 区域配置
AREAS = {
    "🏖️ 沙滩": {
        "desc": "阳光明媚，能捡到漂流木和贝壳",
        "loot": [("木头", 40), ("石头", 25), ("纤维", 20), ("食物", 10), ("淡水", 5)],
        "danger": 0.05,
    },
    "🌴 丛林": {
        "desc": "茂密湿热，资源丰富但危险",
        "loot": [("木头", 30), ("纤维", 30), ("食物", 20), ("草药", 15), ("淡水", 5)],
        "danger": 0.2,
    },
    "⛰️ 山洞": {
        "desc": "阴暗潮湿，有石头和稀有资源",
        "loot": [("石头", 40), ("木头", 20), ("草药", 25), ("食物", 15)],
        "danger": 0.3,
    },
    "🏞️ 河流": {
        "desc": "清澈的淡水来源",
        "loot": [("淡水", 50), ("食物", 30), ("石头", 20)],
        "danger": 0.1,
    },
}

# 制作配方
RECIPES = {
    "🔨 石斧": {"木头": 2, "石头": 3, "desc": "提高探索效率，获得更多资源"},
    "🪢 绳索": {"纤维": 4, "desc": "用于建造和制作"},
    "🍳 烤肉": {"食物": 2, "木头": 1, "desc": "恢复大量饥饿"},
    "💊 药草包": {"草药": 3, "desc": "恢复生命值"},
}

# 建筑
BUILDINGS = {
    "🔥 火堆": {"木头": 5, "石头": 2, "desc": "夜晚保暖，减缓体力流失"},
    "🛖 庇护所": {"木头": 10, "纤维": 6, "绳索": 2, "desc": "安全休息，防止野兽袭击"},
    "🎣 钓鱼陷阱": {"木头": 4, "绳索": 1, "desc": "被动获得食物"},
}

# 事件
GOOD_EVENTS = [
    ("发现了一个补给箱！", {"食物": 2, "绳索": 1}),
    ("找到了一些野果", {"食物": 1}),
    ("捡到一根完好的木棍", {"木头": 2}),
    ("发现清泉", {"淡水": 2}),
]
BAD_EVENTS = [
    ("遇到了一只野猪！", "受伤"),
    ("被毒蛇咬了一口！", "受伤"),
    ("突然下起暴雨，浑身湿透", "寒冷"),
    ("踩到陷阱，脚踝受伤", "受伤"),
]


class SurvivalGame:
    def __init__(self, root):
        self.root = root
        self.root.title("🏝️ 荒岛求生")
        self.root.geometry("1000x700")
        self.root.minsize(900, 650)
        self.root.configure(bg=C_BG)

        # 游戏状态
        self.day = 1
        self.time_of_day = "☀️ 白天"
        self.health = 100
        self.hunger = 100
        self.thirst = 100
        self.energy = 100
        self.inventory = dict(STARTING_ITEMS)
        self.crafted = {}
        self.built = {}
        self.has_axe = False
        self.game_over = False

        self._build_ui()
        self._log("🚢 你的飞机坠毁在一座荒岛上...")
        self._log("🏝️ 你必须想办法活下去！")
        self._log("💡 提示：先去【沙滩】收集资源，然后制作工具和建筑。")
        self._refresh_all()

    # ==================== 界面构建 ====================
    def _build_ui(self):
        self._build_status_bar()

        main = tk.Frame(self.root, bg=C_BG)
        main.pack(fill="both", expand=True, padx=10, pady=5)

        # 左侧
        left = tk.Frame(main, bg=C_BG, width=280)
        left.pack(side="left", fill="y", padx=(0, 5))
        left.pack_propagate(False)
        self._build_stats_panel(left)
        self._build_inventory_panel(left)

        # 中间
        center = tk.Frame(main, bg=C_BG)
        center.pack(side="left", fill="both", expand=True, padx=5)
        self._build_action_panel(center)

        # 右侧
        right = tk.Frame(main, bg=C_BG, width=300)
        right.pack(side="right", fill="y", padx=(5, 0))
        right.pack_propagate(False)
        self._build_log_panel(right)

    def _build_status_bar(self):
        bar = tk.Frame(self.root, bg=C_PANEL, height=60)
        bar.pack(fill="x", padx=10, pady=(10, 0))
        bar.pack_propagate(False)

        self.day_label = tk.Label(bar, text="第 1 天 ☀️", font=("Arial", 18, "bold"),
                                  fg=C_ACCENT, bg=C_PANEL)
        self.day_label.pack(side="left", padx=20)

        self.health_bar = self._make_bar(bar, "❤️ 生命", C_HEALTH)
        self.hunger_bar = self._make_bar(bar, "🍖 饥饿", C_HUNGER)
        self.thirst_bar = self._make_bar(bar, "💧 水分", C_WATER)
        self.energy_bar = self._make_bar(bar, "⚡ 体力", C_ENERGY)

    def _make_bar(self, parent, label, color):
        frame = tk.Frame(parent, bg=C_PANEL)
        frame.pack(side="left", padx=8)
        tk.Label(frame, text=label, font=("Arial", 9), fg=C_TEXT, bg=C_PANEL).pack()
        bar = ttk.Progressbar(frame, length=100, maximum=100, value=100)
        bar.pack()
        return bar

    def _build_stats_panel(self, parent):
        f = tk.LabelFrame(parent, text="📊 生存状态", font=("Arial", 11, "bold"),
                          fg=C_ACCENT, bg=C_PANEL, labelanchor="n")
        f.pack(fill="x", pady=(0, 5))
        self.stat_labels = {}
        for name, val in [("⚔️ 攻击力", "1"), ("🔨 工具", "无"), ("🏗️ 建筑", "无")]:
            row = tk.Frame(f, bg=C_PANEL)
            row.pack(fill="x", padx=8, pady=2)
            tk.Label(row, text=name, font=("Arial", 10), fg=C_TEXT, bg=C_PANEL,
                     width=12, anchor="w").pack(side="left")
            lbl = tk.Label(row, text=val, font=("Arial", 10, "bold"), fg=C_ACCENT, bg=C_PANEL)
            lbl.pack(side="left")
            self.stat_labels[name] = lbl

    def _build_inventory_panel(self, parent):
        f = tk.LabelFrame(parent, text="🎒 背包", font=("Arial", 11, "bold"),
                          fg=C_ACCENT, bg=C_PANEL, labelanchor="n")
        f.pack(fill="both", expand=True)
        self.inv_labels = {}
        for item in STARTING_ITEMS:
            row = tk.Frame(f, bg=C_PANEL)
            row.pack(fill="x", padx=8, pady=2)
            tk.Label(row, text=item, font=("Arial", 10), fg=C_TEXT, bg=C_PANEL,
                     width=10, anchor="w").pack(side="left")
            lbl = tk.Label(row, text="0", font=("Arial", 10, "bold"), fg="white", bg=C_PANEL)
            lbl.pack(side="left")
            self.inv_labels[item] = lbl

    def _build_action_panel(self, parent):
        f = tk.LabelFrame(parent, text="🎮 行动", font=("Arial", 12, "bold"),
                          fg=C_ACCENT, bg=C_PANEL, labelanchor="n")
        f.pack(fill="both", expand=True)

        # 探索
        tk.Label(f, text="🧭 探索区域", font=("Arial", 10, "bold"),
                 fg=C_WARN, bg=C_PANEL).pack(anchor="w", padx=10, pady=(8, 2))
        self.area_btns = {}
        for area in AREAS:
            btn = tk.Button(f, text=area, font=("Arial", 11),
                            fg="white", bg="#37474F", relief="flat", cursor="hand2", height=2,
                            command=lambda a=area: self._explore(a))
            btn.pack(fill="x", padx=10, pady=2)
            self.area_btns[area] = btn

        tk.Frame(f, bg="#37474F", height=1).pack(fill="x", padx=10, pady=8)

        # 基础行动
        act_frame = tk.Frame(f, bg=C_PANEL)
        act_frame.pack(fill="x", padx=10)
        for i, (text, cmd) in enumerate([("🍖 进食", self._eat), ("💧 喝水", self._drink), ("🛏️ 休息", self._rest)]):
            btn = tk.Button(act_frame, text=text, font=("Arial", 11, "bold"),
                            fg="white", bg="#455A64", relief="flat", cursor="hand2", command=cmd)
            btn.grid(row=0, column=i, padx=3, pady=3, sticky="ew")
            act_frame.columnconfigure(i, weight=1)

        # 制作
        tk.Label(f, text="🔨 制作", font=("Arial", 10, "bold"),
                 fg=C_WARN, bg=C_PANEL).pack(anchor="w", padx=10, pady=(8, 2))
        craft_frame = tk.Frame(f, bg=C_PANEL)
        craft_frame.pack(fill="x", padx=10)
        self.craft_btns = {}
        for i, (item, recipe) in enumerate(RECIPES.items()):
            btn = tk.Button(craft_frame, text=item, font=("Arial", 9),
                            fg="white", bg="#4E342E", relief="flat", cursor="hand2",
                            command=lambda it=item: self._craft(it))
            btn.grid(row=i // 2, column=i % 2, padx=2, pady=2, sticky="ew")
            craft_frame.columnconfigure(i % 2, weight=1)
            self.craft_btns[item] = btn

        # 建造
        tk.Label(f, text="🏗️ 建造", font=("Arial", 10, "bold"),
                 fg=C_WARN, bg=C_PANEL).pack(anchor="w", padx=10, pady=(8, 2))
        build_frame = tk.Frame(f, bg=C_PANEL)
        build_frame.pack(fill="x", padx=10)
        self.build_btns = {}
        for i, (bld, cost) in enumerate(BUILDINGS.items()):
            btn = tk.Button(build_frame, text=bld, font=("Arial", 9),
                            fg="white", bg="#263238", relief="flat", cursor="hand2",
                            command=lambda b=bld: self._build(b))
            btn.grid(row=i // 2, column=i % 2, padx=2, pady=2, sticky="ew")
            build_frame.columnconfigure(i % 2, weight=1)
            self.build_btns[bld] = btn   # ✅ 修复：原来写的是 b，改为 bld

        # 底部
        bottom = tk.Frame(f, bg=C_PANEL)
        bottom.pack(fill="x", padx=10, pady=10)
        tk.Button(bottom, text="⏭️ 结束一天", font=("Arial", 11, "bold"),
                  fg="white", bg="#1565C0", relief="flat", cursor="hand2",
                  command=self._end_day).pack(side="left", padx=2, fill="x", expand=True)
        tk.Button(bottom, text="💾 存档", font=("Arial", 11),
                  fg="white", bg="#6A1B9A", relief="flat", cursor="hand2",
                  command=self._save).pack(side="left", padx=2)
        tk.Button(bottom, text="📂 读档", font=("Arial", 11),
                  fg="white", bg="#00695C", relief="flat", cursor="hand2",
                  command=self._load).pack(side="left", padx=2)

    def _build_log_panel(self, parent):
        f = tk.LabelFrame(parent, text="📜 事件日志", font=("Arial", 11, "bold"),
                          fg=C_ACCENT, bg=C_PANEL, labelanchor="n")
        f.pack(fill="both", expand=True)
        self.log_text = tk.Text(f, wrap="word", bg=C_LOG_BG, fg=C_TEXT,
                                font=("Consolas", 9), relief="flat", state="disabled", cursor="arrow")
        scroll = tk.Scrollbar(f, command=self.log_text.yview)
        self.log_text.config(yscrollcommand=scroll.set)
        self.log_text.pack(side="left", fill="both", expand=True, padx=5, pady=5)
        scroll.pack(side="right", fill="y")

    # ==================== 日志 ====================
    def _log(self, msg):
        timestamp = f"[第{self.day}天] "
        self.log_text.config(state="normal")
        self.log_text.insert("end", timestamp + msg + "\n")
        self.log_text.see("end")
        self.log_text.config(state="disabled")

    # ==================== 刷新 ====================
    def _refresh_all(self):
        self.health_bar["value"] = max(0, self.health)
        self.hunger_bar["value"] = max(0, self.hunger)
        self.thirst_bar["value"] = max(0, self.thirst)
        self.energy_bar["value"] = max(0, self.energy)
        self.day_label.config(text=f"第 {self.day} 天 {self.time_of_day}")

        for bar, val in [(self.health_bar, self.health), (self.hunger_bar, self.hunger),
                         (self.thirst_bar, self.thirst), (self.energy_bar, self.energy)]:
            if val < 25:
                bar.configure(style="Red.Horizontal.TProgressbar")
            elif val < 50:
                bar.configure(style="Orange.Horizontal.TProgressbar")
            else:
                bar.configure(style="Green.Horizontal.TProgressbar")

        for item, lbl in self.inv_labels.items():
            lbl.config(text=str(self.inventory.get(item, 0)))

        tools = ["🪓石斧"] if self.has_axe else ["无"]
        self.stat_labels["🔨 工具"].config(text=", ".join(tools))
        built_list = list(self.built.keys()) if self.built else ["无"]
        self.stat_labels["🏗️ 建筑"].config(text=", ".join(built_list)[:20])

        atk = 1 + (2 if self.has_axe else 0) + (1 if "🔥 火堆" in self.built else 0)
        self.stat_labels["⚔️ 攻击力"].config(text=str(atk))

        self._update_buttons()

    def _update_buttons(self):
        for item, recipe in RECIPES.items():
            can = all(self.inventory.get(k, 0) >= v for k, v in recipe.items() if k != "desc")
            self.craft_btns[item].config(state="normal" if can else "disabled",
                                         bg="#4E342E" if can else "#2D2419")
        for bld, cost in BUILDINGS.items():
            can = all(self.inventory.get(k, 0) >= v for k, v in cost.items() if k != "desc")
            self.build_btns[bld].config(state="normal" if can else "disabled",
                                        bg="#263238" if can else "#1A2328")

    # ==================== 游戏逻辑 ====================
    def _check_game_over(self):
        if self.game_over:
            return True
        if self.health <= 0:
            self.game_over = True
            self._log("💀 你的生命值耗尽...")
            messagebox.showinfo("游戏结束", f"💀 你没能活下来...\n坚持了 {self.day} 天。")
            return True
        if self.hunger <= 0 and self.thirst <= 0:
            self.game_over = True
            self._log("💀 饥饿和脱水同时吞噬了你...")
            messagebox.showinfo("游戏结束", f"💀 你没能活下来...\n坚持了 {self.day} 天。")
            return True
        return False

    def _survival_decay(self):
        hunger_loss = 8
        thirst_loss = 12
        energy_loss = 5
        if "🛖 庇护所" in self.built:
            hunger_loss -= 2
            energy_loss -= 2
        if "🔥 火堆" in self.built:
            energy_loss -= 1
        self.hunger -= hunger_loss
        self.thirst -= thirst_loss
        self.energy -= energy_loss
        self._log(f"📉 饥饿-{hunger_loss} 水分-{thirst_loss} 体力-{energy_loss}")

    def _explore(self, area):
        if self.game_over:
            return
        if self.energy < 5:
            self._log("😴 太累了，先休息吧！")
            self._refresh_all()
            return

        cfg = AREAS[area]
        self._log(f"🧭 前往 {area} 探索...")

        if random.random() < cfg["danger"]:
            event_text, event_type = random.choice(BAD_EVENTS)
            self._log(f"⚠️ {event_text}")
            if event_type == "受伤":
                dmg = random.randint(5, 20)
                if self.has_axe:
                    dmg = int(dmg * 0.7)
                self.health -= dmg
                self._log(f"   💥 受到 {dmg} 点伤害！")
            elif event_type == "寒冷":
                self.health -= 5
                self.energy -= 10
                self._log("   🥶 体温下降！")
        else:
            if random.random() < 0.15:
                evt_text, reward = random.choice(GOOD_EVENTS)
                self._log(f"🎉 {evt_text}")
                for k, v in reward.items():
                    self.inventory[k] = self.inventory.get(k, 0) + v
                    self._log(f"   +{v} {k}")
            else:
                loot_pool = []
                for item, weight in cfg["loot"]:
                    loot_pool.extend([item] * weight)
                multiplier = 2 if self.has_axe else 1
                for _ in range(random.randint(1, 2) * multiplier):
                    item = random.choice(loot_pool)
                    amount = random.randint(1, 2) if item in ("木头", "石头", "纤维") else 1
                    self.inventory[item] = self.inventory.get(item, 0) + amount
                    self._log(f"   📦 获得 {amount} 个 {item}")

        self.energy -= 8
        self._survival_decay()
        self._refresh_all()
        if self._check_game_over():
            return
        if self.hunger < 25:
            self._log("⚠️ 快饿坏了！")
        if self.thirst < 25:
            self._log("⚠️ 严重缺水！")

    def _eat(self):
        if self.game_over:
            return
        if self.inventory.get("食物", 0) > 0:
            self.inventory["食物"] -= 1
            self.hunger = min(100, self.hunger + 30)
            self.health = min(100, self.health + 5)
            self._log("🍖 吃掉了食物，饥饿缓解。")
        else:
            self._log("🎒 没有食物！")
        self._refresh_all()

    def _drink(self):
        if self.game_over:
            return
        if self.inventory.get("淡水", 0) > 0:
            self.inventory["淡水"] -= 1
            self.thirst = min(100, self.thirst + 40)
            self._log("💧 喝下了淡水。")
        else:
            self._log("🎒 没有淡水！去河流探索获取。")
        self._refresh_all()

    def _rest(self):
        if self.game_over:
            return
        self._log("🛏️ 休息中...")
        if "🛖 庇护所" in self.built:
            self.energy = min(100, self.energy + 50)
            self.health = min(100, self.health + 10)
            self._log("   🏠 庇护所中安全休息。")
        elif "🔥 火堆" in self.built:
            self.energy = min(100, self.energy + 35)
            self._log("   🔥 靠篝火暖和地睡了一觉。")
        else:
            self.energy = min(100, self.energy + 25)
            if random.random() < 0.3:
                self._log("   🌙 夜晚寒冷，受了点冻...")
                self.health -= 5
            else:
                self._log("   🌙 露天休息，恢复了一些体力。")

        if "🎣 钓鱼陷阱" in self.built and random.random() < 0.6:
            self.inventory["食物"] = self.inventory.get("食物", 0) + 1
            self._log("   🎣 钓鱼陷阱捕获了 1 个食物！")

        self.hunger -= 3
        self.thirst -= 5
        self._refresh_all()
        self._check_game_over()

    def _craft(self, item):
        if self.game_over:
            return
        recipe = RECIPES[item]
        for res, need in recipe.items():
            if res == "desc":
                continue
            if self.inventory.get(res, 0) < need:
                self._log(f"❌ 制作{item}需要：{recipe}")
                return
        for res, need in recipe.items():
            if res == "desc":
                continue
            self.inventory[res] -= need
        self.crafted[item] = self.crafted.get(item, 0) + 1

        if item == "🔨 石斧":
            self.has_axe = True
            self._log("🔨 制作成功！获得石斧，探索效率翻倍！")
        elif item == "🪢 绳索":
            self._log("🪢 制作成功！获得绳索 x1")
        elif item == "🍳 烤肉":
            self.hunger = min(100, self.hunger + 50)
            self._log("🍳 烤了一块肉，饥饿 +50")
        elif item == "💊 药草包":
            self.health = min(100, self.health + 40)
            self._log("💊 药草包治伤，生命 +40")
        self._refresh_all()

    def _build(self, building):
        if self.game_over:
            return
        cost = BUILDINGS[building]
        for res, need in cost.items():
            if res == "desc":
                continue
            if self.inventory.get(res, 0) < need:
                self._log(f"❌ 建造{building}需要：{cost}")
                return
        for res, need in cost.items():
            if res == "desc":
                continue
            self.inventory[res] -= need
        self.built[building] = self.built.get(building, 0) + 1
        self._log(f"🏗️ 建造完成！{building} — {cost.get('desc', '')}")
        self._refresh_all()

    def _end_day(self):
        if self.game_over:
            return
        self.day += 1

        if "🛖 庇护所" not in self.built and random.random() < 0.4:
            self._log("🌙 夜晚野兽在附近徘徊...")
            dmg = random.randint(3, 10)
            self.health -= dmg
            self._log(f"   🐺 受到野兽袭击，生命 -{dmg}")

        if "🎣 钓鱼陷阱" in self.built and random.random() < 0.5:
            self.inventory["食物"] += 1
            self._log("🎣 钓鱼陷阱捕获了食物！")

        self._log(f"🌅 第 {self.day} 天开始了！")
        self._survival_decay()
        self._refresh_all()

        if self._check_game_over():
            return
        if self.day > 30:
            self.game_over = True
            self._log("🏆 生存30天！救援直升机来了！")
            messagebox.showinfo("🎉 胜利！", "🏆 恭喜！生存30天，你获救了！")
            return
        if self.day % 10 == 0:
            self._log(f"🎯 里程碑：已坚持 {self.day} 天！")

    # ==================== 存档 ====================
    def _save(self):
        data = {
            "day": self.day, "health": self.health, "hunger": self.hunger,
            "thirst": self.thirst, "energy": self.energy,
            "inventory": self.inventory, "crafted": self.crafted,
            "built": self.built, "has_axe": self.has_axe,
        }
        try:
            with open(SAVE_FILE, "w", encoding="utf-8") as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
            self._log("💾 游戏已保存。")
        except Exception as e:
            self._log(f"❌ 保存失败：{e}")

    def _load(self):
        if not os.path.exists(SAVE_FILE):
            self._log("❌ 没有存档。")
            return
        try:
            with open(SAVE_FILE, "r", encoding="utf-8") as f:
                data = json.load(f)
            self.day = data["day"]
            self.health = data["health"]
            self.hunger = data["hunger"]
            self.thirst = data["thirst"]
            self.energy = data["energy"]
            self.inventory = data["inventory"]
            self.crafted = data.get("crafted", {})
            self.built = data.get("built", {})
            self.has_axe = data.get("has_axe", False)
            self.game_over = False
            self._log("📂 存档已加载！")
            self._refresh_all()
        except Exception as e:
            self._log(f"❌ 读取失败：{e}")


# ==================== 样式 ====================
def setup_styles(root):
    style = ttk.Style(root)
    try:
        style.theme_use("clam")
    except:
        pass
    style.configure("Horizontal.TProgressbar", background=C_ACCENT,
                    troughcolor="#1a2a3a", borderwidth=0, thickness=14)
    style.configure("Green.Horizontal.TProgressbar", background=C_ACCENT)
    style.configure("Orange.Horizontal.TProgressbar", background=C_WARN)
    style.configure("Red.Horizontal.TProgressbar", background=C_DANGER)


# ==================== 启动 ====================
if __name__ == "__main__":
    root = tk.Tk()
    setup_styles(root)
    app = SurvivalGame(root)
    root.mainloop()