# ===================== 【根号七的工具箱】 =====================

import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext, colorchooser

from PIL import ImageTk, Image, ImageDraw
import webbrowser
import sys
import os
import threading
import time
import pyautogui
from pynput import keyboard

if sys.platform == "win32":
    import win32gui
    import win32con

import datetime
import re


class ToolboxApp:
    def __init__(self, root, VERSION):
        """程序核心初始化"""
        self.root = root
        self.VERSION = VERSION
        self.root.title(f"根号七的工具箱 {self.VERSION}")
        self.root.geometry("1280x800")
        self.root.minsize(1000, 650)

        self.bg_color = "#F0F0F0"
        self.primary_color = "#1F7A48"
        self.second_color = "#E3F2EB"
        self.text_color = "#333333"
        self.root.configure(bg=self.bg_color)

        self.nav_anim_id = None
        self.nav_collapse_width = 60
        self.nav_expand_width = 240

        self.username = "默认用户"
        self.is_editing = False

        # 头像
        self.user_avatar = self.load_circle_avatar("头像.png", size=32)
        self.zan_img = None
        self.qun_img = None

        self.clicker_running = False
        self.clicker_thread = None
        self.hotkey_enabled = tk.BooleanVar(value=False)

        self.float_running = False
        self.float_hotkey_enabled = tk.BooleanVar(value=False)
        self.float_listener = None

        self.setup_window_icon()
        self.setup_global_style()
        self.setup_layout()
        self.bind_shortcuts()
        self.setup_clicker_global_hotkeys()

        self.current_module = None
        self.calc_expression = ""
        self.calc_history = []
        self.classic_images = []
        self.current_nav_btn = None

        self.float_window = None
        self.float_label = None
        self.float_x = 100
        self.float_y = 100
        self.float_font_size = 24
        self.float_color = "#ff0000"
        self.float_bg_color = "#00FF00"
        # 移除隐藏背景开关，固定一直显示背景
        self.float_border_width = 2
        self.float_alpha = tk.DoubleVar(value=100)
        self.float_refresh_id = None

        self.function0()

    # 悬浮字幕
    def parse_float_text(self, raw_text):
        now = datetime.datetime.now()
        var_map = {
            "{year}": str(now.year),
            "{month}": str(now.month),
            "{day}": str(now.day),
            "{hour}": str(now.hour),
            "{minute}": str(now.minute),
            "{second}": str(now.second)
        }
        text = raw_text
        for k, v in var_map.items():
            text = text.replace(k, v)

        math_pat = re.compile(r"\{math:(.+?)\}")

        def calc_match(m):
            expr = m.group(1)
            try:
                res = eval(expr, {"__builtins__": None}, {})
                return str(res)
            except:
                return "错误"

        text = math_pat.sub(calc_match, text)
        text = text.replace("\\n", "\n")
        return text

    def float_auto_refresh(self):
        # 修复：检查组件是否存在且有效，避免切换界面后调用已销毁的组件
        if self.float_window and self.float_label and hasattr(self, 'float_text_entry'):
            try:
                if not self.float_text_entry.winfo_exists():
                    return
                # 获取文本并更新
                raw = self.float_text_entry.get("1.0", tk.END).strip()
                real_txt = self.parse_float_text(raw)
                self.float_label.config(text=real_txt)
            except:
                return
        # 循环调用刷新
        self.float_refresh_id = self.root.after(1000, self.float_auto_refresh)

    def setup_float_global_hotkeys(self):
        def on_f10_press(key):
            try:
                if key == keyboard.Key.f10 and self.float_hotkey_enabled.get():
                    self.root.after(0, self.toggle_float)
            except:
                pass

        self.float_listener = keyboard.Listener(on_press=on_f10_press)
        self.float_listener.daemon = True
        self.float_listener.start()

    def toggle_float(self):
        if not self.float_running:
            self.show_float_text()
        else:
            self.hide_float_text()

    # 连点器快捷键
    def setup_clicker_global_hotkeys(self):
        self.hotkey_listener = None

        def on_press(key):
            if not self.hotkey_enabled.get():
                return
            try:
                if key == keyboard.Key.f9:
                    self.root.after(0, self.toggle_clicker)
            except:
                pass

        try:
            self.hotkey_listener = keyboard.Listener(on_press=on_press, daemon=True)
            self.hotkey_listener.start()
        except:
            pass

    def toggle_clicker(self):
        if self.clicker_running:
            self.stop_clicker()
        else:
            self.start_clicker()

    def get_pressed(self):
        try:
            return keyboard.Controller().pressed_keys
        except:
            return set()

    def start_clicker(self):
        if self.clicker_running:
            return
        try:
            interval = float(self.click_interval.get()) / 1000
            count = int(self.click_times.get())
            btn_text = self.click_btn.get()
            mode = self.click_mode.get()
            if btn_text == "左键":
                btn = "left"
            else:
                btn = "right"

        except:
            messagebox.showwarning("提示", "请输入有效数字")
            return

        self.clicker_running = True
        self.click_status.config(text="状态：运行中", fg="#e53e3e")

        def task():
            n = 0
            while self.clicker_running:
                if mode == "单击":
                    pyautogui.click(button=btn)
                else:
                    pyautogui.doubleClick(button=btn)
                n += 1
                if count != -1 and n >= count:
                    break
                time.sleep(interval)
            self.clicker_running = False
            self.root.after(0, lambda: self.click_status.config(text="状态：已停止", fg=self.text_color))

        self.clicker_thread = threading.Thread(target=task, daemon=True)
        self.clicker_thread.start()

    def stop_clicker(self):
        self.clicker_running = False
        self.click_status.config(text="状态：已停止", fg=self.text_color)

    def function3(self):
        self.clear_main_frame()
        self.current_module = "clicker"

        tk.Label(self.main_frame, text="🖱️ 连点器", font=("微软雅黑", 22, "bold"),
                 bg=self.bg_color, fg=self.primary_color).pack(pady=(10, 20), anchor="w")

        frame = tk.Frame(self.main_frame, bg="white", bd=2, relief=tk.RIDGE)
        frame.pack(fill=tk.X, padx=0, pady=5)
        inner = tk.Frame(frame, bg="white")
        inner.pack(padx=20, pady=18)

        tk.Label(inner, text="点击间隔(ms)：", bg="white", font=("微软雅黑", 12)).grid(row=0, column=0, sticky="w",
                                                                                      padx=5)
        self.click_interval = tk.Entry(inner, font=("微软雅黑", 12), width=8)
        self.click_interval.grid(row=0, column=1, padx=5)
        self.click_interval.insert(0, "100")

        tk.Label(inner, text="点击次数(-1无限)：", bg="white", font=("微软雅黑", 12)).grid(row=0, column=2, sticky="w",
                                                                                          padx=5)
        self.click_times = tk.Entry(inner, font=("微软雅黑", 12), width=8)
        self.click_times.grid(row=0, column=3, padx=5)
        self.click_times.insert(0, "-1")

        tk.Label(inner, text="鼠标按键：", bg="white", font=("微软雅黑", 12)).grid(row=1, column=0, sticky="w", pady=12)
        self.click_btn = tk.StringVar(value="左键")
        ttk.Combobox(inner, textvariable=self.click_btn, values=["左键", "右键"], state="readonly", width=7).grid(
            row=1, column=1)

        tk.Label(inner, text="点击模式：", bg="white", font=("微软雅黑", 12)).grid(row=1, column=2, sticky="w")
        self.click_mode = tk.StringVar(value="单击")
        ttk.Combobox(inner, textvariable=self.click_mode, values=["单击", "双击"], state="readonly", width=7).grid(
            row=1, column=3)

        btn_frame = tk.Frame(self.main_frame, bg=self.bg_color)
        btn_frame.pack(pady=12)

        start_btn = tk.Button(btn_frame, text="▶ 启动连点", font=("微软雅黑", 12, "bold"),
                              bg=self.primary_color, fg="white", relief=tk.FLAT,
                              activebackground="#186439", activeforeground="white",
                              padx=18, pady=6, command=self.start_clicker)
        start_btn.grid(row=0, column=0, padx=8)

        stop_btn = tk.Button(btn_frame, text="⏹ 停止连点", font=("微软雅黑", 12, "bold"),
                             bg="#dc2626", fg="white", relief=tk.FLAT,
                             activebackground="#b91c1c", activeforeground="white",
                             padx=18, pady=6, command=self.stop_clicker)
        stop_btn.grid(row=0, column=1, padx=8)

        self.click_status = tk.Label(self.main_frame, text="状态：已停止", font=("微软雅黑", 13),
                                     bg=self.bg_color, fg=self.text_color)
        self.click_status.pack(pady=4)

        hk_frame = tk.Frame(self.main_frame, bg=self.bg_color)
        hk_frame.pack(pady=4)
        tk.Label(hk_frame, text="快捷键：F9 切换启动/停止",
                 font=("微软雅黑", 12), bg=self.bg_color).pack(side=tk.LEFT)
        tk.Checkbutton(hk_frame, text="启用快捷键", variable=self.hotkey_enabled,
                       bg=self.bg_color, font=("微软雅黑", 11)).pack(side=tk.LEFT, padx=8)

    # 头像加载
    def load_circle_avatar(self, img_path, size=32):
        try:
            img = Image.open(img_path).convert("RGBA")
            img = img.resize((size, size), Image.LANCZOS)
            mask = Image.new("L", (size, size), 0)
            draw = ImageDraw.Draw(mask)
            draw.ellipse((0, 0, size, size), fill=255)
            circle_img = Image.new("RGBA", (size, size), (255, 255, 255, 0))
            circle_img.paste(img, (0, 0), mask=mask)
            print(f'图片 "{img_path}" 加载完成')
            return ImageTk.PhotoImage(circle_img)
        except Exception:
            print(f'图片 "{img_path}" 加载失败，未能找到该文件')
            return self.create_default_avatar(size)

    def create_default_avatar(self, size=32):
        img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
        draw = ImageDraw.Draw(img)
        draw.ellipse((0, 0, size, size), fill="#CCCCCC")
        draw.ellipse((size * 0.25, size * 0.15, size * 0.75, size * 0.45), fill="#AAAAAA")
        draw.rectangle((size * 0.2, size * 0.5, size * 0.8, size * 0.9), fill="#AAAAAA")
        return ImageTk.PhotoImage(img)

    def setup_window_icon(self):
        try:
            icon_path = "图标4.ico"  # 应用图片，可选1-4
            if os.path.exists(icon_path):
                self.root.iconbitmap(icon_path)
        except Exception:
            pass

    def setup_global_style(self):
        self.style = ttk.Style()
        self.style.theme_use("clam")
        self.style.configure("Primary.TButton", font=("微软雅黑", 10, "bold"), background=self.primary_color,
                             foreground="white", padding=12)
        self.style.map("Primary.TButton", background=[('active', "#186439")])
        self.style.configure("Nav.TButton", font=("微软雅黑", 11), background="white", foreground=self.text_color,
                             padding=12, borderwidth=0)
        self.style.map("Nav.TButton", background=[('active', self.second_color), ('pressed', self.second_color)])
        self.style.configure("Selected.Nav.TButton", font=("微软雅黑", 11, "bold"), background="#E3F2EB",
                             foreground=self.text_color, padding=12, borderwidth=0, relief=tk.FLAT)
        self.style.map("Selected.Nav.TButton", background=[('active', "#C8E6D8")])
        self.style.configure("NavSmall.TButton", font=("微软雅黑", 9), background=self.primary_color,
                             foreground="white", padding=(3, 2))
        self.style.map("NavSmall.TButton", background=[('active', "#186439")])

    def clear_main_frame(self):
        try:
            self.root.unbind("<Key>")
        except:
            pass
        self.classic_images = []
        for widget in self.main_frame.winfo_children():
            widget.destroy()

    def bind_shortcuts(self):
        self.root.bind("<F11>", self.toggle_fullscreen)
        self.root.bind("<Escape>", self.exit_fullscreen)
        self.root.bind("<Control-q>", self.quit_app)

    def toggle_fullscreen(self, event=None):
        is_full = self.root.attributes("-fullscreen")
        self.root.attributes("-fullscreen", not is_full)

    def exit_fullscreen(self, event=None):
        self.root.attributes("-fullscreen", False)

    def quit_app(self, event=None):
        if messagebox.askokcancel("退出确认", "确定要退出工具箱吗？"):
            self.root.destroy()
            sys.exit(0)

    def animate_expand(self):
        w = self.nav_frame.winfo_width()
        if w < self.nav_expand_width:
            self.nav_frame.config(width=w + 4)
            self.nav_anim_id = self.root.after(18, self.animate_expand)

    def animate_collapse(self):
        w = self.nav_frame.winfo_width()
        if w > self.nav_collapse_width:
            self.nav_frame.config(width=w - 4)
            self.nav_anim_id = self.root.after(18, self.animate_collapse)

    def set_selected_nav(self, selected_btn):
        for btn, _, _ in self.nav_buttons:
            btn.config(style="Nav.TButton")
        selected_btn.config(style="Selected.Nav.TButton")
        self.current_nav_btn = selected_btn

    # 工具栏
    def setup_layout(self):
        self.header_frame = tk.Frame(self.root, bg=self.primary_color, height=60)
        self.header_frame.pack(fill=tk.X, side=tk.TOP)
        self.header_frame.pack_propagate(False)
        tk.Label(self.header_frame, text="🌵 根号七的工具箱", font=("微软雅黑", 18, "bold"), bg=self.primary_color,
                 fg="white").pack(side=tk.LEFT, padx=20, pady=12)

        self.nav_frame = tk.Frame(self.root, bg="white")
        self.nav_frame.pack(fill=tk.Y, side=tk.LEFT)
        self.nav_frame.pack_propagate(False)
        self.nav_frame.config(width=self.nav_collapse_width)

        def check_mouse_pos():
            try:
                mx, my = self.root.winfo_pointerxy()
                nx1 = self.nav_frame.winfo_rootx()
                nx2 = nx1 + self.nav_frame.winfo_width()
                ny1 = self.nav_frame.winfo_rooty()
                ny2 = ny1 + self.nav_frame.winfo_height()
                if nx1 <= mx <= nx2 and ny1 <= my <= ny2:
                    if self.nav_anim_id:
                        self.root.after_cancel(self.nav_anim_id)
                    self.animate_expand()
                else:
                    if self.nav_anim_id:
                        self.root.after_cancel(self.nav_anim_id)
                    self.animate_collapse()
            except:
                pass
            self.root.after(30, check_mouse_pos)

        check_mouse_pos()

        # 工具/功能
        self.nav_buttons = []
        nav_config = [
            ("🏠", "🏠 首页", self.function0),
            ("🧭", "🧭 网址导航", self.function1),
            ("🧮", "🧮 计算器", self.function2),
            ("🖱", "🖱 鼠标指针辅助器", self.function3),
            ("📝", "📝 自定义漂浮字幕", self.function4),
            ("💖", "💖 支持根号七", self.function888)
        ]
        for icon, text, cmd in nav_config:
            btn = ttk.Button(self.nav_frame, text=icon, style="Nav.TButton")
            btn.config(command=lambda b=btn, c=cmd: (self.set_selected_nav(b), c()))
            btn.pack(fill=tk.X, pady=4, padx=8)
            self.nav_buttons.append((btn, icon, text))

        # ====================== 用户信息（可修改昵称） ======================
        bottom_frame = tk.Frame(self.nav_frame, bg="white")
        bottom_frame.pack(side=tk.BOTTOM, fill=tk.X, padx=0, pady=0)

        tk.Label(bottom_frame, text="——用户信息——————————", font=("微软雅黑", 10, "bold"),
                 bg="white", fg="#666666").pack(anchor=tk.W, padx=12, pady=(0, 2))

        # 提示标签（错误提示）
        self.tip_frame = None
        self.tip_label = None

        # 头像 + 名字行
        user_row = tk.Frame(bottom_frame, bg="white")
        user_row.pack(anchor=tk.W, padx=8, pady=(0, 10))
        tk.Label(user_row, image=self.user_avatar, bg="white").pack(side=tk.LEFT, padx=4)

        self.name_label = tk.Label(user_row, text=self.username, font=("微软雅黑", 11), bg="white", cursor="hand2")
        self.name_label.pack(side=tk.LEFT)
        self.name_label.bind("<Button-1>", lambda e: self.start_edit_name())

        # 编辑框、按钮（默认隐藏）
        self.name_edit_var = tk.StringVar(value=self.username)
        self.name_entry = None
        self.confirm_btn = None
        self.cancel_btn = None

        def update_btn_text():
            w = self.nav_frame.winfo_width()
            for btn, ico, txt in self.nav_buttons:
                btn.config(text=txt if w > 180 else ico)
            self.root.after(50, update_btn_text)

        update_btn_text()
        self.set_selected_nav(self.nav_buttons[0][0])

        self.footer_frame = tk.Frame(self.root, bg="#DCDCDC", height=24)
        self.footer_frame.pack(fill=tk.X, side=tk.BOTTOM)
        self.footer_frame.pack_propagate(False)
        tk.Label(self.footer_frame, text=self.VERSION, font=("微软雅黑", 9), bg="#DCDCDC", fg="black", padx=15).pack(
            side=tk.RIGHT)

        self.right_container = tk.Frame(self.root, bg=self.bg_color)
        self.right_container.pack(fill=tk.BOTH, expand=True, side=tk.RIGHT)
        self.main_frame = tk.Frame(self.right_container, bg=self.bg_color)
        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

    # ====================== 昵称修改逻辑 ======================
    def start_edit_name(self):
        if self.is_editing:
            return
        self.is_editing = True
        self.name_label.pack_forget()

        self.name_edit_var.set(self.username)
        self.name_entry = tk.Entry(
            self.name_label.master, textvariable=self.name_edit_var,
            font=("微软雅黑", 11), width=8, bg="#f8f8f8"
        )
        self.name_entry.pack(side=tk.LEFT, padx=(2, 4))
        self.name_entry.focus()

        # 确定按钮（蓝底白字 圆角）
        self.confirm_btn = tk.Button(
            self.name_label.master, text="确定",
            font=("微软雅黑", 9), bg="#3a7aff", fg="white",
            relief=tk.FLAT, padx=6, pady=1,
            command=self.confirm_edit_name
        )
        # 取消按钮（白底黑字 灰边）
        self.cancel_btn = tk.Button(
            self.name_label.master, text="取消",
            font=("微软雅黑", 9), bg="white", fg="#333",
            relief=tk.FLAT, padx=6, pady=1,
            command=self.cancel_edit_name
        )
        self.confirm_btn.pack(side=tk.LEFT, padx=2)
        self.cancel_btn.pack(side=tk.LEFT, padx=2)

        # 绑定回车确定
        self.name_entry.bind("<Return>", lambda e: self.confirm_edit_name())
        self.name_entry.bind("<Escape>", lambda e: self.cancel_edit_name())

    def cancel_edit_name(self):
        self.hide_tip()
        self.is_editing = False
        self.name_entry.destroy()
        self.confirm_btn.destroy()
        self.cancel_btn.destroy()
        self.name_label.pack(side=tk.LEFT)

    def confirm_edit_name(self):
        new_name = self.name_edit_var.get().strip()
        # 长度限制
        if len(new_name) == 0 or len(new_name) > 8:
            self.show_tip("长度必须 1~8 位")
            return
        # 规则：汉字、英文、. - _
        if not re.fullmatch(r'^[\u4e00-\u9fa5a-zA-Z0-9\.\-_]+$', new_name):
            self.show_tip("仅支持中文、英文、小数点、划线 和 下划线")
            return

        self.hide_tip()
        self.username = new_name
        self.name_label.config(text=new_name)
        self.cancel_edit_name()

    def show_tip(self, msg):
        self.hide_tip()
        self.tip_label = tk.Label(
            self.nav_frame, text=msg, font=("微软雅黑", 9),
            bg="#ffebee", fg="#d32f2f", padx=6, pady=2
        )
        self.tip_label.place(relx=0.05, rely=0.82)

    def hide_tip(self):
        if self.tip_label:
            self.tip_label.destroy()
            self.tip_label = None

    # ====================== 功能模块 ======================
    def function0(self):
        self.clear_main_frame()
        self.current_module = "home"
        tk.Label(self.main_frame, text="欢迎使用 根号七的工具箱", font=("微软雅黑", 24, "bold"), bg=self.bg_color,
                 fg=self.primary_color).pack(pady=40)
        tk.Label(self.main_frame, text="左侧工具栏可选择对应工具", font=("微软雅黑", 14), bg=self.bg_color,
                 fg=self.text_color).pack(pady=10)
        tk.Label(self.main_frame, text="F11切换全屏 | Esc退出全屏 | Ctrl+Q退出程序", font=("微软雅黑", 12),
                 bg=self.bg_color, fg=self.text_color).pack(pady=20)
        notice_frame = tk.Frame(self.main_frame, bg="white", bd=2, relief=tk.RIDGE)
        notice_frame.pack(fill=tk.X, padx=100, pady=20)
        tk.Label(notice_frame, text="新增&修复 功能", font=("微软雅黑", 14, "bold"), bg="white").pack(pady=(15, 10),
                                                                                                      anchor="w",
                                                                                                      padx=20)
        tk.Label(notice_frame,
                 text=("1." + "新增 连点器、漂浮字幕 功能" + "\n"
                       "2." + "修复了无法使用快捷键的问题" + "\n"
                       "3." + "这个字幕实在太难搞了,想要穿透其点到下面的东西就无法显示字幕，想要透明背景就自动变成白色或黑色填充，我放弃了。"),
                 font=("微软雅黑", 11), bg="white", fg=self.text_color, justify="left").pack(pady=(0, 15), anchor="w",
                                                                                             padx=20)

    def function1(self):
        self.clear_main_frame()
        self.current_module = "nav"
        tk.Label(self.main_frame, text="🧭 网址导航", font=("微软雅黑", 22, "bold"), bg=self.bg_color,
                 fg=self.primary_color).pack(pady=(10, 5), anchor="w")
        tk.Label(self.main_frame, text="网址为作者推荐", font=("微软雅黑", 10), bg=self.bg_color, fg="#9CA3AF").pack(
            pady=(0, 20), anchor="w")

        # 搜索栏区域
        search_frame = tk.Frame(self.main_frame, bg=self.bg_color)
        search_frame.pack(fill=tk.X, pady=10)

        # 搜索引擎下拉框（能改高度！不挤布局！）
        search_engine = tk.StringVar(value="百度")
        engine_combobox = ttk.Combobox(
            search_frame,
            textvariable=search_engine,
            values=["百度", "必应", "搜狗", "哔哩哔哩 搜视频"],
            state="readonly",
            width=10,
            font=("微软雅黑", 24)  #下拉框高度
        )
        engine_combobox.pack(side=tk.LEFT, padx=5)

        # 搜索按钮（先放！保证不被顶出去）
        def search():
            query = self.search_entry.get().strip()
            if not query or query == "输入搜索内容":
                messagebox.showwarning("提示", "请输入搜索内容")
                return
            engine = search_engine.get()
            if engine == "百度":
                url = f"https://www.baidu.com/s?wd={query}"
            elif engine == "必应":
                url = f"https://cn.bing.com/search?q={query}"
            elif engine == "搜狗":
                url = f"https://www.sogou.com/web?query={query}"
            elif engine == "哔哩哔哩 搜视频":
                url = f"https://search.bilibili.com/all?keyword={query}"
            webbrowser.open_new_tab(url)

        search_btn = tk.Button(search_frame, text="搜索", font=("微软雅黑", 15, "bold"),
                               bg=self.primary_color, fg="white", relief=tk.FLAT, command=search)
        search_btn.pack(side=tk.RIGHT, padx=5)

        # 搜索输入框（自动占满剩余空间，永远不挤按钮）
        self.search_entry = tk.Entry(search_frame, font=("微软雅黑", 24))
        self.search_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True, ipady=2)
        self.search_entry.insert(0, "输入搜索内容")

        # 回车搜索
        self.search_entry.bind("<Return>", lambda e: search())

        website_list = [
            ("哔哩哔哩", "https://www.bilibili.com"),
            ("抖音", "https://www.douyin.com"),
            ("豆包", "https://www.doubao.com"),
            ("Deepseek", "https://www.deepseek.com"),
            ("CCTV", "https://www.cctv.com"),
            ("MBTI测试","https://www.jyshare.com/front-end/10312/"),
            ("B站关注", "https://space.bilibili.com/3493288684292639")
        ]
        btn_container = tk.Frame(self.main_frame, bg=self.bg_color)
        btn_container.pack(fill=tk.BOTH, expand=True)

        def open_website(site_name, site_url):
            if messagebox.askyesno("导航提示", f"是否打开【{site_name}】官网？"):
                try:
                    webbrowser.open_new_tab(site_url)
                except Exception as e:
                    messagebox.showerror("跳转失败", f"打开网站失败：{str(e)}")

        col_count = 7
        btn_width = 16
        btn_height = 0
        font_name = "微软雅黑"
        font_size = 14

        for index, (site_name, site_url) in enumerate(website_list):
            row = index // col_count
            col = index % col_count
            nav_btn = tk.Button(
                btn_container,
                text=site_name,
                command=lambda name=site_name, url=site_url: open_website(name, url),
                width=btn_width,
                height=btn_height,
                font=(font_name, font_size),
                bg=self.primary_color,
                fg="white",
                relief=tk.FLAT,
                cursor="hand2"
            )
            nav_btn.grid(row=row, column=col, padx=6, pady=6, sticky="nsew")

        for col in range(col_count):
            btn_container.grid_columnconfigure(col, weight=1)

    def function2(self):
        self.clear_main_frame()
        self.current_module = "calculator"
        self.calc_expression = ""
        main_container = tk.Frame(self.main_frame, bg=self.bg_color)
        main_container.pack(fill=tk.BOTH, expand=True)
        calc_frame = tk.Frame(main_container, bg=self.bg_color)
        calc_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 15))
        tk.Label(calc_frame, text="🧮 计算器", font=("微软雅黑", 20, "bold"), bg=self.bg_color,
                 fg=self.primary_color).pack(pady=(0, 20), anchor="w")
        self.calc_display = tk.Entry(calc_frame, font=("微软雅黑", 24), justify="right", bd=10, bg="white",
                                     relief=tk.FLAT)
        self.calc_display.pack(fill=tk.X, pady=10, ipady=15)
        btn_frame = tk.Frame(calc_frame, bg=self.bg_color)
        btn_frame.pack(fill=tk.BOTH, expand=True, pady=10)
        calc_buttons = [
            ("C", 0, 0, "#EF4444", "white"), ("←", 0, 1, "#F59E0B", "white"), ("%", 0, 2, "#F59E0B", "white"),
            ("÷", 0, 3, "#F59E0B", "white"),
            ("7", 1, 0, "white", self.text_color), ("8", 1, 1, "white", self.text_color),
            ("9", 1, 2, "white", self.text_color), ("×", 1, 3, "#F59E0B", "white"),
            ("4", 2, 0, "white", self.text_color), ("5", 2, 1, "white", self.text_color),
            ("6", 2, 2, "white", self.text_color), ("-", 2, 3, "#F59E0B", "white"),
            ("1", 3, 0, "white", self.text_color), ("2", 3, 1, "white", self.text_color),
            ("3", 3, 2, "white", self.text_color), ("+", 3, 3, "#F59E0B", "white"),
            ("00", 4, 0, "white", self.text_color), ("0", 4, 1, "white", self.text_color),
            (".", 4, 2, "white", self.text_color), ("=", 4, 3, self.primary_color, "white"),
        ]

        def is_valid_expression(exp):
            if not exp: return False
            if exp[0] in "+×÷%." or exp[-1] in "+-×÷%.": return False
            invalid_list = ["++", "+-", "+×", "+÷", "-+", "--", "-×", "-÷", "×+", "×-", "××", "×÷", "÷+", "÷-", "÷×",
                            "÷÷", ".."]
            for item in invalid_list:
                if item in exp: return False
            return True

        def calc_btn_click(value):
            if value == "C":
                self.calc_expression = ""
                self.calc_display.delete(0, tk.END)
            elif value == "←":
                self.calc_expression = self.calc_expression[:-1]
                self.calc_display.delete(0, tk.END)
                self.calc_display.insert(tk.END, self.calc_expression)
            elif value == "=":
                calc_result()
            else:
                self.calc_expression += value
                self.calc_display.delete(0, tk.END)
                self.calc_display.insert(tk.END, self.calc_expression)

        def calc_result():
            if not is_valid_expression(self.calc_expression):
                self.calc_display.delete(0, tk.END)
                self.calc_display.insert(tk.END, "表达式错误")
                self.calc_expression = ""
                return
            try:
                expression = self.calc_expression.replace("×", "*").replace("÷", "/")
                result = eval(expression)
                if isinstance(result, float) and result.is_integer():
                    result = int(result)
                self.calc_history.append(f"{self.calc_expression} = {result}")
                update_history_display()
                self.calc_display.delete(0, tk.END)
                self.calc_display.insert(tk.END, str(result))
                self.calc_expression = str(result)
            except ZeroDivisionError:
                self.calc_display.delete(0, tk.END)
                self.calc_display.insert(tk.END, "除数不能为0")
                self.calc_expression = ""
            except Exception:
                self.calc_display.delete(0, tk.END)
                self.calc_display.insert(tk.END, "表达式错误")
                self.calc_expression = ""

        def calc_keyboard_input(event):
            key = event.keysym
            if key in "0123456789":
                self.calc_expression += key
            elif key in ["period", "KP_Decimal"]:
                self.calc_expression += "."
            elif key in ["plus", "KP_Add"]:
                self.calc_expression += "+"
            elif key in ["minus", "KP_Subtract"]:
                self.calc_expression += "-"
            elif key in ["asterisk", "KP_Multiply"]:
                self.calc_expression += "×"
            elif key in ["slash", "KP_Division"]:
                self.calc_expression += "÷"
            elif key == "Return":
                calc_result()
            elif key == "BackSpace":
                self.calc_expression = self.calc_expression[:-1]
            elif key == "Delete":
                self.calc_expression = ""
            self.calc_display.delete(0, tk.END)
            self.calc_display.insert(tk.END, self.calc_expression)

        self.root.bind("<Key>", calc_keyboard_input)
        for text, row, col, bg, fg in calc_buttons:
            btn = tk.Button(btn_frame, text=text, font=("微软雅黑", 14, "bold"), bg=bg, fg=fg, bd=0, relief=tk.FLAT,
                            command=lambda t=text: calc_btn_click(t))
            btn.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
        for i in range(5): btn_frame.grid_rowconfigure(i, weight=1)
        for i in range(4): btn_frame.grid_columnconfigure(i, weight=1)
        history_frame = tk.Frame(main_container, bg="white", bd=2, relief=tk.RIDGE, width=280)
        history_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=False, padx=(15, 0))
        history_frame.pack_propagate(False)
        tk.Label(history_frame, text="📝 计算历史记录", font=("微软雅黑", 12, "bold"), bg="white").pack(pady=10)
        self.history_display = scrolledtext.ScrolledText(history_frame, font=("微软雅黑", 10), wrap=tk.WORD,
                                                         bg="#F8FAFC", state=tk.DISABLED)
        self.history_display.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        def clear_calc_history():
            self.calc_history = []
            update_history_display()

        ttk.Button(history_frame, text="清空历史记录", command=clear_calc_history, style="Primary.TButton").pack(
            pady=10, padx=10, fill=tk.X)

        def update_history_display():
            self.history_display.config(state=tk.NORMAL)
            self.history_display.delete(1.0, tk.END)
            for item in reversed(self.calc_history):
                self.history_display.insert(tk.END, f"▶ {item}\n\n")
            self.history_display.config(state=tk.DISABLED)

        update_history_display()

    def function4(self):
        self.clear_main_frame()
        self.current_module = "float_text"

        tk.Label(self.main_frame, text="📝 自定义漂浮字幕", font=("微软雅黑", 22, "bold"),
                 bg=self.bg_color, fg=self.primary_color).pack(pady=(10, 20), anchor="w")

        main_panel = tk.Frame(self.main_frame, bg=self.bg_color)
        main_panel.pack(fill=tk.BOTH, expand=True, padx=0, pady=5)

        frame = tk.Frame(main_panel, bg="white", bd=2, relief=tk.RIDGE)
        frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=0, pady=0)
        inner = tk.Frame(frame, bg="white")
        inner.pack(padx=20, pady=18, fill=tk.X)

        tk.Label(inner, text="字幕内容：", bg="white", font=("微软雅黑", 12)).grid(row=0, column=0, sticky="w", padx=5,
                                                                                  pady=5)
        self.float_text_entry = tk.Text(inner, font=("微软雅黑", 12), width=30, height=3, wrap=tk.WORD)
        self.float_text_entry.grid(row=0, column=1, columnspan=3, padx=5, pady=5, sticky="ew")
        self.float_text_entry.insert("1.0", "点击修改漂浮字幕")

        tk.Label(inner, text="横向坐标：", bg="white", font=("微软雅黑", 12)).grid(row=1, column=0, sticky="w", padx=5,
                                                                                  pady=5)
        self.float_x_entry = tk.Entry(inner, font=("微软雅黑", 12), width=10)
        self.float_x_entry.grid(row=1, column=1, padx=5, pady=5)
        self.float_x_entry.insert(0, "100")

        tk.Label(inner, text="纵向坐标：", bg="white", font=("微软雅黑", 12)).grid(row=1, column=2, sticky="w", padx=5,
                                                                                  pady=5)
        self.float_y_entry = tk.Entry(inner, font=("微软雅黑", 12), width=10)
        self.float_y_entry.grid(row=1, column=3, padx=5, pady=5)
        self.float_y_entry.insert(0, "100")

        tk.Label(inner, text="文本大小：", bg="white", font=("微软雅黑", 12)).grid(row=2, column=0, sticky="w", padx=5,
                                                                                  pady=5)
        self.float_size_entry = tk.Entry(inner, font=("微软雅黑", 12), width=10)
        self.float_size_entry.grid(row=2, column=1, padx=5, pady=5)
        self.float_size_entry.insert(0, "24")

        tk.Label(inner, text="文本字体：", bg="white", font=("微软雅黑", 12)).grid(row=3, column=0, sticky="w", padx=5,
                                                                                  pady=5)
        self.float_font_entry = tk.Entry(inner, font=("微软雅黑", 12), width=10)
        self.float_font_entry.grid(row=3, column=1, padx=5, pady=5)
        self.float_font_entry.insert(0, "微软雅黑")

        tk.Label(inner, text="文本颜色：", bg="white", font=("微软雅黑", 12)).grid(row=4, column=0, sticky="w", padx=5,
                                                                                  pady=5)
        self.color_btn = tk.Button(inner, text="选择颜色", command=self.choose_float_color, bg="#ff0000", fg="white",
                                   font=("微软雅黑", 10))
        self.color_btn.grid(row=4, column=1, padx=5, pady=5)

        tk.Label(inner, text="背景颜色：", bg="white", font=("微软雅黑", 12)).grid(row=5, column=0, sticky="w", padx=5,
                                                                                  pady=5)
        self.bg_color_btn = tk.Button(inner, text="选择颜色", command=self.choose_float_bg_color, bg="#00FF00",
                                      fg="white", font=("微软雅黑", 10))
        self.bg_color_btn.grid(row=5, column=1, padx=5, pady=5)

        tk.Label(inner, text="透明度：", bg="white", font=("微软雅黑", 12)).grid(row=6, column=0, sticky="w", padx=5,
                                                                                pady=5)
        self.alpha_scale = tk.Scale(inner, from_=1, to=100, variable=self.float_alpha, orient=tk.HORIZONTAL, bg="white")
        self.alpha_scale.grid(row=6, column=1, columnspan=3, sticky="ew", padx=5, pady=5)
        self.alpha_scale.set(100)

        help_frame = tk.Frame(main_panel, bg="white", bd=2, relief=tk.RIDGE)
        help_frame.pack(side=tk.RIGHT, padx=(10, 0), fill=tk.Y)

        # 文本预设
        tk.Label(inner, text="预设：", bg="white", font=("微软雅黑", 12)).grid(row=7, column=0, sticky="w", padx=5,
                                                                              pady=8)
        # 当前时间
        def preset1():
            self.float_text_entry.delete("1.0", tk.END)
            self.float_text_entry.insert("1.0", "现在时间：{year}年{month}月{day}日 {hour}:{minute}:{second}")

        # ？
        def preset2():
            self.float_text_entry.delete("1.0", tk.END)
            self.float_text_entry.insert("1.0", "默认文本")

        ttk.Button(inner, text="当前时间", command=preset1).grid(row=7, column=1, padx=3, pady=8)
        ttk.Button(inner, text="暂无更多", command=preset2).grid(row=7, column=2, padx=3, pady=8)

        tk.Label(help_frame, text="📌 变量使用说明", font=("微软雅黑", 14, "bold"), bg="white").pack(pady=(15, 10),
                                                                                                    padx=15)

        help_text = """输入以下内容可自动显示：

{year}   →  当前年份
{month}  →  当前月份
{day}   →  今日日期
{hour}   →  当前小时
{minute} →  当前分钟
{second} →  当前秒数

\\n → 换行

{math:表达式} → 计算结果
(目前支持：加 + ，减 - ，乘 * ，除 / ，取余 %)

例：
今天是{year}年{month}月{day}日
距离凌晨已经过去了
{math:{hour}*60*60+{minute}*60+{second}}秒"""

        tk.Label(help_frame, text=help_text, justify=tk.LEFT, font=("微软雅黑", 11), bg="white", fg="#333333").pack(
            anchor="w", padx=15, pady=5)

        btn_frame = tk.Frame(self.main_frame, bg=self.bg_color)
        btn_frame.pack(pady=12)
        tk.Button(btn_frame, text="💬 显示字幕", font=("微软雅黑", 12, "bold"),
                  bg=self.primary_color, fg="white", relief=tk.FLAT, padx=18, pady=6,
                  command=self.show_float_text).grid(row=0, column=0, padx=8)

        tk.Button(btn_frame, text="❌ 隐藏字幕", font=("微软雅黑", 12, "bold"),
                  bg="#dc2626", fg="white", relief=tk.FLAT, padx=18, pady=6,
                  command=self.hide_float_text).grid(row=0, column=1, padx=8)

        self.float_status = tk.Label(self.main_frame, text="状态：已停止", font=("微软雅黑", 13),
                                     bg=self.bg_color, fg=self.text_color)
        self.float_status.pack(pady=4)

        float_hk_frame = tk.Frame(self.main_frame, bg=self.bg_color)
        float_hk_frame.pack(pady=4)
        tk.Label(float_hk_frame, text="快捷键：F10 切换显示/隐藏",
                 font=("微软雅黑", 12), bg=self.bg_color).pack(side=tk.LEFT)
        tk.Checkbutton(float_hk_frame, text="启用快捷键", variable=self.float_hotkey_enabled,
                       bg=self.bg_color, font=("微软雅黑", 11)).pack(side=tk.LEFT, padx=8)

    def choose_float_color(self):
        color = colorchooser.askcolor(title="选择文字颜色")[1]
        if color:
            self.float_color = color
            self.color_btn.config(bg=color)

    def choose_float_bg_color(self):
        color = colorchooser.askcolor(title="选择背景颜色")[1]
        if color:
            self.float_bg_color = color
            self.bg_color_btn.config(bg=color)

    def set_click_through(self, hwnd):
        if sys.platform == "win32":
            ex_style = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
            ex_style |= win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT
            win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, ex_style)
            win32gui.SetLayeredWindowAttributes(hwnd, 0, 255, 2)

    def show_float_text(self):
        if self.float_window:
            self.float_window.destroy()

        try:
            self.float_x = int(self.float_x_entry.get())
            self.float_y = int(self.float_y_entry.get())
            self.float_font_size = int(self.float_size_entry.get())
            # 读取用户输入的字体
            self.float_font_family = self.float_font_entry.get().strip()
        except ValueError:
            messagebox.showwarning("输入错误", "坐标和字体大小必须为数字")
            return

        self.float_window = tk.Toplevel(self.root)
        self.float_window.overrideredirect(True)
        self.float_window.geometry(f"+{self.float_x}+{self.float_y}")
        self.float_window.attributes("-topmost", True)
        self.float_window.attributes("-alpha", self.float_alpha.get() / 100)

        self.float_window.config(bg=self.float_bg_color)
        label_bg = self.float_bg_color

        raw_text = self.float_text_entry.get("1.0", tk.END).strip()
        real_txt = self.parse_float_text(raw_text)

        # 悬浮字幕字体
        self.float_label = tk.Label(
            self.float_window,
            text=real_txt,
            font=(self.float_font_family, self.float_font_size, "bold"),
            fg=self.float_color,
            bg=label_bg
        )
        self.float_label.pack()

        self.float_window.update()
        hwnd = self.float_window.winfo_id()
        self.set_click_through(hwnd)
        self.float_auto_refresh()

        self.float_running = True
        self.float_status.config(text="状态：运行中", fg="#e53e3e")

    def hide_float_text(self):
        if self.float_refresh_id:
            self.root.after_cancel(self.float_refresh_id)
            self.float_refresh_id = None
        if self.float_window:
            self.float_window.destroy()
            self.float_window = None
            self.float_label = None

        self.float_running = False
        self.float_status.config(text="状态：已停止", fg=self.text_color)

    def function888(self):
        self.clear_main_frame()
        self.current_module = "support"
        tk.Label(self.main_frame, text="💖 支持根号七", font=("微软雅黑", 24, "bold"), bg=self.bg_color,
                 fg=self.primary_color).pack(pady=30)
        content_frame = tk.Frame(self.main_frame, bg=self.bg_color)
        content_frame.pack(fill=tk.BOTH, expand=True, padx=50)
        zanshang = tk.Frame(content_frame, bg="white", bd=2, relief=tk.RIDGE)
        zanshang.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10)
        tk.Label(zanshang, text="💰 赞赏码", font=("微软雅黑", 16, "bold"), bg="white").pack(pady=20)
        try:
            img = Image.open("赞赏码.png").resize((200, 200))
            self.zan_img = ImageTk.PhotoImage(img)
            tk.Label(zanshang, image=self.zan_img, bg="white").pack()
            print("图片“赞赏码.png”加载成功")
        except:
            tk.Label(zanshang, text="未找到图片", font=("微软雅黑", 12), bg="white").pack()
            print("图片“赞赏码.png”加载失败，未找到该图片")
        qun = tk.Frame(content_frame, bg="white", bd=2, relief=tk.RIDGE)
        qun.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10)
        tk.Label(qun, text="👥 交流群", font=("微软雅黑", 16, "bold"), bg="white").pack(pady=20)
        try:
            img = Image.open("交流群.png").resize((180, 180))
            self.qun_img = ImageTk.PhotoImage(img)
            tk.Label(qun, image=self.qun_img, bg="white").pack()
            print("图片“交流群.png”加载成功")
        except:
            tk.Label(qun, text="未找到图片", font=("微软雅黑", 12), bg="white").pack()
            print("图片“交流群.png”加载失败，未找到该图片")
        tk.Label(qun, text="群号：1083170749", font=("微软雅黑", 14, "bold"), bg="white", fg=self.primary_color).pack(
            pady=15)
        bili = tk.Frame(content_frame, bg="white", bd=2, relief=tk.RIDGE)
        bili.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10)
        tk.Label(bili, text="📺 B站关注", font=("微软雅黑", 16, "bold"), bg="white").pack(pady=20)
        tk.Label(bili, text="UP主：根号七大玉", font=("微软雅黑", 14), bg="white").pack(pady=10)

        def open_bili():
            webbrowser.open("https://space.bilibili.com/3493288684292639")

        ttk.Button(bili, text="🚀 立即前往关注", command=open_bili, style="Primary.TButton").pack(pady=30)


# ===================== 程序启动入口 ==========================

if __name__ == "__main__":
    VERSION = "v2.2.1"

    if sys.platform == "win32":
        import ctypes

        try:
            ctypes.windll.shcore.SetProcessDpiAwareness(1)
        except:
            pass

    root = tk.Tk()
    app = ToolboxApp(root, VERSION)
    app.setup_float_global_hotkeys()
    print(f"窗口“根号七的工具箱 {VERSION}”初始化完成")
    print(f"窗口“根号七的工具箱 {VERSION}”弹窗完成")
    root.mainloop()

# ============================================================

# 由三分之根号七制作
# 交流群1083170749
# B站 根号七大玉 -> https://space.bilibili.com/3493288684292639

# ============================================================